CanCastResult BossSpellWorker::_BSWSpellSelector(uint8 m_uiSpellIdx, Unit* pTarget) { if (_bossSpellCount == 0) return CAST_FAIL_OTHER; SpellEntry const *spell; SpellTable* pSpell = &m_BossSpell[m_uiSpellIdx]; Unit* pSummon = NULL; debug_log("BSW: Casting spell number %u type %u",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget); switch (pSpell->m_CastTarget) { case DO_NOTHING: return CAST_OK; case CAST_ON_SELF: if (!pSpell->m_IsBugged) return _DoCastSpellIfCan(boss, pSpell->m_uiSpellEntry[currentDifficulty]); else return _BSWDoCast(m_uiSpellIdx, boss); break; case CAST_ON_SUMMONS: if (!pTarget) return CAST_FAIL_OTHER; else return _DoCastSpellIfCan(pTarget, pSpell->m_uiSpellEntry[currentDifficulty]); break; case CAST_ON_VICTIM: pTarget = boss->getVictim(); return _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_RANDOM: pTarget = SelectUnit(SELECT_TARGET_RANDOM); return _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_BOTTOMAGGRO: pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); return _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_TARGET: return _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case APPLY_AURA_SELF: if (spell = (SpellEntry *)GetSpellStore()->LookupEntry(pSpell->m_uiSpellEntry[currentDifficulty])) if(boss->AddAura(pSpell->m_uiSpellEntry[currentDifficulty], boss)) return CAST_OK; else return CAST_FAIL_OTHER; break; case APPLY_AURA_TARGET: if (!pTarget) return CAST_FAIL_OTHER; if (spell = (SpellEntry *)GetSpellStore()->LookupEntry(pSpell->m_uiSpellEntry[currentDifficulty])) if (pTarget->AddAura(pSpell->m_uiSpellEntry[currentDifficulty], pTarget)) return CAST_OK; else return CAST_FAIL_OTHER; break; case SUMMON_NORMAL: pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); if(pSummon) return CAST_OK; else return CAST_FAIL_OTHER; break; case SUMMON_TEMP: pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, urand(pSpell->m_uiSpellTimerMin[currentDifficulty],pSpell->m_uiSpellTimerMax[currentDifficulty])); if(pSummon) return CAST_OK; else return CAST_FAIL_OTHER; break; case SUMMON_INSTANT: pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_MANUAL_DESPAWN,0); if(pSummon) return CAST_OK; else return CAST_FAIL_OTHER; break; case CAST_ON_ALLPLAYERS: { CanCastResult res1 = CAST_FAIL_OTHER; Map::PlayerList const& pPlayers = pMap->GetPlayers(); for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr) { pTarget = itr->getSource(); if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(boss, pSpell->LocData.x)) if (!pSpell->m_IsBugged) { res1 = _DoCastSpellIfCan(pTarget, pSpell->m_uiSpellEntry[currentDifficulty]); } else { _BSWDoCast(m_uiSpellIdx, pTarget); res1 = CAST_OK; }; return res1; } break; } case CAST_ON_FRENDLY: pTarget = SelectLowHPFriendly(); return _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_FRENDLY_LOWHP: pTarget = SelectLowHPFriendly(); return _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; default: return CAST_FAIL_OTHER; break; }; return CAST_FAIL_OTHER; };
CanCastResult BSWScriptedAI::_BSWSpellSelector(uint8 m_uiSpellIdx, Unit* pTarget) { BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx]; Unit* pSummon = NULL; CanCastResult result = CAST_FAIL_OTHER; debug_log("BSW: Casting spell number %u type %u",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget); if (pSpell->m_uiSpellTimerMax[currentDifficulty] >= HOUR*IN_MILLISECONDS) m_creature->InterruptNonMeleeSpells(true); switch (pSpell->m_CastTarget) { case DO_NOTHING: result = CAST_OK; break; case CAST_ON_SELF: result = _BSWCastOnTarget(m_creature, m_uiSpellIdx); break; case CAST_ON_SUMMONS: result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_VICTIM: pTarget = m_creature->getVictim(); result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_RANDOM: pTarget = _doSelect(0, false, 60.0f); result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_BOTTOMAGGRO: pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_BOTTOMAGGRO,0); result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_TARGET: result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case APPLY_AURA_SELF: if (_doAura(m_uiSpellIdx, m_creature, EFFECT_INDEX_0)) result = CAST_OK; else result = CAST_FAIL_OTHER; break; case APPLY_AURA_TARGET: if (!pTarget || !pTarget->IsInMap(m_creature)) { result = CAST_FAIL_OTHER; break; } if (_doAura(m_uiSpellIdx, pTarget, EFFECT_INDEX_0)) result = CAST_OK; else result = CAST_FAIL_OTHER; break; case SUMMON_NORMAL: pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); if(pSummon) result = CAST_OK; else result = CAST_FAIL_OTHER; break; case SUMMON_TEMP: pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, urand(pSpell->m_uiSpellTimerMin[currentDifficulty],pSpell->m_uiSpellTimerMax[currentDifficulty])); if(pSummon) result = CAST_OK; else result = CAST_FAIL_OTHER; break; case SUMMON_INSTANT: pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_MANUAL_DESPAWN,0); if(pSummon) result = CAST_OK; else result = CAST_FAIL_OTHER; break; case CAST_ON_ALLPLAYERS: { Map* pMap = m_creature->GetMap(); Map::PlayerList const& pPlayers = pMap->GetPlayers(); if (!pPlayers.isEmpty()) { for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr) { pTarget = itr->getSource(); if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(m_creature, pSpell->LocData.x)) { if (!pSpell->m_IsBugged) { m_creature->CastSpell(pTarget, pSpell->m_uiSpellEntry[currentDifficulty], false); } else { _BSWDoCast(m_uiSpellIdx, pTarget); }; result = CAST_OK; }; } } else result = CAST_FAIL_OTHER; } break; case CAST_ON_FRENDLY: pTarget = DoSelectLowestHpFriendly(pSpell->LocData.x,0); result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_FRENDLY_LOWHP: pTarget = DoSelectLowestHpFriendly(pSpell->LocData.x,1); result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_RANDOM_POINT: if (!pTarget) pTarget = m_creature; if (pSpell->LocData.z <= 1.0f) { float fPosX, fPosY, fPosZ; if (!pTarget->IsPositionValid() || !pTarget->IsInMap(m_creature)) { if (pTarget->GetTypeId() == TYPEID_PLAYER) error_log("BSW: CAST_ON_RANDOM_POINT FAILED: player has invalid position. SpellID is %u",pSpell->m_uiSpellEntry[currentDifficulty]); else error_log("BSW: CAST_ON_RANDOM_POINT FAILED: creature has invalid position. SpellID is %u",pSpell->m_uiSpellEntry[currentDifficulty]); result = CAST_FAIL_OTHER; break; } pTarget->GetPosition(fPosX, fPosY, fPosZ); pTarget->GetRandomPoint(fPosX, fPosY, fPosZ, urand((uint32)pSpell->LocData.x, (uint32)pSpell->LocData.y), fPosX, fPosY, fPosZ); if ((int)fPosZ == 0) { error_log("BSW: CAST_ON_RANDOM_POINT FAILED: Positon Z is NULL. Strange bug"); result = CAST_FAIL_OTHER; break; } if (SpellEntry const *spell = (SpellEntry *)GetSpellStore()->LookupEntry(pSpell->m_uiSpellEntry[currentDifficulty])) if (SpellRangeEntry const *pSpellRange = GetSpellRangeStore()->LookupEntry(spell->rangeIndex)) if (m_creature->GetDistance(fPosX, fPosY, fPosZ) <= pSpellRange->maxRange) { m_creature->CastSpell(fPosX, fPosY, fPosZ, pSpell->m_uiSpellEntry[currentDifficulty], false); result = CAST_OK; break; }; result = CAST_FAIL_TOO_FAR; } else result = CAST_FAIL_OTHER; break; case CAST_ON_RANDOM_PLAYER: if ( pSpell->LocData.x < 1 ) pTarget = _doSelect(0, false, 60.0f); else pTarget = _doSelect(0, false, (float)pSpell->LocData.x); result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case APPLY_AURA_ALLPLAYERS: { Map* pMap = m_creature->GetMap(); Map::PlayerList const& pPlayers = pMap->GetPlayers(); for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr) { pTarget = itr->getSource(); if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(m_creature, pSpell->LocData.x)) { _doAura(m_uiSpellIdx, pTarget, EFFECT_INDEX_0); result = CAST_OK; } } } break; case FORCE_CAST: result = _BSWDoForceCast(m_uiSpellIdx, pTarget); break; case SPELLTABLEPARM_NUMBER: default: error_log("BSW: FAILED casting spell number %u type %u - type not exists",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget); result = CAST_FAIL_OTHER; break; }; if (pSpell->textEntry && result == CAST_OK) { if (pTarget) DoScriptText(pSpell->textEntry,m_creature,pTarget); else DoScriptText(pSpell->textEntry,m_creature); }; debug_log("BSW: Casted spell number %u, result = %u",pSpell->m_uiSpellEntry[currentDifficulty], result); return result; };
CanCastResult BossSpellWorker::_BSWSpellSelector(uint8 m_uiSpellIdx, Unit* pTarget) { SpellEntry const *spell; SpellTable* pSpell = &m_BossSpell[m_uiSpellIdx]; Unit* pSummon = NULL; debug_log("BSW: Casting spell number %u type %u",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget); switch (pSpell->m_CastTarget) { case DO_NOTHING: return CAST_OK; case CAST_ON_SELF: if (!pSpell->m_IsBugged) return _DoCastSpellIfCan(boss, pSpell->m_uiSpellEntry[currentDifficulty]); else return _BSWDoCast(m_uiSpellIdx, boss); break; case CAST_ON_SUMMONS: if (!pTarget) return CAST_FAIL_OTHER; else return _DoCastSpellIfCan(pTarget, pSpell->m_uiSpellEntry[currentDifficulty]); break; case CAST_ON_VICTIM: pTarget = boss->getVictim(); return _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_RANDOM: pTarget = boss->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); return _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_BOTTOMAGGRO: pTarget = boss->SelectAttackingTarget(ATTACKING_TARGET_BOTTOMAGGRO,0); return _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_TARGET: return _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case APPLY_AURA_SELF: spell = (SpellEntry *)GetSpellStore()->LookupEntry(pSpell->m_uiSpellEntry[currentDifficulty]); if (spell) if (boss->AddAura(new BossAura(spell, EFFECT_INDEX_0, &pSpell->varData, boss, boss))) return CAST_OK; return CAST_FAIL_OTHER; break; case APPLY_AURA_TARGET: if (!pTarget || !pTarget->IsInMap(boss)) return CAST_FAIL_OTHER; _doAura(m_uiSpellIdx, pTarget, EFFECT_INDEX_0); return CAST_OK; break; case SUMMON_NORMAL: pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); if(pSummon) return CAST_OK; else return CAST_FAIL_OTHER; break; case SUMMON_TEMP: pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, urand(pSpell->m_uiSpellTimerMin[currentDifficulty],pSpell->m_uiSpellTimerMax[currentDifficulty])); if(pSummon) return CAST_OK; else return CAST_FAIL_OTHER; break; case SUMMON_INSTANT: pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_MANUAL_DESPAWN,0); if(pSummon) return CAST_OK; else return CAST_FAIL_OTHER; break; case CAST_ON_ALLPLAYERS: { CanCastResult res1 = CAST_FAIL_OTHER; Map::PlayerList const& pPlayers = pMap->GetPlayers(); for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr) { pTarget = itr->getSource(); if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(boss, pSpell->LocData.x)) { if (!pSpell->m_IsBugged) { res1 = _DoCastSpellIfCan(pTarget, pSpell->m_uiSpellEntry[currentDifficulty]); } else { _BSWDoCast(m_uiSpellIdx, pTarget); res1 = CAST_OK; }; }; return res1; } break; } case CAST_ON_FRENDLY: pTarget = SelectLowHPFriendly(pSpell->LocData.x); return _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_FRENDLY_LOWHP: pTarget = SelectLowHPFriendly(pSpell->LocData.x); return _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_RANDOM_POINT: if (!pTarget) pTarget = boss; if (pSpell->LocData.z <= 1.0f) { float fPosX, fPosY, fPosZ; if (!pTarget->IsPositionValid() || !pTarget->IsInMap(boss)) { if (pTarget->GetTypeId() == TYPEID_PLAYER) error_log("BSW: CAST_ON_RANDOM_POINT FAILED: player has invalid position. SpellID is %u",pSpell->m_uiSpellEntry[currentDifficulty]); else error_log("BSW: CAST_ON_RANDOM_POINT FAILED: creature has invalid position. SpellID is %u",pSpell->m_uiSpellEntry[currentDifficulty]); return CAST_FAIL_OTHER; } pTarget->GetPosition(fPosX, fPosY, fPosZ); pTarget->GetRandomPoint(fPosX, fPosY, fPosZ, urand((uint32)pSpell->LocData.x, (uint32)pSpell->LocData.y), fPosX, fPosY, fPosZ); if ((int)fPosZ == 0) { error_log("BSW: CAST_ON_RANDOM_POINT FAILED: Positon Z is NULL. Strange bug"); return CAST_FAIL_OTHER; } if (SpellEntry const *spell = (SpellEntry *)GetSpellStore()->LookupEntry(pSpell->m_uiSpellEntry[currentDifficulty])) if (SpellRangeEntry const *pSpellRange = GetSpellRangeStore()->LookupEntry(spell->rangeIndex)) if (boss->GetDistance(fPosX, fPosY, fPosZ) <= pSpellRange->maxRange) { boss->CastSpell(fPosX, fPosY, fPosZ, pSpell->m_uiSpellEntry[currentDifficulty], false); return CAST_OK; }; return CAST_FAIL_TOO_FAR; } else return CAST_FAIL_OTHER; break; case CAST_ON_RANDOM_PLAYER: if ( pSpell->LocData.x < 1 ) pTarget = SelectRandomPlayer(); else pTarget = SelectRandomPlayerAtRange((float)pSpell->LocData.x); if (pTarget && pTarget->IsInMap(boss)) return _BSWCastOnTarget(pTarget, m_uiSpellIdx); else return CAST_FAIL_OTHER; break; case APPLY_AURA_ALLPLAYERS: { Map::PlayerList const& pPlayers = pMap->GetPlayers(); for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr) { pTarget = itr->getSource(); if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(boss, pSpell->LocData.x)) _doAura(m_uiSpellIdx, pTarget, EFFECT_INDEX_0); } return CAST_OK; } break; case SPELLTABLEPARM_NUMBER: default: return CAST_FAIL_OTHER; break; }; error_log("BSW: FAILED casting spell number %u type %u - type not exists",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget); return CAST_FAIL_OTHER; };