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; }
/** * @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); }
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); }
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(); }
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); }