bool SystemManager::_LoadSystemDynamics() { std::vector<DBSystemDynamicEntity> entities; if(!m_db.LoadSystemDynamicEntities(m_systemID, entities)) { _log(SERVICE__ERROR, "Unable to load dynamic entities during boot of system %u.", m_systemID); return false; } //uint32 next_hack_entity_ID = m_systemID + 900000000; std::vector<DBSystemDynamicEntity>::iterator cur, end; cur = entities.begin(); end = entities.end(); for(; cur != end; cur++) { SystemEntity *se = DynamicEntityFactory::BuildEntity(*this, m_services.item_factory, *cur); if(se == NULL) { codelog(SERVICE__ERROR, "Failed to create entity for item %u (type %u)", cur->itemID, cur->typeID); continue; } //TODO: use proper log type. _log(SPAWN__MESSAGE, "Loaded dynamic entity %u of type %u for system %u", cur->itemID, cur->typeID, m_systemID); m_entities[se->GetID()] = se; bubbles.Add(se, false); m_entityChanged = true; } return true; }
void DroneEntity::Killed(Damage &fatal_blow) { m_destiny->Stop(); DynamicSystemEntity::Killed(fatal_blow); SystemEntity *killer = fatal_blow.source; Client* client = m_services.entity_list.FindByShip( killer->Item()->ownerID() ); if( !killer->IsClient() ) { if( client != NULL ) { killer = static_cast<SystemEntity*>(client); } } else { client = killer->CastToClient(); } //TODO: award status changes. (entitySecurityStatusKillBonus) client->GetChar()->addSecurityRating( m_self->GetAttribute(AttrEntitySecurityStatusKillBonus).get_float() ); m_system->RemoveEntity(this); }
bool SystemManager::BuildDynamicEntity(Client *who, const DBSystemDynamicEntity &entity) { SystemEntity *se = DynamicEntityFactory::BuildEntity(*this, m_services.item_factory, entity ); if( se == NULL ) { sLog.Error( "SystemManager::BuildDynamicEntity()", "Failed to create entity for item %u (type %u)", entity.itemID, entity.typeID ); return false; } sLog.Debug( "SystemManager::BuildDynamicEntity()", "Loaded dynamic entity %u of type %u for system %u", entity.itemID, entity.typeID, m_systemID ); m_entities[se->GetID()] = se; bubbles.Add(se, false); m_entityChanged = true; return true; }
SystemManager::~SystemManager() { //we mustn't delete clients because they are owned by the entity list. std::map<uint32, SystemEntity *>::iterator cur, end, tmp; cur = m_entities.begin(); end = m_entities.end(); while(cur != end) { SystemEntity *se = cur->second; cur++; if(!se->IsClient()) delete se; } //must be deleted AFTER all the NPCs which it spawn have been, since //they will call back to their spawning spawn entries. delete m_spawnManager; bubbles.clear(); }
void AsteroidEntity::Killed(Damage &fatal_blow) { m_destiny->Stop(); DynamicSystemEntity::Killed(fatal_blow); SystemEntity *killer = fatal_blow.source; Client* client = m_services.entity_list.FindByShip( killer->Item()->ownerID() ); if( !killer->IsClient() ) { if( client != NULL ) { killer = static_cast<SystemEntity*>(client); } } else { client = killer->CastToClient(); } m_system->RemoveEntity(this); }
SystemManager::~SystemManager() { //we mustn't delete clients because they are owned by the entity list. std::map<uint32, SystemEntity *>::iterator cur, end, tmp; cur = m_entities.begin(); end = m_entities.end(); while(cur != end) { SystemEntity *se = cur->second; cur++; // If entity is an NPC, save its data to DB for persietence across server restarts: if(se->IsNPC()) se->CastToNPC()->SaveNPC(); if(!se->IsClient()) delete se; } //must be deleted AFTER all the NPCs which it spawn have been, since //they will call back to their spawning spawn entries. delete m_spawnManager; bubbles.clear(); }
void NPC::Killed(Damage &fatal_blow) { m_destiny->Stop(); DynamicSystemEntity::Killed(fatal_blow); SystemEntity *killer = fatal_blow.source; Client* client = m_services.entity_list.FindByShip( killer->Item()->ownerID() ); if( !killer->IsClient() ) { if( client != NULL ) { killer = static_cast<SystemEntity*>(client); } } else { client = killer->CastToClient(); } //TODO: drop loot. //_DropLoot(fatal_blow.source); _DropLoot(killer); //award kill bounty. //_AwardBounty(fatal_blow.source); _AwardBounty(killer); //TODO: award status changes. (entitySecurityStatusKillBonus) client->GetChar()->addSecurityRating( m_self->GetAttribute(AttrEntitySecurityStatusKillBonus).get_float() ); //notify our spawner that we are gone. if(m_spawner != NULL) { m_spawner->SpawnDepoped(m_self->itemID()); } m_system->RemoveNPC(this); }
void SystemManager::MakeSetState(const SystemBubble *bubble, DoDestiny_SetState &ss) const { Buffer* stateBuffer = new Buffer; AddBall_header head; head.more = 0; head.sequence = ss.stamp; stateBuffer->Append( head ); //I am not thrilled with this mechanism, but I cant think of a better //way to deal with it right now. The issue is that we need to send out // info for all system-wide entities (celestials, etc), as well as all // entities in our current bubble. Well, it is likely that some things // in our bubble are system-wide, and we would be sending out duplciates. // so, we use a set to enforce uniqueness. std::set<SystemEntity*> visibleEntities; { std::map<uint32, SystemEntity*>::const_iterator cur, end; cur = m_entities.begin(); end = m_entities.end(); for(; cur != end; ++cur) { if( !cur->second->IsVisibleSystemWide() ) { //_log(COMMON__WARNING, "%u is not visible!", cur->first); continue; } //_log(COMMON__WARNING, "%u is system wide visible!", cur->first); visibleEntities.insert( cur->second ); } } //bubble is null??? why??? bubble->GetEntities( visibleEntities ); PySafeDecRef( ss.slims ); ss.slims = new PyList; //go through all entities and gather the info we need... std::set<SystemEntity*>::const_iterator cur, end; cur = visibleEntities.begin(); end = visibleEntities.end(); for(; cur != end; ++cur) { SystemEntity* ent = *cur; //_log(COMMON__WARNING, "Encoding entity %u", ent->GetID()); //ss.damageState ss.damageState[ ent->GetID() ] = ent->MakeDamageState(); //ss.slims ss.slims->AddItem( new PyObject( new PyString( "foo.SlimItem" ), ent->MakeSlimItem() ) ); //append the destiny binary data... ent->EncodeDestiny( *stateBuffer ); } //ss.destiny_state ss.destiny_state = new PyBuffer( &stateBuffer ); SafeDelete( stateBuffer ); //ss.gangCorps //ss.aggressors //ss.droneState ss.droneState = m_db.GetSolDroneState( m_systemID ); if( NULL == ss.droneState ) { _log( SERVICE__ERROR, "Unable to query dronestate entity for destiny update in system %u!", m_systemID ); ss.droneState = new PyNone; } //ss.solItem ss.solItem = m_db.GetSolRow( m_systemID ); if( NULL == ss.solItem ) { _log( CLIENT__ERROR, "Unable to query solarsystem entity for destiny update in system %u!", m_systemID ); ss.solItem = new PyNone; } //ss.effectStates ss.effectStates = new PyList; //ss.allianceBridges ss.allianceBridges = new PyList; _log( DESTINY__TRACE, "Set State:" ); ss.Dump( DESTINY__TRACE, " " ); _log( DESTINY__TRACE, " Buffer:" ); _hex( DESTINY__TRACE, &( ss.destiny_state->content() )[0], ss.destiny_state->content().size() ); _log( DESTINY__TRACE, " Decoded:" ); Destiny::DumpUpdate( DESTINY__TRACE, &( ss.destiny_state->content() )[0], ss.destiny_state->content().size() ); }
void NPCAIMgr::Process() { if(!m_processTimer.Check()) return; // Test to see if we have a Shield Booster if( m_shieldBoosterTimer.Enabled() ) { // It's time to recharge? if( m_shieldBoosterTimer.Check() ) { m_npc->UseShieldRecharge(); } } // Test to see if we have an Armor Repair if( m_armorRepairTimer.Enabled() ) { // It's time to recharge? if( m_armorRepairTimer.Check() ) { m_npc->UseArmorRepairer(); } } switch(m_state) { case Idle: //TODO: wander around? //TODO: look around for shit to shoot at? // The parameter proximityRange tells us how far we "see" break; case Chasing: { //NOTE: getting our target like this is pretty weak... SystemEntity *target = m_npc->targets.GetFirstTarget(false); if(target == NULL) { //no valid target... if(m_npc->targets.HasNoTargets()) { _log(NPC__AI_TRACE, "[%u] Stopped chasing, no targets remain.", m_npc->GetID()); m_state = Idle; return; } //else, still locking or something. return; } if(m_npc->DistanceTo2(target) < m_entityAttackRange2.get_float()) { //we caught up... off to follow mode. Should orbit, but that //isnt working yet. _log(NPC__AI_TRACE, "[%u] Was chasing %u, but they are close enough now. Following.", m_npc->GetID(), target->GetID()); _EnterFollowing(target); return; } //else, we continue chasing... should we shoot? CheckAttacks(target); } break; case Following: { //NOTE: getting our target like this is pretty weak... SystemEntity *target = m_npc->targets.GetFirstTarget(false); if(target == NULL) { //no valid target... if(m_npc->targets.HasNoTargets()) { _log(NPC__AI_TRACE, "[%u] Stopped chasing, no targets remain.", m_npc->GetID()); m_state = Idle; return; } //else, still locking or something. return; } if(m_npc->DistanceTo2(target) > m_entityChaseMaxDistance2.get_float()) { //they are too far away now... _log(NPC__AI_TRACE, "[%u] Was chasing with %u, but they are too far away now. Chasing.", m_npc->GetID(), target->GetID()); _EnterChasing(target); return; } //ok, we are close enough... CheckAttacks(target); } break; case Engaged: { //NOTE: getting our target like this is pretty weak... SystemEntity *target = m_npc->targets.GetFirstTarget(false); if(target == NULL) { //no valid target... if(m_npc->targets.HasNoTargets()) { _log(NPC__AI_TRACE, "[%u] Stopped chasing, no targets remain.", m_npc->GetID()); _EnterIdle(); return; } //else, still locking or something. return; } if(m_npc->DistanceTo2(target) > m_entityAttackRange2.get_float()) { //they are too far away now... _log(NPC__AI_TRACE, "[%u] Was engaged with %u, but they are too far away now. Following.", m_npc->GetID(), target->GetID()); _EnterFollowing(target); return; } //ok, we are close enough... CheckAttacks(target); } break; //no default on purpose } }
void NPCAIMgr::Process() { if(!m_processTimer.Check()) return; // Test to see if we have a Shield Booster if( m_shieldBoosterTimer.Enabled() ) { // It's time to recharge? if( m_shieldBoosterTimer.Check() ) { m_npc->UseShieldRecharge(); } } // Test to see if we have an Armor Repair if( m_armorRepairTimer.Enabled() ) { // It's time to recharge? if( m_armorRepairTimer.Check() ) { m_npc->UseArmorRepairer(); } } switch(m_state) { case Idle: { //TODO: wander around? //TODO: look around for shit to shoot at? // The parameter proximityRange tells us how far we "see" if( m_beginFindTarget.Check() ) { std::set<SystemEntity *> possibleTargets; m_npc->Bubble()->GetEntities(possibleTargets); std::set<SystemEntity *>::iterator cur, end; cur = possibleTargets.begin(); end = possibleTargets.end(); for(; cur != end; cur++) { // We find a target // TODO: Determine the weakest target to engage if( (*cur)->IsClient() ) { // Check to see if this player ship is not cloaked, so we can really target them: if( ((*cur)->CastToClient()->Destiny()) != NULL ) { if( !((*cur)->CastToClient()->Destiny()->IsCloaked()) ) { // TODO: Check to see if target's standings are below 0.0, if so, engage, otherwise, ignore: //Client * const currentClient = (*cur)->CastToClient(); //if( currentClient->GetStandingsFrom(this->m_npc->CastToNPC()->GetCorporationID()) >= 0.0 ) // break; // Check to see if it's a capsule // Target him and begin the process of the attack. if( !((*cur)->Item()->groupID() == EVEDB::invGroups::Capsule) ) this->Targeted((*cur)); break; } } } } } break; } case Chasing: { //NOTE: getting our target like this is pretty weak... SystemEntity *target = m_npc->targets.GetFirstTarget(false); if(target == NULL) { //no valid target... if(m_npc->targets.HasNoTargets()) { _log(NPC__AI_TRACE, "[%u] Stopped chasing, no targets remain.", m_npc->GetID()); m_state = Idle; return; } //else, still locking or something. return; } if(m_npc->DistanceTo2(target) < m_entityAttackRange2.get_float()) { //we caught up... off to follow mode. Should orbit, but that //isnt working yet. _log(NPC__AI_TRACE, "[%u] Was chasing %u, but they are close enough now. Following.", m_npc->GetID(), target->GetID()); _EnterEngaged(target); return; } //else, we continue chasing... should we shoot? CheckAttacks(target); } break; case Following: { //NOTE: getting our target like this is pretty weak... SystemEntity *target = m_npc->targets.GetFirstTarget(false); if(target == NULL) { //no valid target... if(m_npc->targets.HasNoTargets()) { _log(NPC__AI_TRACE, "[%u] Stopped chasing, no targets remain.", m_npc->GetID()); m_state = Idle; return; } //else, still locking or something. return; } if(m_npc->DistanceTo2(target) > m_entityChaseMaxDistance2.get_float()) { //they are too far away now... _log(NPC__AI_TRACE, "[%u] Was chasing with %u, but they are too far away now. Chasing.", m_npc->GetID(), target->GetID()); _EnterChasing(target); return; } //ok, we are close enough... CheckAttacks(target); } break; case Engaged: { //NOTE: getting our target like this is pretty weak... SystemEntity *target = m_npc->targets.GetFirstTarget(false); if(target == NULL) { //no valid target... if(m_npc->targets.HasNoTargets()) { _log(NPC__AI_TRACE, "[%u] Stopped chasing, no targets remain.", m_npc->GetID()); _EnterIdle(); return; } //else, still locking or something. return; } if(m_npc->DistanceTo2(target) > m_entityAttackRange2.get_float()) { //they are too far away now... _log(NPC__AI_TRACE, "[%u] Was engaged with %u, but they are too far away now. Following.", m_npc->GetID(), target->GetID()); _EnterFollowing(target); return; } //ok, we are close enough... CheckAttacks(target); } break; //no default on purpose } }