*Fix target priority of chain heal.

--HG--
branch : trunk
This commit is contained in:
megamage
2009-01-27 14:34:42 -06:00
parent 230767b40f
commit ed6337550e
4 changed files with 46 additions and 87 deletions

View File

@@ -853,8 +853,7 @@ enum Targets
TARGET_DEST_CASTER_BACK_LEFT = 42, //water totem
TARGET_DEST_CASTER_BACK_RIGHT = 43, //air totem
TARGET_DEST_CASTER_FRONT_RIGHT = 44, //fire totem
TARGET_CHAIN_HEAL = 45,
//TARGET_UNIT_CHAINHEAL
TARGET_UNIT_CHAINHEAL = 45,
TARGET_SCRIPT_COORDINATES = 46,
//TARGET_DEST_NEARBY_ENTRY
TARGET_DEST_CASTER_FRONT = 47,

View File

@@ -1288,6 +1288,7 @@ struct ChainHealingOrder : public std::binary_function<const Unit*, const Unit*,
{
return (ChainHealingHash(_Left) < ChainHealingHash(_Right));
}
int32 ChainHealingHash(Unit const* Target) const
{
if (Target == MainTarget)
@@ -1305,18 +1306,6 @@ struct ChainHealingOrder : public std::binary_function<const Unit*, const Unit*,
}
};
class ChainHealingFullHealth: std::unary_function<const Unit*, bool>
{
public:
const Unit* MainTarget;
ChainHealingFullHealth(const Unit* Target) : MainTarget(Target) {};
bool operator()(const Unit* Target)
{
return (Target != MainTarget && Target->GetHealth() == Target->GetMaxHealth());
}
};
// Helper for targets nearest to the spell target
// The spell target is always first unless there is a target at _completely_ the same position (unbelievable case)
struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit, bool>
@@ -1341,7 +1330,15 @@ void Spell::SearchChainTarget(std::list<Unit*> &TagUnitMap, float max_range, uin
max_range += num * CHAIN_SPELL_JUMP_RADIUS;
std::list<Unit*> tempUnitMap;
SearchAreaTarget(tempUnitMap, max_range, PUSH_TARGET_CENTER, TargetType);
if(TargetType == SPELL_TARGETS_CHAINHEAL)
{
SearchAreaTarget(tempUnitMap, max_range, PUSH_TARGET_CENTER, SPELL_TARGETS_ALLY);
tempUnitMap.sort(ChainHealingOrder(m_caster));
if(cur->GetHealth() == cur->GetMaxHealth() && tempUnitMap.size())
cur = tempUnitMap.front();
}
else
SearchAreaTarget(tempUnitMap, max_range, PUSH_TARGET_CENTER, TargetType);
tempUnitMap.remove(cur);
while(num)
@@ -1352,19 +1349,34 @@ void Spell::SearchChainTarget(std::list<Unit*> &TagUnitMap, float max_range, uin
if(tempUnitMap.empty())
break;
tempUnitMap.sort(TargetDistanceOrder(cur));
std::list<Unit*>::iterator next = tempUnitMap.begin();
std::list<Unit*>::iterator next;
if(cur->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS)
break;
while(!cur->IsWithinLOSInMap(*next)
|| m_spellInfo->DmgClass==SPELL_DAMAGE_CLASS_MELEE
&& !m_caster->isInFront(*next, max_range))
if(TargetType == SPELL_TARGETS_CHAINHEAL)
{
++next;
if(next == tempUnitMap.end())
return;
next = tempUnitMap.begin();
while(cur->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS
|| !cur->IsWithinLOSInMap(*next))
{
++next;
if(next == tempUnitMap.end())
return;
}
}
else
{
tempUnitMap.sort(TargetDistanceOrder(cur));
next = tempUnitMap.begin();
if(cur->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS)
break;
while(!cur->IsWithinLOSInMap(*next)
|| m_spellInfo->DmgClass==SPELL_DAMAGE_CLASS_MELEE
&& !m_caster->isInFront(*next, max_range))
{
++next;
if(next == tempUnitMap.end() || cur->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS)
return;
}
}
cur = *next;
@@ -1537,6 +1549,12 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
else if(SelectMagnetTarget()) //TODO: chain target should also use magnet target
SearchChainTarget(TagUnitMap, radius, EffectChainTarget, SPELL_TARGETS_ENEMY);
break;
case TARGET_UNIT_CHAINHEAL:
if(EffectChainTarget <= 1)
TagUnitMap.push_back(target);
else
SearchChainTarget(TagUnitMap, radius, EffectChainTarget, SPELL_TARGETS_CHAINHEAL);
break;
}
}break;
@@ -1791,66 +1809,6 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
TagUnitMap.push_back(m_caster);
break;
}
case TARGET_CHAIN_HEAL:
{
Unit* pUnitTarget = m_targets.getUnitTarget();
if(!pUnitTarget)
break;
if (EffectChainTarget <= 1)
TagUnitMap.push_back(pUnitTarget);
else
{
unMaxTargets = EffectChainTarget;
float max_range = radius + unMaxTargets * CHAIN_SPELL_JUMP_RADIUS;
std::list<Unit *> tempUnitMap;
Trinity::SpellNotifierCreatureAndPlayer notifier(*this, tempUnitMap, max_range, PUSH_SELF_CENTER, SPELL_TARGETS_ALLY);
m_caster->VisitNearbyObject(max_range, notifier);
if(m_caster != pUnitTarget && std::find(tempUnitMap.begin(),tempUnitMap.end(),m_caster) == tempUnitMap.end() )
tempUnitMap.push_front(m_caster);
tempUnitMap.sort(TargetDistanceOrder(pUnitTarget));
if(tempUnitMap.empty())
break;
if(*tempUnitMap.begin() == pUnitTarget)
tempUnitMap.erase(tempUnitMap.begin());
TagUnitMap.push_back(pUnitTarget);
uint32 t = unMaxTargets - 1;
Unit *prev = pUnitTarget;
std::list<Unit*>::iterator next = tempUnitMap.begin();
while(t && next != tempUnitMap.end() )
{
if(prev->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS)
break;
if(!prev->IsWithinLOSInMap(*next))
{
++next;
continue;
}
if((*next)->GetHealth() == (*next)->GetMaxHealth())
{
next = tempUnitMap.erase(next);
continue;
}
prev = *next;
TagUnitMap.push_back(prev);
tempUnitMap.erase(next);
tempUnitMap.sort(TargetDistanceOrder(prev));
next = tempUnitMap.begin();
--t;
}
}
}break;
case TARGET_AREAEFFECT_PARTY_AND_CLASS:
{
Player* targetPlayer = m_targets.getUnitTarget() && m_targets.getUnitTarget()->GetTypeId() == TYPEID_PLAYER

View File

@@ -205,7 +205,8 @@ enum SpellTargets
{
SPELL_TARGETS_ALLY,
SPELL_TARGETS_ENEMY,
SPELL_TARGETS_ENTRY
SPELL_TARGETS_ENTRY,
SPELL_TARGETS_CHAINHEAL,
};
#define SPELL_SPELL_CHANNEL_UPDATE_INTERVAL 1000

View File

@@ -107,6 +107,7 @@ SpellMgr::SpellMgr()
case TARGET_UNIT_TARGET_ENEMY:
case TARGET_UNIT_TARGET_PARTY:
case TARGET_UNIT_PARTY_TARGET:
case TARGET_UNIT_CHAINHEAL:
SpellTargetType[i] = TARGET_TYPE_UNIT_TARGET;
break;
case TARGET_UNIT_CHANNEL: