Esempio n. 1
0
vector<IMapMovingObject*> Map::getMovingObject(){
	vector <IMapMovingObject*> result;
	for (int i = 0; i < _mapWidth; i++)
		for (int j = 0; j < _mapHeight; j++)
			if (isMonster(pair<int, int>(i, j)) == true)
				result.push_back(((IMapMovingObject*)(*this)(i, j)));
	return result;
}
Esempio n. 2
0
/**
* @brief        Gets NPC information for use in various NPC packets.
*
* @param        pkt        The packet the information will be stored in.
*/
void CNpc::GetNpcInfo(Packet & pkt)
{
        pkt << GetProtoID()
                << uint8(isMonster() ? 1 : 2) // Monster = 1, NPC = 2 (need to use a better flag)
                << m_sPid
                << GetType()
                << m_iSellingGroup
                << m_sSize
                << m_iWeapon_1 << m_iWeapon_2
                // Monsters require 0 regardless, otherwise they'll act as NPCs.
                << uint8(isMonster() ? 0 : GetNation())
                << GetLevel()
                << GetSPosX() << GetSPosZ() << GetSPosY()
                << uint32(isGateOpen())
                << m_byObjectType
                << uint16(0) << uint16(0) // unknown
                << int16(m_byDirection);
}
Esempio n. 3
0
bool Creature::doReflectionDamage(Damage damage, Creature* target, ReflectedDamageType printZero) {
    int dmg = damage.getReflected() ? damage.getReflected() : damage.getPhysicalReflected();

    // don't quit if we want to print 0
    if(!dmg && printZero == REFLECTED_NONE)
        return(false);

    if(damage.getReflected() || printZero == REFLECTED_MAGIC) {
        target->printColor("Your shield of magic reflects %s%d^x damage.\n", target->customColorize("*CC:DAMAGE*").c_str(), dmg);
        printColor("%M's shield of magic flares up and hits you for %s%d^x damage.\n", target, customColorize("*CC:DAMAGE*").c_str(), dmg);
        broadcastGroup(false, this, "%M's shield of magic flares up and hits %N for *CC:DAMAGE*%d^x damage.\n",
            target, this, dmg);
    } else {
        switch(damage.getPhysicalReflectedType()) {
        case REFLECTED_FIRE_SHIELD:
        default:
            target->printColor("Your shield of fire reflects %s%d^x damage.\n", target->customColorize("*CC:DAMAGE*").c_str(), dmg);
            printColor("%M's shield of fire flares up and hits you for %s%d^x damage.\n", target, customColorize("*CC:DAMAGE*").c_str(), dmg);
            broadcastGroup(false, this, "%M's shield of fire flares up and hits %N for *CC:DAMAGE*%d^x damage.\n",
                target, this, dmg);
            break;
        }
    }

    if(damage.getDoubleReflected()) {
        Damage reflectedDamage;
        reflectedDamage.setReflected(damage.getDoubleReflected());
        target->doReflectionDamage(reflectedDamage, this);
    }

    // we may have gotten this far for printing reasons (even on zero), but really, go no further
    if(!dmg)
        return(false);

    if(target->isPlayer() && isMonster())
        getAsMonster()->adjustThreat(target, dmg);

    hp.decrease(dmg);
    if(hp.getCur() <= 0)
        return(true);
    return(false);
}
Esempio n. 4
0
void NounShip::destroyShip( Noun * pKiller, bool bZeroVelocity )
{
	// make sure the damage is enough
	m_Damage = maxDamage();
	// clear the current order & command, so if they respawn the ship doesn't try to keep doing it's last command
	setCommand( NOCOMMAND, NULL );
	setOrder( NOORDER, NULL, NULL );

	// inform the context user first
	if ( pKiller != this )
	{
		gameContext()->gameUser()->onDestroyed( this, pKiller );
		if ( pKiller != NULL )
			gameContext()->gameUser()->onKill( pKiller, this );
	}
	else 
		gameContext()->gameUser()->onSelfDestruct( this );

	if ( WidgetCast<NounPlanet>( pKiller ) )
		gameContext()->gameUser()->onCollidePlanet( this );

	// create the primary explosion
	if ( context()->isClient() )
	{
		Scene * pScene = destroyEffect();
		if ( pScene != NULL )
		{
			// TODO: no need to add this explosion of this player is nowhere near the explosion
			// ship destroyed, create the explosion effect
			SceneryDebris * pEffect = new SceneryDebris;
			pEffect->setNounContext( new NounContext( pScene ) );
			pEffect->setContext( context() );
			pEffect->setPosition( worldPosition() );
			pEffect->setDelay( 0.0f );
			pEffect->setFrame( frame() );

			if (! bZeroVelocity )
				pEffect->setVelocity( Vector3( sin( m_fHeading ) * m_fVelocity, 0.0f, cos( m_fHeading) * m_fVelocity ) );
			if (! pEffect->setSegment( "Effect" ) )
				pEffect->setLife( 15.0f );

			context()->attachNoun( pEffect );
		}

		NounTrail::CopyTrailsIntoZone( this );
	}

	// list of destroyed items to remove from ship..
	std::list< Noun * > destroyed;

	// damage enhancements, once they reach their maxDamage() they are destroyed..
	for(int i=0;i<childCount();++i)
	{
		NounEnhancement * pEnh = WidgetCast<NounEnhancement>( child(i) );
		if ( pEnh != NULL )
		{
			if ( pEnh->incrementDamage() )
			{
				LOG_STATUS( "NounShip", "[ENHANCEMENT]:Destroyed:%s:%s:%u", pEnh->getName(), name(), userId() );
				message( CharString().format( "<color;ffffff>Comms: Enhancement '%s' destroyed!", pEnh->getName() ) );
				destroyed.push_back( pEnh );
			}
			continue;
		}

		// remove any beacons on death..
		NounBeacon * pBeacon = WidgetCast<NounBeacon>( child(i) );
		if ( pBeacon != NULL )
		{
			destroyed.push_back( pBeacon );
			continue;
		}
	}

	// server-side only logic
	if ( isServer() )
	{
		// check for area damage
		Array< GameContext::NounCollision > collide;
		if ( context()->proximityCheck( worldPosition(), explodeArea(), collide ) )
		{
			for(int i=0;i<collide.size();i++)
			{
				NounGame * pCollide = WidgetCast<NounGame>( collide[i].pNoun );
				if ( !pCollide || pCollide == this )
					continue;

				if ( pCollide->canDamage( DAMAGE_ENERGY | DAMAGE_KINETIC ) &&
					collide[i].fDistance < explodeArea() )
				{
					float damageRatio = 1.0f - (collide[i].fDistance / explodeArea());
					int damage = damageRatio * explodeDamage();
					
					if ( damage > 0 )
					{
						pCollide->inflictDamage( tick(), this, damage, DAMAGE_ENERGY | DAMAGE_KINETIC, 
							pCollide->worldFrame() * (worldPosition() - pCollide->worldPosition()) );
					}
				}
			}
		}

		// drop enhancements after we do area damage, otherwise we'll destroy the dropped loot..
		dropLoot();

		// space-monsters do not leave behind devices
		if ( ! isMonster() )
		{
			// eject some of the resources used to build the ship into space
			int nAmount = DESTROYED_SHIP_RESOURCE * buildCost( this );
			while( nAmount > 0 )
			{
				CargoResource::Ref pCargo = new CargoResource( nAmount );
				nAmount -= pCargo->quantity();

				Vector3 vPosition( worldPosition() + RandomVector( -radius(), radius() ) );
				vPosition.y = 0.0f;

				pCargo->setPosition( vPosition );
				context()->attachNoun( pCargo );
			}

			//// check for any cargo items...  if found put them into space
			//for(int i=0;i<childCount();i++)
			//{
			//	BaseNode * pChild = child(i);
		
			//	NounCargo::Ref pCargo;
			//	if ( WidgetCast<NounCargo>( pChild ) )
			//	{
			//		int roll = rand() % 100;
			//		if ( roll < ((NounCargo *)pChild)->durability() )
			//			pCargo = (NounCargo *)pChild->copy();
			//	}

			//	if ( pCargo.valid() )
			//	{
			//		Vector3 vPosition( worldPosition() + RandomVector( -5.0f, 5.0f ) );
			//		vPosition.y = 0.0f;

			//		pCargo->setPosition( vPosition );
			//		context()->attachNoun( pCargo );
			//	}
			//}
		}

		// last before detach so that players dont dupe thier enhancements
		// that were dropped
		// save off storage with this "active" ship
		if(userId() != 0)
			context()->user()->saveStorage(this);

	}

	// remove desrtroyed items from ship..
	while( destroyed.size() > 0 )
	{
		Noun * pDestroyed = destroyed.front();
		destroyed.pop_front();

		if ( pDestroyed )
			pDestroyed->detachSelf();
	}

	// lastly, detach the ship from the universe
	setDetach();
}
Esempio n. 5
0
bool Creature::canFlee(bool displayFail, bool checkTimer) {
    bool    crtInRoom=false;
    long    t=0;
    int     i=0;

    if(isMonster()) {

        if(!flagIsSet(M_WILL_FLEE) || flagIsSet(M_DM_FOLLOW))
            return(false);

        if(hp.getCur() > hp.getMax()/5)
            return(false);

        if(flagIsSet(M_PERMENANT_MONSTER))
            return(false);

    } else {
        //Player* pThis = getPlayer();
        if(!ableToDoCommand())
            return(false);

        if(flagIsSet(P_SITTING)) {
            if(displayFail)
                print("You have to stand up first.\n");
            return(false);
        }

        if(isEffected("hold-person")) {
            if(displayFail)
                print("You are unable to move right now.\n");
            return(false);
        }

        // blah blah re-submit
        if( (cClass == CreatureClass::BERSERKER || cClass == CreatureClass::CLERIC) &&
            isEffected("berserk") )
        {
            if(displayFail)
                printColor("^rYour lust for battle prevents you from fleeing!\n");
            return(false);
        }

        if(checkTimer && !isEffected("fear") && !isStaff()) {
            t = time(0);
            i = MAX(getLTAttack(), MAX(lasttime[LT_SPELL].ltime,lasttime[LT_READ_SCROLL].ltime)) + 3L;
            if(t < i) {
                if(displayFail)
                    pleaseWait(i-t);
                return(false);
            }
        }

        // confusion and drunkenness overrides following checks
        if(isEffected("confusion") || isEffected("drunkenness"))
            return(true);


        // players can only flee if someone/something else is in the room
        for(Monster* mons : getConstRoomParent()->monsters) {
            if(!mons->isPet()) {
                crtInRoom = true;
                break;
            }
        }

        if(!crtInRoom) {
            for(Player* ply : getConstRoomParent()->players) {
                if(ply == this)
                    continue;
                if(!ply->isStaff()) {
                    crtInRoom = true;
                    break;
                }
            }
        }

        if( !crtInRoom && !checkStaff("There's nothing to flee from!\n") ) {
            getAsPlayer()->setFleeing(false);
            return(false);
        }
    }

    return(true);
}