CreatureObject* ThreatMap::getHighestThreatCreature() { Locker locker(&lockMutex); ManagedReference<CreatureObject*> currentThreat = this->currentThreat.get(); if(currentThreat != NULL && !currentThreat->isDead() && !currentThreat->isIncapacitated() && !currentThreat->isDestroyed() && !cooldownTimerMap.isPast("doEvaluation")) return currentThreat; threatMatrix.clear(); for (int i = 0; i < size(); ++i) { ThreatMapEntry* entry = &elementAt(i).getValue(); CreatureObject* creature = elementAt(i).getKey(); ManagedReference<CreatureObject*> selfStrong = cast<CreatureObject*>(self.get().get()); if (!creature->isDead() && !creature->isIncapacitated() && creature->isInRange(selfStrong, 128.f) && creature->isAttackableBy(selfStrong)) threatMatrix.add(creature, entry); } this->currentThreat = threatMatrix.getLargestThreat(); cooldownTimerMap.updateToCurrentAndAddMili("doEvaluation", ThreatMap::EVALUATIONCOOLDOWN); return this->currentThreat.get().get(); }
uint64 CreatureObject::getNearestAttackingDefender(void) { uint64 defenederId = 0; float minLenght = FLT_MAX; ObjectIDList::iterator it = mDefenders.begin(); while(it != mDefenders.end()) { if((*it) != 0) { CreatureObject* defender = dynamic_cast<CreatureObject*>(gWorldManager->getObjectById((*it))); if (defender && !defender->isDead() && !defender->isIncapacitated()) { if ((defender->getCreoGroup() == CreoGroup_Player) || (defender->getCreoGroup() == CreoGroup_Creature)) { float len = glm::distance(this->mPosition, defender->mPosition); if (len < minLenght) { minLenght = len; defenederId = (*it); } } } } ++it; } return defenederId; }
bool LairObject::getLairTarget(void) { bool newTarget = false; float nearestDistanceFromLair = 128.0; // Todo: Use a real value. uint64 nearestDefenderId = 0; // Attack nearest target or the first target found within range or the one doing most damage or random? lol ObjectIDList::iterator defenderIt = this->getDefenders()->begin(); while (defenderIt != this->getDefenders()->end()) { CreatureObject* creatureObject = dynamic_cast<CreatureObject*>(gWorldManager->getObjectById((*defenderIt))); if (creatureObject) { // We may have a target, since he is attacking this lair. if (!creatureObject->isIncapacitated() && !creatureObject->isDead()) { float distanceFromLair = glm::distance(this->mPosition, creatureObject->mPosition); if (distanceFromLair < nearestDistanceFromLair) { nearestDistanceFromLair = distanceFromLair; nearestDefenderId = (*defenderIt); } newTarget = true; } else { // Make peace with this poor fellow. this->makePeaceWithDefender(*defenderIt); defenderIt = this->mDefenders.begin(); continue; } } defenderIt++; } if (newTarget) { this->setTarget(nearestDefenderId); } return newTarget; }
bool CombatManager::_verifyCombatState(CreatureObject* attacker, uint64 defenderId) { PlayerObject* playerAttacker = dynamic_cast<PlayerObject*>(attacker); CreatureObject* defender = dynamic_cast<CreatureObject*>(gWorldManager->getObjectById(defenderId)); if (!defender) { // No such object. return(false); } // Do not try to attack already incapped or dead objects. if (defender->isIncapacitated() || defender->isDead()) { return false; } //Do not attack if we are incapped or already dead or mounted. if (attacker->isIncapacitated() || attacker->isDead() || playerAttacker->checkIfMounted()) { return false; } // make sure we got both objects if (playerAttacker && defender) { //Do not attack if we are mounted if(playerAttacker->checkIfMounted()) { return false; } // if our target is a player, he must be dueling us or both need to be overt(TODO) if (PlayerObject* defenderPlayer = dynamic_cast<PlayerObject*>(defender)) { // also return, if our target is incapacitated or dead if(!playerAttacker->checkDuelList(defenderPlayer) || !defenderPlayer->checkDuelList(playerAttacker) || defenderPlayer == playerAttacker) { return(false); } if(defenderPlayer->isIncapacitated()) { // gMessageLib->sendSystemMessage(playerAttacker,L"","base_player","prose_target_incap"); return(false); } else if(defenderPlayer->isDead()) { // gMessageLib->sendSystemMessage(playerAttacker,L"","base_player","prose_target_dead"); return(false); } // put us in combat state gStateManager.setCurrentActionState(attacker, CreatureState_Combat); gStateManager.setCurrentActionState(attacker, CreatureState_CombatAttitudeNormal); // put our target in combat state if(!defenderPlayer->states.checkState(CreatureState_Combat)) { gStateManager.setCurrentActionState(defender, CreatureState_Combat); gStateManager.setCurrentActionState(defender, CreatureState_CombatAttitudeNormal); } // update our defender list if (!playerAttacker->checkDefenderList(defenderPlayer->getId())) { playerAttacker->AddDefender(defenderPlayer->getId()); } // update our targets defender list if (!defenderPlayer->checkDefenderList(playerAttacker->getId())) { playerAttacker->AddDefender(defenderPlayer->getId()); } if (!defenderPlayer->autoAttackEnabled()) { // Player can/may start auto-attack if idle. defenderPlayer->getController()->enqueueAutoAttack(playerAttacker->getId()); } } else { // our target is a creature if (defender->isIncapacitated()) { // gMessageLib->sendSystemMessage(playerAttacker,L"","base_player","prose_target_incap"); return(false); } else if (defender->isDead()) { // gMessageLib->sendSystemMessage(playerAttacker,L"","base_player","prose_target_dead"); return(false); } // Vefify that out target is attackable. It's not nice to spam attacks at innocent npc's. if (!(defender->getPvPStatus() & CreaturePvPStatus_Attackable)) { return(false); } // put us in combat state // if (!playerAttacker->states.checkState((CreatureState)(CreatureState_Combat + CreatureState_CombatAttitudeNormal))) { // playerAttacker->togglePvPStateOn((CreaturePvPStatus)(CreaturePvPStatus_Attackable + CreaturePvPStatus_Aggressive + CreaturePvPStatus_Enemy)); gMessageLib->sendUpdatePvpStatus(playerAttacker,playerAttacker, playerAttacker->getPvPStatus() | CreaturePvPStatus_Attackable); // TEST STATE MANAGER! gStateManager.setCurrentActionState(attacker, CreatureState_Combat); gStateManager.setCurrentActionState(attacker, CreatureState_CombatAttitudeNormal); } if (!defender->states.checkState((CreatureState_Combat))) { // Creature was NOT in combat before, and may very well be dormant. // Wake him up. gWorldManager->forceHandlingOfDormantNpc(defender->getId()); gWorldManager->forceHandlingOfReadyNpc(defender->getId()); // Creature may need some aggro built up before going into combat state?? gStateManager.setCurrentActionState(defender, CreatureState_Combat); gStateManager.setCurrentActionState(defender, CreatureState_CombatAttitudeNormal); } gMessageLib->sendUpdatePvpStatus(defender, playerAttacker, defender->getPvPStatus() | CreaturePvPStatus_Attackable | CreaturePvPStatus_Enemy); // update our defender list if (!playerAttacker->checkDefenderList(defender->getId())) { playerAttacker->AddDefender(defenderPlayer->getId()); } // update our targets defender list if (!defender->checkDefenderList(playerAttacker->getId())) { playerAttacker->AddDefender(defenderPlayer->getId()); } } } else { return(false); } return(true); }
bool NpcManager::_verifyCombatState(CreatureObject* attacker, uint64 defenderId) { if (!attacker || !defenderId) { return false; } CreatureObject* defender = dynamic_cast<CreatureObject*>(gWorldManager->getObjectById(defenderId)); if (!defender) { return false; } // If the target (defender) do have me in his defender list, we should not bother. /* if (defender->checkDefenderList(attacker->getId())) { return true; } */ PlayerObject* playerAttacker = dynamic_cast<PlayerObject*>(attacker); // make sure we got both objects if (playerAttacker && defender) { // if our target is a player, he must be dueling us or both need to be overt(TODO) if (PlayerObject* defenderPlayer = dynamic_cast<PlayerObject*>(defender)) { // also return, if our target is incapacitated or dead if(!playerAttacker->checkDuelList(defenderPlayer) || !defenderPlayer->checkDuelList(playerAttacker) || defenderPlayer == playerAttacker) { return(false); } if(defenderPlayer->GetCreature()->isIncapacitated()) { // gMessageLib->sendSystemMessage(playerAttacker,L"","base_player","prose_target_incap"); return(false); } else if(defenderPlayer->GetCreature()->isDead()) { // gMessageLib->sendSystemMessage(playerAttacker,L"","base_player","prose_target_dead"); return(false); } // put us in combat state if(!playerAttacker->GetCreature()->states.checkState(CreatureState_Combat)) { gStateManager.setCurrentActionState(playerAttacker->GetCreature(),CreatureState_Combat); gStateManager.setCurrentActionState(playerAttacker->GetCreature(),CreatureState_CombatAttitudeNormal); } // put our target in combat state if(!defenderPlayer->GetCreature()->states.checkState(CreatureState_Combat)) { gStateManager.setCurrentActionState(defenderPlayer->GetCreature(),CreatureState_Combat); gStateManager.setCurrentActionState(defenderPlayer->GetCreature(),CreatureState_CombatAttitudeNormal); } // update our defender list if (!playerAttacker->GetCreature()->checkDefenderList(defenderPlayer->getId())) // or if (!playerAttacker->checkDefenderList(defenderId) { playerAttacker->GetCreature()->AddDefender(defenderPlayer->getId()); } // update our targets defender list if (!defenderPlayer->GetCreature()->checkDefenderList(playerAttacker->getId())) { playerAttacker->GetCreature()->AddDefender(defenderPlayer->getId()); } } else { // our target is a creature if (defender->isIncapacitated()) { // gMessageLib->sendSystemMessage(playerAttacker,L"","base_player","prose_target_incap"); return(false); } else if (defender->isDead()) { // gMessageLib->sendSystemMessage(playerAttacker,L"","base_player","prose_target_dead"); return(false); } // Vefify that our target is attackable. It's not nice to spam attacks at innocent npc's. if (!(defender->getPvPStatus() & CreaturePvPStatus_Attackable)) { return(false); } // put us in combat state if (!playerAttacker->GetCreature()->states.checkState(CreatureState_Combat)) { gStateManager.setCurrentActionState(playerAttacker->GetCreature(),CreatureState_Combat); gStateManager.setCurrentActionState(playerAttacker->GetCreature(),CreatureState_CombatAttitudeNormal); } // put our target in combat state if (!defender->states.checkState(CreatureState_Combat)) { gStateManager.setCurrentActionState(defender,CreatureState_Combat); gStateManager.setCurrentActionState(defender,CreatureState_CombatAttitudeNormal); } // update our defender list if (!playerAttacker->GetCreature()->checkDefenderList(defender->getId())) { playerAttacker->GetCreature()->AddDefender(defenderPlayer->getId()); } // update our targets defender list if (!defender->checkDefenderList(playerAttacker->getId())) { playerAttacker->GetCreature()->AddDefender(defenderPlayer->getId()); } } return(true); } else if (AttackableCreature* attackerNpc = dynamic_cast<AttackableCreature*>(attacker)) { // make sure we got both objects if (attackerNpc && defender) { // Our target can be a player or another npc. if (PlayerObject* defenderPlayer = dynamic_cast<PlayerObject*>(defender)) { // The target (defender) is a player. Kill him! if (defenderPlayer->GetCreature()->isIncapacitated()) { // gMessageLib->sendSystemMessage(playerAttacker,L"","base_player","prose_target_incap"); return(false); } else if(defenderPlayer->GetCreature()->isDead()) { return(false); } /* if (!defenderPlayer->checkPvPState(CreaturePvPStatus_Attackable)) { // Player is not attackable return(false); } */ // put us in combat state if (!attackerNpc->states.checkState(CreatureState_Combat)) { gStateManager.setCurrentActionState(attackerNpc,CreatureState_Combat); gStateManager.setCurrentActionState(attackerNpc,CreatureState_CombatAttitudeNormal); } // put our target in combat stance if (!defenderPlayer->GetCreature()->states.checkState(CreatureState_Combat)) { gMessageLib->sendUpdatePvpStatus(defenderPlayer->GetCreature(),defenderPlayer, defenderPlayer->GetCreature()->getPvPStatus() | CreaturePvPStatus_Attackable | CreaturePvPStatus_Aggressive); // | CreaturePvPStatus_Enemy); gStateManager.setCurrentActionState(defenderPlayer->GetCreature(),CreatureState_Combat); gStateManager.setCurrentActionState(defenderPlayer->GetCreature(),CreatureState_CombatAttitudeNormal); } // If the target (defender) is not on our list, update pvp-status. if (!attackerNpc->checkDefenderList(defenderPlayer->getId())) { // May not be neeeded, since the pvp-status is changed when getting enough aggro. // gMessageLib->sendUpdatePvpStatus(attackerNpc,defenderPlayer, attackerNpc->getPvPStatus() | CreaturePvPStatus_Attackable | CreaturePvPStatus_Aggressive | CreaturePvPStatus_Enemy); // update our defender list playerAttacker->GetCreature()->AddDefender(defenderPlayer->getId()); // Update player and all his group mates currently in range. /* PlayerList inRangeMembers = defenderPlayer->getInRangeGroupMembers(true); PlayerList::iterator it = inRangeMembers.begin(); while (it != inRangeMembers.end()) { PlayerObject* player = (*it); // If player online, send emote. if (player && player->isConnected()) { MessageLib->sendUpdatePvpStatus(attackerNpc,player); } } */ } // update our targets defender list if (!defenderPlayer->GetCreature()->checkDefenderList(attackerNpc->getId())) { playerAttacker->GetCreature()->AddDefender(defenderPlayer->getId()); } // Player can/may start auto-attack if idle. if (!defenderPlayer->autoAttackEnabled()) { defenderPlayer->getController()->enqueueAutoAttack(attackerNpc->getId()); } } else if (dynamic_cast<AttackableCreature*>(defender)) { // The target (defender) is a npc. Kill him! // Here I think some validation would be great, don't wanna kill you piket-brother? if (defenderPlayer->GetCreature()->isIncapacitated()) { // gMessageLib->sendSystemMessage(playerAttacker,L"","base_player","prose_target_incap"); return(false); } else if(defenderPlayer->GetCreature()->isDead()) { return(false); } // put us in combat state if (!attackerNpc->states.checkState(CreatureState_Combat)) { gStateManager.setCurrentActionState(attackerNpc,CreatureState_Combat); gStateManager.setCurrentActionState(attackerNpc,CreatureState_CombatAttitudeNormal); } // put our target in combat state if (!defenderPlayer->GetCreature()->states.checkState(CreatureState_Combat)) { gStateManager.setCurrentActionState(defenderPlayer->GetCreature(),CreatureState_Combat); gStateManager.setCurrentActionState(defenderPlayer->GetCreature(),CreatureState_CombatAttitudeNormal); } // update our defender list if (!attackerNpc->checkDefenderList(defenderPlayer->getId())) { playerAttacker->GetCreature()->AddDefender(defenderPlayer->getId()); } // update our targets defender list if (!defenderPlayer->GetCreature()->checkDefenderList(attackerNpc->getId())) { playerAttacker->GetCreature()->AddDefender(defenderPlayer->getId()); } } return(true); } return(false); } return false; }