public void processThreatEvent(ThreatRefStatusChangeEvent threatRefStatusChangeEvent) { threatRefStatusChangeEvent.setThreatManager(this); // now we can set the threat manager HostileReference hostilRef = threatRefStatusChangeEvent.getReference(); switch (threatRefStatusChangeEvent.getType()) { case UnitEventTypes.ThreatRefThreatChange: if ((getCurrentVictim() == hostilRef && threatRefStatusChangeEvent.getFValue() < 0.0f) || (getCurrentVictim() != hostilRef && threatRefStatusChangeEvent.getFValue() > 0.0f)) { setDirty(true); // the order in the threat list might have changed } break; case UnitEventTypes.ThreatRefOnlineStatus: if (!hostilRef.isOnline()) { if (hostilRef == getCurrentVictim()) { setCurrentVictim(null); setDirty(true); } Owner.SendRemoveFromThreatList(hostilRef); threatContainer.remove(hostilRef); threatOfflineContainer.addReference(hostilRef); } else { if (getCurrentVictim() != null && hostilRef.getThreat() > (1.1f * getCurrentVictim().getThreat())) { setDirty(true); } threatContainer.addReference(hostilRef); threatOfflineContainer.remove(hostilRef); } break; case UnitEventTypes.ThreatRefRemoveFromList: if (hostilRef == getCurrentVictim()) { setCurrentVictim(null); setDirty(true); } Owner.SendRemoveFromThreatList(hostilRef); if (hostilRef.isOnline()) { threatContainer.remove(hostilRef); } else { threatOfflineContainer.remove(hostilRef); } break; } }
void tauntApply(Unit taunter) { HostileReference refe = threatContainer.getReferenceByTarget(taunter); if (getCurrentVictim() != null && refe != null && (refe.getThreat() < getCurrentVictim().getThreat())) { if (refe.getTempThreatModifier() == 0.0f) // Ok, temp threat is unused { refe.setTempThreat(getCurrentVictim().getThreat()); } } }
public float getThreat(Unit victim, bool alsoSearchOfflineList = false) { float threat = 0.0f; HostileReference refe = threatContainer.getReferenceByTarget(victim); if (refe == null && alsoSearchOfflineList) { refe = threatOfflineContainer.getReferenceByTarget(victim); } if (refe != null) { threat = refe.getThreat(); } return(threat); }
public HostileReference selectNextVictim(Creature attacker, HostileReference currentVictim) { HostileReference currentRef = null; bool found = false; bool noPriorityTargetFound = false; for (var i = 0; i < threatList.Count; i++) { if (found) { break; } currentRef = threatList[i]; Unit target = currentRef.getTarget(); Contract.Assert(target); // if the ref has status online the target must be there ! // some units are prefered in comparison to others if (!noPriorityTargetFound && (target.IsImmunedToDamage(attacker.GetMeleeDamageSchoolMask()) || target.HasNegativeAuraWithInterruptFlag(SpellAuraInterruptFlags.TakeDamage))) { if (i != threatList.Count - 1) { // current victim is a second choice target, so don't compare threat with it below if (currentRef == currentVictim) { currentVictim = null; } continue; } else { // if we reached to this point, everyone in the threatlist is a second choice target. In such a situation the target with the highest threat should be attacked. noPriorityTargetFound = true; i = 0; continue; } } if (attacker.CanCreatureAttack(target)) // skip non attackable currently targets { if (currentVictim != null) // select 1.3/1.1 better target in comparison current target { // list sorted and and we check current target, then this is best case if (currentVictim == currentRef || currentRef.getThreat() <= 1.1f * currentVictim.getThreat()) { if (currentVictim != currentRef && attacker.CanCreatureAttack(currentVictim.getTarget())) { currentRef = currentVictim; // for second case, if currentvictim is attackable } found = true; break; } if (currentRef.getThreat() > 1.3f * currentVictim.getThreat() || (currentRef.getThreat() > 1.1f * currentVictim.getThreat() && attacker.IsWithinMeleeRange(target))) { //implement 110% threat rule for targets in melee range found = true; //and 130% rule for targets in ranged distances break; //for selecting alive targets } } else // select any { found = true; break; } } } if (!found) { currentRef = null; } return(currentRef); }