void NPCAIMgr::Targeted(SystemEntity *by_who) { //TODO: determind lock speed. //TODO: obey maxLockedTargets //m_npc->targets.StartTargeting(by_who, 1000); if( m_npc->Item()->GetAttribute(AttrMaxLockedTargets) > m_npc->targets.GetTotalTargets()) m_npc->targets.StartTargeting( by_who, 1000 ); switch(m_state) { case Idle: { _log(NPC__AI_TRACE, "[%u] Targeted by %u in Idle. Attacking.", m_npc->GetID(), by_who->GetID()); double dist = m_npc->DistanceTo2(by_who); if(dist < m_entityAttackRange2.get_float()) { _EnterEngaged(by_who); } else if(dist < m_entityChaseMaxDistance2.get_float()) { _EnterFollowing(by_who); } else { _EnterChasing(by_who); } } break; case Chasing: _log(NPC__AI_TRACE, "[%u] Targeted by %u while chasing.", m_npc->GetID(), by_who->GetID()); break; case Following: _log(NPC__AI_TRACE, "[%u] Targeted by %u while following.", m_npc->GetID(), by_who->GetID()); break; case Engaged: _log(NPC__AI_TRACE, "[%u] Targeted by %u while chasing.", m_npc->GetID(), by_who->GetID()); break; //no default on purpose } }
void NPCAIMgr::CheckAttacks(SystemEntity *target) { if(m_mainAttackTimer.Check(false)) { _log(NPC__AI_TRACE, "[%u] Attack timer expired. Attacking %u.", m_npc->GetID(), target->GetID()); InventoryItemRef self = m_npc->Item(); //reset the attack timer. //NOTE: there is probably a more intelligent way to make this descision. //if(self->entityAttackDelayMax() <= 0) { //use speed field... m_mainAttackTimer.Start(self->GetAttribute(AttrSpeed).get_int()); //} else { //I think this field is actually meant as a reaction time to the player showing up in range. // m_mainAttackTimer.Start(MakeRandomInt( // self->entityAttackDelayMin(), // self->entityAttackDelayMax() )); //} //Do main attack... //check our attack range... if(m_npc->DistanceTo2(target) > m_entityAttackRange2.get_float()) { _log(NPC__AI_TRACE, "[%u] Target (%u) is too far away (%.2f > %.2f)", m_npc->GetID(), target->GetID(), m_npc->DistanceTo2(target), m_entityAttackRange2); _EnterFollowing(target); return; } //TODO: check to-hit... //TODO: Need to consult dgmTypeEffects to determine what kind // of effects to throw for this attack. _SendWeaponEffect("effects.Laser", target); Damage d( m_npc, (InventoryItemRef)self, effectTargetAttack); //should get this from somewhere. m_npc->ApplyDamageModifiers(d, m_npc); target->ApplyDamage(d); } }
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 } }