📄 skill.cpp.svn-base
字号:
target.reflectResult = SKILLS_MISS_NONE;
// Add target to list
m_UniqueTargetInfo.push_back(target);
}
void SKILLS::AddUnitTarget(uint64 unitGUID, uint32 effIndex)
{
Unit* unit = m_caster->GetGUID()==unitGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, unitGUID);
if (unit)
AddUnitTarget(unit, effIndex);
}
void SKILLS::AddGOTarget(GameObject* pVictim, uint32 effIndex)
{
if( m_SKILLSInfo->Effect[effIndex]==0 )
return;
uint64 targetGUID = pVictim->GetGUID();
// Lookup target in already in list
for(std::list<GOTargetInfo>::iterator ihit= m_UniqueGOTargetInfo.begin();ihit != m_UniqueGOTargetInfo.end();++ihit)
{
if (targetGUID == ihit->targetGUID) // Found in list
{
ihit->effectMask |= 1<<effIndex; // Add only effect mask
return;
}
}
// This is new target calculate data for him
GOTargetInfo target;
target.targetGUID = targetGUID;
target.effectMask = 1<<effIndex;
// SKILLS have speed - need calculate incoming time
if (m_SKILLSInfo->speed > 0.0f)
{
// calculate SKILLS incoming interval
float dist = m_caster->GetDistance(pVictim->GetPositionX(), pVictim->GetPositionY(), pVictim->GetPositionZ());
if (dist < 5.0f) dist = 5.0f;
target.timeDelay = (uint64) floor(dist / m_SKILLSInfo->speed * 1000.0f);
if (m_delayMoment==0 || m_delayMoment>target.timeDelay)
m_delayMoment = target.timeDelay;
}
else
target.timeDelay = 0LL;
++m_countOfHit;
// Add target to list
m_UniqueGOTargetInfo.push_back(target);
}
void SKILLS::AddGOTarget(uint64 goGUID, uint32 effIndex)
{
GameObject* go = ObjectAccessor::GetGameObject(*m_caster, goGUID);
if (go)
AddGOTarget(go, effIndex);
}
void SKILLS::AddItemTarget(Item* pitem, uint32 effIndex)
{
if( m_SKILLSInfo->Effect[effIndex]==0 )
return;
// Lookup target in already in list
for(std::list<ItemTargetInfo>::iterator ihit= m_UniqueItemInfo.begin();ihit != m_UniqueItemInfo.end();++ihit)
{
if (pitem == ihit->item) // Found in list
{
ihit->effectMask |= 1<<effIndex; // Add only effect mask
return;
}
}
// This is new target add data
ItemTargetInfo target;
target.item = pitem;
target.effectMask = 1<<effIndex;
m_UniqueItemInfo.push_back(target);
}
void SKILLS::doTriggers(SKILLSMissInfo missInfo, uint32 damage, uint32 block, uint32 absorb, bool crit)
{
// Do triggers depenends from hit result (triggers on hit do in effects)
// Set aura states depends from hit result
if (missInfo!=SKILLS_MISS_NONE)
{
// Miss/dodge/parry/block only for melee based SKILLSs
// Resist only for magic based SKILLSs
switch (missInfo)
{
case SKILLS_MISS_MISS:
if(m_caster->GetTypeId()== TYPEID_PLAYER)
((Player*)m_caster)->UpdateWeaponSkill(BASE_ATTACK);
m_caster->CastMeleeProcDamageAndSKILLS(unitTarget, 0, m_attackType, MELEE_HIT_MISS, m_SKILLSInfo, m_IsTriggeredSKILLS);
break;
case SKILLS_MISS_RESIST:
m_caster->ProcDamageAndSKILLS(unitTarget, PROC_FLAG_TARGET_RESISTS, PROC_FLAG_RESIST_SKILLS, 0, m_SKILLSInfo, m_IsTriggeredSKILLS);
break;
case SKILLS_MISS_DODGE:
if(unitTarget->GetTypeId() == TYPEID_PLAYER)
((Player*)unitTarget)->UpdateDefense();
// Overpower
if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->getClass() == CLASS_WARRIOR)
{
((Player*) m_caster)->AddComboPoints(unitTarget, 1);
m_caster->StartReactiveTimer( REACTIVE_OVERPOWER );
}
// Riposte
if (unitTarget->getClass() != CLASS_ROGUE)
{
unitTarget->ModifyAuraState(AURA_STATE_DEFENSE, true);
unitTarget->StartReactiveTimer( REACTIVE_DEFENSE );
}
m_caster->CastMeleeProcDamageAndSKILLS(unitTarget, 0, m_attackType, MELEE_HIT_DODGE, m_SKILLSInfo, m_IsTriggeredSKILLS);
break;
case SKILLS_MISS_PARRY:
// Update victim defense ?
if(unitTarget->GetTypeId() == TYPEID_PLAYER)
((Player*)unitTarget)->UpdateDefense();
// Mongoose bite - set only Counterattack here
if (unitTarget->getClass() == CLASS_HUNTER)
{
unitTarget->ModifyAuraState(AURA_STATE_HUNTER_PARRY,true);
unitTarget->StartReactiveTimer( REACTIVE_HUNTER_PARRY );
}
else
{
unitTarget->ModifyAuraState(AURA_STATE_DEFENSE, true);
unitTarget->StartReactiveTimer( REACTIVE_DEFENSE );
}
m_caster->CastMeleeProcDamageAndSKILLS(unitTarget, 0, m_attackType, MELEE_HIT_PARRY, m_SKILLSInfo, m_IsTriggeredSKILLS);
break;
case SKILLS_MISS_BLOCK:
unitTarget->ModifyAuraState(AURA_STATE_DEFENSE, true);
unitTarget->StartReactiveTimer( REACTIVE_DEFENSE );
m_caster->CastMeleeProcDamageAndSKILLS(unitTarget, 0, m_attackType, MELEE_HIT_BLOCK, m_SKILLSInfo, m_IsTriggeredSKILLS);
break;
// Trigger from this events not supported
case SKILLS_MISS_EVADE:
case SKILLS_MISS_IMMUNE:
case SKILLS_MISS_IMMUNE2:
case SKILLS_MISS_DEFLECT:
case SKILLS_MISS_ABSORB:
// Trigger from reflects need do after get reflect result
case SKILLS_MISS_REFLECT:
break;
default:
break;
}
}
}
void SKILLS::DoAllEffectOnTarget(TargetInfo *target)
{
// Get mask of effects for target
uint32 mask = target->effectMask;
if (mask == 0) // No effects
return;
Unit* unit = m_caster->GetGUID()==target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster,target->targetGUID);
if (unit==NULL)
return;
SKILLSMissInfo missInfo = target->missCondition;
// Need init unitTarget by default unit (can changed in code on reflect)
// Or on missInfo!=SKILLS_MISS_NONE unitTarget undefined (but need in trigger subsystem)
unitTarget = unit;
if (missInfo==SKILLS_MISS_NONE) // In case SKILLS hit target, do all effect on that target
DoSKILLSHitOnUnit(unit, mask);
else if (missInfo == SKILLS_MISS_REFLECT) // In case SKILLS reflect from target, do all effect on caster (if hit)
{
if (target->reflectResult == SKILLS_MISS_NONE) // If reflected SKILLS hit caster -> do all effect on him
DoSKILLSHitOnUnit(m_caster, mask);
}
// Do triggers only on miss/resist/parry/dodge
if (missInfo!=SKILLS_MISS_NONE)
doTriggers(missInfo);
// Call scripted function for AI if this SKILLS is casted upon a creature
if(IS_CREATURE_GUID(target->targetGUID))
{
// cast at creature (or GO) quest objectives update at succesful cast finished (+channel finished)
// ignore autorepeat/melee casts for speed (not exist quest for SKILLSs (hm... )
if( m_caster->GetTypeId() == TYPEID_PLAYER && !IsAutoRepeat() && !IsMeleeSKILLS() && !IsChannelActive() )
((Player*)m_caster)->CastedCreatureOrGO(unit->Getid(),unit->GetGUID(),m_SKILLSInfo->Id);
if(((Creature*)unit)->AI())
((Creature*)unit)->AI()->SKILLSHit(m_caster ,m_SKILLSInfo);
}
}
void SKILLS::DoSKILLSHitOnUnit(Unit *unit, const uint32 effectMask)
{
if(!unit || !effectMask)
return;
// Recheck immune (only for delayed SKILLSs)
if (m_SKILLSInfo->speed && (unit->IsImmunedToSKILLSDamage(m_SKILLSInfo,true) || unit->IsImmunedToSKILLS(m_SKILLSInfo,true)))
{
m_caster->SendSKILLSMiss(unit, m_SKILLSInfo->Id, SKILLS_MISS_IMMUNE);
return;
}
for(uint32 effectNumber=0;effectNumber<3;effectNumber++)
{
if (effectMask & (1<<effectNumber))
{
HandleEffects(unit,NULL,NULL,effectNumber,m_damageMultipliers[effectNumber]);
if ( m_applyMultiplier[effectNumber] )
{
// Get multiplier
float multiplier = m_SKILLSInfo->DmgMultiplier[effectNumber];
// Apply multiplier mods
if(Player* modOwner = m_originalCaster->GetSKILLSModOwner())
modOwner->ApplySKILLSMod(m_SKILLSInfo->Id, SKILLSMOD_EFFECT_PAST_FIRST, multiplier,this);
m_damageMultipliers[effectNumber] *= multiplier;
}
}
}
}
void SKILLS::DoAllEffectOnTarget(GOTargetInfo *target)
{
uint32 effectMask = target->effectMask;
if(!effectMask)
return;
GameObject* go = ObjectAccessor::GetGameObject(*m_caster, target->targetGUID);
if(!go)
return;
for(uint32 effectNumber=0;effectNumber<3;effectNumber++)
if (effectMask & (1<<effectNumber))
HandleEffects(NULL,NULL,go,effectNumber);
// cast at creature (or GO) quest objectives update at succesful cast finished (+channel finished)
// ignore autorepeat/melee casts for speed (not exist quest for SKILLSs (hm... )
if( m_caster->GetTypeId() == TYPEID_PLAYER && !IsAutoRepeat() && !IsMeleeSKILLS() && !IsChannelActive() )
((Player*)m_caster)->CastedCreatureOrGO(go->Getid(),go->GetGUID(),m_SKILLSInfo->Id);
}
void SKILLS::DoAllEffectOnTarget(ItemTargetInfo *target)
{
uint32 effectMask = target->effectMask;
if(!target->item || !effectMask)
return;
for(uint32 effectNumber=0;effectNumber<3;effectNumber++)
if (effectMask & (1<<effectNumber))
HandleEffects(NULL, target->item, NULL, effectNumber);
}
bool SKILLS::IsAliveUnitPresentInTargetList()
{
// Not need check return true
if (m_needAliveTargetMask == 0)
return true;
uint8 needAliveTargetMask = m_needAliveTargetMask;
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
{
if( ihit->missCondition == SKILLS_MISS_NONE && (needAliveTargetMask & ihit->effectMask) )
{
Unit *unit = m_caster->GetGUID()==ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
if (unit && unit->isAlive())
needAliveTargetMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
}
}
// is all effects from m_needAliveTargetMask have alive targets
return needAliveTargetMask==0;
}
// Helper for Chain Healing
// SKILLS target first
// Raidmates then descending by injury suffered (MaxHealth - Health)
// Other players/mobs then descending by injury suffered (MaxHealth - Health)
struct ChainHealingOrder : public std::binary_function<const Unit*, const Unit*, bool>
{
const Unit* MainTarget;
ChainHealingOrder(Unit const* Target) : MainTarget(Target) {};
// functor for operator ">"
bool operator()(Unit const* _Left, Unit const* _Right) const
{
return (ChainHealingHash(_Left) < ChainHealingHash(_Right));
}
int32 ChainHealingHash(Unit const* Target) const
{
if (Target == MainTarget)
return 0;
else if (Target->GetTypeId() == TYPEID_PLAYER && MainTarget->GetTypeId() == TYPEID_PLAYER &&
((Player const*)Target)->IsInSameRaidWith((Player const*)MainTarget))
{
if (Target->GetHealth() == Target->GetMaxHealth())
return 40000;
else
return 20000 - Target->GetMaxHealth() + Target->GetHealth();
}
else
return 40000 - Target->GetMaxHealth() + Target->GetHealth();
}
};
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());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -