mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 13:37:05 +00:00
[7852] Use union of per-event type structures, more checks at creature event ai loading.
Including: * Fixed check for EVENT_T_SPELLHIT school field. Add check at loading. Note: this event expect before and now schol _mask_ in param2. * In EVENT_T_RECEIVE_EMOTE use original player condition check code instead copy of related code.
This commit is contained in:
parent
e712baa58c
commit
72b4ff2fac
4 changed files with 262 additions and 403 deletions
|
|
@ -30,6 +30,22 @@
|
||||||
#include "WorldPacket.h"
|
#include "WorldPacket.h"
|
||||||
#include "InstanceData.h"
|
#include "InstanceData.h"
|
||||||
|
|
||||||
|
bool CreatureEventAIHolder::UpdateRepeatTimer( Creature* creature, uint32 repeatMin, uint32 repeatMax )
|
||||||
|
{
|
||||||
|
if (repeatMin == repeatMax)
|
||||||
|
Time = repeatMin;
|
||||||
|
else if (repeatMax > repeatMin)
|
||||||
|
Time = urand(repeatMin, repeatMax);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", creature->GetEntry(), Event.event_id, Event.event_type);
|
||||||
|
Enabled = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int CreatureEventAI::Permissible(const Creature *creature)
|
int CreatureEventAI::Permissible(const Creature *creature)
|
||||||
{
|
{
|
||||||
if( creature->GetAIName() == "EventAI" )
|
if( creature->GetAIName() == "EventAI" )
|
||||||
|
|
@ -106,53 +122,25 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
if (pHolder.Event.event_chance <= rnd % 100)
|
if (pHolder.Event.event_chance <= rnd % 100)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint32 param1 = pHolder.Event.event_param1;
|
CreatureEventAI_Event const& event = pHolder.Event;
|
||||||
uint32 param2 = pHolder.Event.event_param2;
|
|
||||||
uint32 param3 = pHolder.Event.event_param3;
|
|
||||||
uint32 param4 = pHolder.Event.event_param4;
|
|
||||||
|
|
||||||
//Check event conditions based on the event type, also reset events
|
//Check event conditions based on the event type, also reset events
|
||||||
switch (pHolder.Event.event_type)
|
switch (event.event_type)
|
||||||
{
|
{
|
||||||
case EVENT_T_TIMER:
|
case EVENT_T_TIMER:
|
||||||
{
|
|
||||||
if (!m_creature->isInCombat())
|
if (!m_creature->isInCombat())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//Repeat Timers
|
//Repeat Timers
|
||||||
if (param3 == param4)
|
pHolder.UpdateRepeatTimer(m_creature,event.timer.repeatMin,event.timer.repeatMax);
|
||||||
{
|
break;
|
||||||
pHolder.Time = param3;
|
|
||||||
|
|
||||||
}else if (param4 > param3)
|
|
||||||
pHolder.Time = urand(param3, param4);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
|
||||||
pHolder.Enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EVENT_T_TIMER_OOC:
|
case EVENT_T_TIMER_OOC:
|
||||||
{
|
|
||||||
if (m_creature->isInCombat())
|
if (m_creature->isInCombat())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//Repeat Timers
|
//Repeat Timers
|
||||||
if (param3 == param4)
|
pHolder.UpdateRepeatTimer(m_creature,event.timer.repeatMin,event.timer.repeatMax);
|
||||||
{
|
break;
|
||||||
pHolder.Time = param3;
|
|
||||||
|
|
||||||
}else if (param4 > param3)
|
|
||||||
pHolder.Time = urand(param3, param4);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
|
||||||
pHolder.Enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EVENT_T_HP:
|
case EVENT_T_HP:
|
||||||
{
|
{
|
||||||
if (!m_creature->isInCombat() || !m_creature->GetMaxHealth())
|
if (!m_creature->isInCombat() || !m_creature->GetMaxHealth())
|
||||||
|
|
@ -160,24 +148,13 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
|
|
||||||
uint32 perc = (m_creature->GetHealth()*100) / m_creature->GetMaxHealth();
|
uint32 perc = (m_creature->GetHealth()*100) / m_creature->GetMaxHealth();
|
||||||
|
|
||||||
if (perc > param1 || perc < param2)
|
if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//Repeat Timers
|
//Repeat Timers
|
||||||
if (param3 == param4)
|
pHolder.UpdateRepeatTimer(m_creature,event.percent_range.repeatMin,event.percent_range.repeatMax);
|
||||||
{
|
break;
|
||||||
pHolder.Time = param3;
|
|
||||||
|
|
||||||
}else if (param4 > param3)
|
|
||||||
pHolder.Time = urand(param3, param4);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
|
||||||
pHolder.Enabled = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case EVENT_T_MANA:
|
case EVENT_T_MANA:
|
||||||
{
|
{
|
||||||
if (!m_creature->isInCombat() || !m_creature->GetMaxPower(POWER_MANA))
|
if (!m_creature->isInCombat() || !m_creature->GetMaxPower(POWER_MANA))
|
||||||
|
|
@ -185,109 +162,38 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
|
|
||||||
uint32 perc = (m_creature->GetPower(POWER_MANA)*100) / m_creature->GetMaxPower(POWER_MANA);
|
uint32 perc = (m_creature->GetPower(POWER_MANA)*100) / m_creature->GetMaxPower(POWER_MANA);
|
||||||
|
|
||||||
if (perc > param1 || perc < param2)
|
if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//Repeat Timers
|
//Repeat Timers
|
||||||
if (param3 == param4)
|
pHolder.UpdateRepeatTimer(m_creature,event.percent_range.repeatMin,event.percent_range.repeatMax);
|
||||||
{
|
break;
|
||||||
pHolder.Time = param3;
|
|
||||||
|
|
||||||
}else if (param4 > param3)
|
|
||||||
pHolder.Time = urand(param3, param4);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
|
||||||
pHolder.Enabled = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case EVENT_T_AGGRO:
|
case EVENT_T_AGGRO:
|
||||||
{
|
break;
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EVENT_T_KILL:
|
case EVENT_T_KILL:
|
||||||
{
|
|
||||||
//Repeat Timers
|
//Repeat Timers
|
||||||
if (param1 == param2)
|
pHolder.UpdateRepeatTimer(m_creature,event.kill.repeatMin,event.kill.repeatMax);
|
||||||
{
|
break;
|
||||||
pHolder.Time = param1;
|
|
||||||
|
|
||||||
}else if (param2 > param1)
|
|
||||||
pHolder.Time = urand(param1, param2);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
|
||||||
pHolder.Enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case EVENT_T_DEATH:
|
case EVENT_T_DEATH:
|
||||||
{
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EVENT_T_EVADE:
|
case EVENT_T_EVADE:
|
||||||
{
|
break;
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EVENT_T_SPELLHIT:
|
case EVENT_T_SPELLHIT:
|
||||||
{
|
|
||||||
//Spell hit is special case, param1 and param2 handled within CreatureEventAI::SpellHit
|
//Spell hit is special case, param1 and param2 handled within CreatureEventAI::SpellHit
|
||||||
|
|
||||||
//Repeat Timers
|
//Repeat Timers
|
||||||
if (param3 == param4)
|
pHolder.UpdateRepeatTimer(m_creature,event.spell_hit.repeatMin,event.spell_hit.repeatMax);
|
||||||
{
|
break;
|
||||||
pHolder.Time = param3;
|
|
||||||
|
|
||||||
}else if (param4 > param3)
|
|
||||||
pHolder.Time = urand(param3, param4);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
|
||||||
pHolder.Enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EVENT_T_RANGE:
|
case EVENT_T_RANGE:
|
||||||
{
|
|
||||||
//Repeat Timers
|
//Repeat Timers
|
||||||
if (param3 == param4)
|
pHolder.UpdateRepeatTimer(m_creature,event.range.repeatMin,event.range.repeatMax);
|
||||||
{
|
break;
|
||||||
pHolder.Time = param3;
|
|
||||||
|
|
||||||
}else if (param4 > param3)
|
|
||||||
pHolder.Time = urand(param3, param4);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
|
||||||
pHolder.Enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EVENT_T_OOC_LOS:
|
case EVENT_T_OOC_LOS:
|
||||||
{
|
|
||||||
//Repeat Timers
|
//Repeat Timers
|
||||||
if (param3 == param4)
|
pHolder.UpdateRepeatTimer(m_creature,event.ooc_los.repeatMin,event.ooc_los.repeatMax);
|
||||||
{
|
break;
|
||||||
pHolder.Time = param3;
|
|
||||||
|
|
||||||
}else if (param4 > param3)
|
|
||||||
pHolder.Time = urand(param3, param4);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
|
||||||
pHolder.Enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EVENT_T_SPAWNED:
|
case EVENT_T_SPAWNED:
|
||||||
{
|
break;
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EVENT_T_TARGET_HP:
|
case EVENT_T_TARGET_HP:
|
||||||
{
|
{
|
||||||
if (!m_creature->isInCombat() || !m_creature->getVictim() || !m_creature->getVictim()->GetMaxHealth())
|
if (!m_creature->isInCombat() || !m_creature->getVictim() || !m_creature->getVictim()->GetMaxHealth())
|
||||||
|
|
@ -295,78 +201,42 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
|
|
||||||
uint32 perc = (m_creature->getVictim()->GetHealth()*100) / m_creature->getVictim()->GetMaxHealth();
|
uint32 perc = (m_creature->getVictim()->GetHealth()*100) / m_creature->getVictim()->GetMaxHealth();
|
||||||
|
|
||||||
if (perc > param1 || perc < param2)
|
if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//Repeat Timers
|
//Repeat Timers
|
||||||
if (param3 == param4)
|
pHolder.UpdateRepeatTimer(m_creature,event.percent_range.repeatMin,event.percent_range.repeatMax);
|
||||||
{
|
break;
|
||||||
pHolder.Time = param3;
|
|
||||||
|
|
||||||
}else if (param4 > param3)
|
|
||||||
pHolder.Time = urand(param3, param4);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
|
||||||
pHolder.Enabled = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case EVENT_T_TARGET_CASTING:
|
case EVENT_T_TARGET_CASTING:
|
||||||
{
|
|
||||||
if (!m_creature->isInCombat() || !m_creature->getVictim() || !m_creature->getVictim()->IsNonMeleeSpellCasted(false, false, true))
|
if (!m_creature->isInCombat() || !m_creature->getVictim() || !m_creature->getVictim()->IsNonMeleeSpellCasted(false, false, true))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//Repeat Timers
|
//Repeat Timers
|
||||||
if (param1 == param2)
|
pHolder.UpdateRepeatTimer(m_creature,event.target_casting.repeatMin,event.target_casting.repeatMax);
|
||||||
{
|
break;
|
||||||
pHolder.Time = param1;
|
|
||||||
|
|
||||||
}else if (param2 > param1)
|
|
||||||
pHolder.Time = urand(param1, param2);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
|
||||||
pHolder.Enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EVENT_T_FRIENDLY_HP:
|
case EVENT_T_FRIENDLY_HP:
|
||||||
{
|
{
|
||||||
if (!m_creature->isInCombat())
|
if (!m_creature->isInCombat())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Unit* pUnit = DoSelectLowestHpFriendly(param2, param1);
|
Unit* pUnit = DoSelectLowestHpFriendly(event.friendly_hp.radius, event.friendly_hp.hpDeficit);
|
||||||
|
|
||||||
if (!pUnit)
|
if (!pUnit)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
pActionInvoker = pUnit;
|
pActionInvoker = pUnit;
|
||||||
|
|
||||||
//Repeat Timers
|
//Repeat Timers
|
||||||
if (param3 == param4)
|
pHolder.UpdateRepeatTimer(m_creature,event.friendly_hp.repeatMin,event.friendly_hp.repeatMax);
|
||||||
{
|
break;
|
||||||
pHolder.Time = param3;
|
|
||||||
|
|
||||||
}else if (param4 > param3)
|
|
||||||
pHolder.Time = urand(param3, param4);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
|
||||||
pHolder.Enabled = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case EVENT_T_FRIENDLY_IS_CC:
|
case EVENT_T_FRIENDLY_IS_CC:
|
||||||
{
|
{
|
||||||
if (!m_creature->isInCombat())
|
if (!m_creature->isInCombat())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::list<Creature*> pList;
|
std::list<Creature*> pList;
|
||||||
DoFindFriendlyCC(pList, param2);
|
DoFindFriendlyCC(pList, event.friendly_is_cc.radius);
|
||||||
|
|
||||||
//List is empty
|
//List is empty
|
||||||
if (pList.empty())
|
if (pList.empty())
|
||||||
|
|
@ -376,23 +246,13 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
pActionInvoker = *(pList.begin());
|
pActionInvoker = *(pList.begin());
|
||||||
|
|
||||||
//Repeat Timers
|
//Repeat Timers
|
||||||
if (param3 == param4)
|
pHolder.UpdateRepeatTimer(m_creature,event.friendly_is_cc.repeatMin,event.friendly_is_cc.repeatMax);
|
||||||
{
|
break;
|
||||||
pHolder.Time = param3;
|
|
||||||
|
|
||||||
}else if (param4 > param3)
|
|
||||||
pHolder.Time = urand(param3, param4);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
|
||||||
pHolder.Enabled = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case EVENT_T_FRIENDLY_MISSING_BUFF:
|
case EVENT_T_FRIENDLY_MISSING_BUFF:
|
||||||
{
|
{
|
||||||
std::list<Creature*> pList;
|
std::list<Creature*> pList;
|
||||||
DoFindFriendlyMissingBuff(pList, param2, param1);
|
DoFindFriendlyMissingBuff(pList, event.friendly_buff.radius, event.friendly_buff.spellId);
|
||||||
|
|
||||||
//List is empty
|
//List is empty
|
||||||
if (pList.empty())
|
if (pList.empty())
|
||||||
|
|
@ -402,20 +262,9 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
pActionInvoker = *(pList.begin());
|
pActionInvoker = *(pList.begin());
|
||||||
|
|
||||||
//Repeat Timers
|
//Repeat Timers
|
||||||
if (param3 == param4)
|
pHolder.UpdateRepeatTimer(m_creature,event.friendly_buff.repeatMin,event.friendly_buff.repeatMax);
|
||||||
{
|
break;
|
||||||
pHolder.Time = param3;
|
|
||||||
|
|
||||||
}else if (param4 > param3)
|
|
||||||
pHolder.Time = urand(param3, param4);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
|
||||||
pHolder.Enabled = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case EVENT_T_SUMMONED_UNIT:
|
case EVENT_T_SUMMONED_UNIT:
|
||||||
{
|
{
|
||||||
//Prevent event from occuring on no unit or non creatures
|
//Prevent event from occuring on no unit or non creatures
|
||||||
|
|
@ -423,34 +272,31 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//Creature id doesn't match up
|
//Creature id doesn't match up
|
||||||
if (param1 && ((Creature*)pActionInvoker)->GetEntry() != param1)
|
if (((Creature*)pActionInvoker)->GetEntry() != event.summon_unit.creatureId)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//Repeat Timers
|
//Repeat Timers
|
||||||
if (param2 == param3)
|
pHolder.UpdateRepeatTimer(m_creature,event.summon_unit.repeatMin,event.summon_unit.repeatMax);
|
||||||
{
|
|
||||||
pHolder.Time = param2;
|
|
||||||
|
|
||||||
}else if (param3 > param2)
|
|
||||||
pHolder.Time = urand(param2, param3);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
|
||||||
pHolder.Enabled = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case EVENT_T_TARGET_MANA:
|
||||||
|
{
|
||||||
|
if (!m_creature->isInCombat() || !m_creature->getVictim() || !m_creature->getVictim()->GetMaxPower(POWER_MANA))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint32 perc = (m_creature->getVictim()->GetPower(POWER_MANA)*100) / m_creature->getVictim()->GetMaxPower(POWER_MANA);
|
||||||
|
|
||||||
|
if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//Repeat Timers
|
||||||
|
pHolder.UpdateRepeatTimer(m_creature,event.percent_range.repeatMin,event.percent_range.repeatMax);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case EVENT_T_REACHED_HOME:
|
case EVENT_T_REACHED_HOME:
|
||||||
{
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EVENT_T_RECEIVE_EMOTE:
|
case EVENT_T_RECEIVE_EMOTE:
|
||||||
{
|
break;
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u has invalid Event Type(%u), missing from ProcessEvent() Switch.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u has invalid Event Type(%u), missing from ProcessEvent() Switch.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -922,25 +768,16 @@ void CreatureEventAI::Reset()
|
||||||
//Reset all events to enabled
|
//Reset all events to enabled
|
||||||
for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
|
for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
|
||||||
{
|
{
|
||||||
switch ((*i).Event.event_type)
|
CreatureEventAI_Event const& event = (*i).Event;
|
||||||
|
switch (event.event_type)
|
||||||
{
|
{
|
||||||
//Reset all out of combat timers
|
//Reset all out of combat timers
|
||||||
case EVENT_T_TIMER_OOC:
|
case EVENT_T_TIMER_OOC:
|
||||||
{
|
{
|
||||||
if ((*i).Event.event_param2 == (*i).Event.event_param1)
|
if ((*i).UpdateRepeatTimer(m_creature,event.timer.initialMin,event.timer.initialMax))
|
||||||
{
|
|
||||||
(*i).Time = (*i).Event.event_param1;
|
|
||||||
(*i).Enabled = true;
|
(*i).Enabled = true;
|
||||||
}
|
break;
|
||||||
else if ((*i).Event.event_param2 > (*i).Event.event_param1)
|
|
||||||
{
|
|
||||||
(*i).Time = urand((*i).Event.event_param1, (*i).Event.event_param2);
|
|
||||||
(*i).Enabled = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has InitialMax < InitialMin. Event disabled.", m_creature->GetEntry(), (*i).Event.event_id, (*i).Event.event_type);
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
//default:
|
//default:
|
||||||
//TODO: enable below code line / verify this is correct to enable events previously disabled (ex. aggro yell), instead of enable this in void Aggro()
|
//TODO: enable below code line / verify this is correct to enable events previously disabled (ex. aggro yell), instead of enable this in void Aggro()
|
||||||
//(*i).Enabled = true;
|
//(*i).Enabled = true;
|
||||||
|
|
@ -1034,7 +871,8 @@ void CreatureEventAI::EnterCombat(Unit *enemy)
|
||||||
{
|
{
|
||||||
for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
|
for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
|
||||||
{
|
{
|
||||||
switch ((*i).Event.event_type)
|
CreatureEventAI_Event const& event = (*i).Event;
|
||||||
|
switch (event.event_type)
|
||||||
{
|
{
|
||||||
case EVENT_T_AGGRO:
|
case EVENT_T_AGGRO:
|
||||||
(*i).Enabled = true;
|
(*i).Enabled = true;
|
||||||
|
|
@ -1042,18 +880,8 @@ void CreatureEventAI::EnterCombat(Unit *enemy)
|
||||||
break;
|
break;
|
||||||
//Reset all in combat timers
|
//Reset all in combat timers
|
||||||
case EVENT_T_TIMER:
|
case EVENT_T_TIMER:
|
||||||
if ((*i).Event.event_param2 == (*i).Event.event_param1)
|
if ((*i).UpdateRepeatTimer(m_creature,event.timer.initialMin,event.timer.initialMax))
|
||||||
{
|
|
||||||
(*i).Time = (*i).Event.event_param1;
|
|
||||||
(*i).Enabled = true;
|
(*i).Enabled = true;
|
||||||
}
|
|
||||||
else if ((*i).Event.event_param2 > (*i).Event.event_param1)
|
|
||||||
{
|
|
||||||
(*i).Time = urand((*i).Event.event_param1, (*i).Event.event_param2);
|
|
||||||
(*i).Enabled = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has InitialMax < InitialMin. Event disabled.", m_creature->GetEntry(), (*i).Event.event_id, (*i).Event.event_type);
|
|
||||||
break;
|
break;
|
||||||
//All normal events need to be re-enabled and their time set to 0
|
//All normal events need to be re-enabled and their time set to 0
|
||||||
default:
|
default:
|
||||||
|
|
@ -1104,14 +932,14 @@ void CreatureEventAI::MoveInLineOfSight(Unit *who)
|
||||||
if ((*itr).Event.event_type == EVENT_T_OOC_LOS)
|
if ((*itr).Event.event_type == EVENT_T_OOC_LOS)
|
||||||
{
|
{
|
||||||
//can trigger if closer than fMaxAllowedRange
|
//can trigger if closer than fMaxAllowedRange
|
||||||
float fMaxAllowedRange = (*itr).Event.event_param2;
|
float fMaxAllowedRange = (*itr).Event.ooc_los.maxRange;
|
||||||
|
|
||||||
//if range is ok and we are actually in LOS
|
//if range is ok and we are actually in LOS
|
||||||
if (m_creature->IsWithinDistInMap(who, fMaxAllowedRange) && m_creature->IsWithinLOSInMap(who))
|
if (m_creature->IsWithinDistInMap(who, fMaxAllowedRange) && m_creature->IsWithinLOSInMap(who))
|
||||||
{
|
{
|
||||||
//if friendly event&&who is not hostile OR hostile event&&who is hostile
|
//if friendly event&&who is not hostile OR hostile event&&who is hostile
|
||||||
if (((*itr).Event.event_param1 && !m_creature->IsHostileTo(who)) ||
|
if (((*itr).Event.ooc_los.noHostile && !m_creature->IsHostileTo(who)) ||
|
||||||
((!(*itr).Event.event_param1) && m_creature->IsHostileTo(who)))
|
((!(*itr).Event.ooc_los.noHostile) && m_creature->IsHostileTo(who)))
|
||||||
ProcessEvent(*itr, who);
|
ProcessEvent(*itr, who);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1151,17 +979,11 @@ void CreatureEventAI::SpellHit(Unit* pUnit, const SpellEntry* pSpell)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
|
for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
|
||||||
{
|
|
||||||
if ((*i).Event.event_type == EVENT_T_SPELLHIT)
|
if ((*i).Event.event_type == EVENT_T_SPELLHIT)
|
||||||
{
|
|
||||||
//If spell id matches (or no spell id) & if spell school matches (or no spell school)
|
//If spell id matches (or no spell id) & if spell school matches (or no spell school)
|
||||||
if (!(*i).Event.event_param1 || pSpell->Id == (*i).Event.event_param1)
|
if (!(*i).Event.spell_hit.spellId || pSpell->Id == (*i).Event.spell_hit.spellId)
|
||||||
{
|
if (pSpell->SchoolMask & (*i).Event.spell_hit.schoolMask)
|
||||||
if ((*i).Event.event_param2_s == -1 || pSpell->SchoolMask == (*i).Event.event_param2)
|
|
||||||
ProcessEvent(*i, pUnit);
|
ProcessEvent(*i, pUnit);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreatureEventAI::UpdateAI(const uint32 diff)
|
void CreatureEventAI::UpdateAI(const uint32 diff)
|
||||||
|
|
@ -1216,8 +1038,7 @@ void CreatureEventAI::UpdateAI(const uint32 diff)
|
||||||
case EVENT_T_RANGE:
|
case EVENT_T_RANGE:
|
||||||
if (Combat)
|
if (Combat)
|
||||||
if (m_creature->IsInMap(m_creature->getVictim()))
|
if (m_creature->IsInMap(m_creature->getVictim()))
|
||||||
if (m_creature->IsInRange(m_creature->getVictim(),
|
if (m_creature->IsInRange(m_creature->getVictim(),(float)(*i).Event.range.minDist,(float)(*i).Event.range.maxDist))
|
||||||
(float)(*i).Event.event_param1,(float)(*i).Event.event_param2))
|
|
||||||
ProcessEvent(*i);
|
ProcessEvent(*i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1531,60 +1352,11 @@ void CreatureEventAI::ReceiveEmote(Player* pPlayer, uint32 text_emote)
|
||||||
{
|
{
|
||||||
if ((*itr).Event.event_type == EVENT_T_RECEIVE_EMOTE)
|
if ((*itr).Event.event_type == EVENT_T_RECEIVE_EMOTE)
|
||||||
{
|
{
|
||||||
if ((*itr).Event.event_param1 != text_emote)
|
if ((*itr).Event.receive_emote.emoteId != text_emote)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool bProcess = false;
|
PlayerCondition pcon((*itr).Event.receive_emote.condition,(*itr).Event.receive_emote.conditionValue1,(*itr).Event.receive_emote.conditionValue2);
|
||||||
|
if (pcon.Meets(pPlayer))
|
||||||
switch((*itr).Event.event_param2)
|
|
||||||
{
|
|
||||||
//enum ConditionType
|
|
||||||
case CONDITION_NONE: // 0 0
|
|
||||||
bProcess = true;
|
|
||||||
break;
|
|
||||||
case CONDITION_AURA: // spell_id effindex
|
|
||||||
if (pPlayer->HasAura((*itr).Event.event_param3,(*itr).Event.event_param4))
|
|
||||||
bProcess = true;
|
|
||||||
break;
|
|
||||||
case CONDITION_ITEM: // item_id count
|
|
||||||
if (pPlayer->HasItemCount((*itr).Event.event_param3,(*itr).Event.event_param4))
|
|
||||||
bProcess = true;
|
|
||||||
break;
|
|
||||||
case CONDITION_ITEM_EQUIPPED: // item_id count
|
|
||||||
if (pPlayer->HasItemOrGemWithIdEquipped((*itr).Event.event_param3,(*itr).Event.event_param4))
|
|
||||||
bProcess = true;
|
|
||||||
break;
|
|
||||||
case CONDITION_ZONEID: // zone_id 0
|
|
||||||
if (pPlayer->GetZoneId() == (*itr).Event.event_param3)
|
|
||||||
bProcess = true;
|
|
||||||
break;
|
|
||||||
case CONDITION_REPUTATION_RANK: // faction_id min_rank
|
|
||||||
if (pPlayer->GetReputationRank((*itr).Event.event_param3) >= (*itr).Event.event_param4)
|
|
||||||
bProcess = true;
|
|
||||||
break;
|
|
||||||
case CONDITION_TEAM: // player_team 0, (469 - Alliance 67 - Horde)
|
|
||||||
if (pPlayer->GetTeam() == (*itr).Event.event_param3)
|
|
||||||
bProcess = true;
|
|
||||||
break;
|
|
||||||
case CONDITION_SKILL: // skill_id min skill_value
|
|
||||||
if (pPlayer->HasSkill((*itr).Event.event_param3) && pPlayer->GetSkillValue((*itr).Event.event_param3) >= (*itr).Event.event_param4)
|
|
||||||
bProcess = true;
|
|
||||||
break;
|
|
||||||
case CONDITION_QUESTREWARDED: // quest_id 0
|
|
||||||
if (pPlayer->GetQuestRewardStatus((*itr).Event.event_param3))
|
|
||||||
bProcess = true;
|
|
||||||
break;
|
|
||||||
case CONDITION_QUESTTAKEN: // quest_id 0, for condition true while quest active.
|
|
||||||
if (pPlayer->GetQuestStatus((*itr).Event.event_param3) == QUEST_STATUS_INCOMPLETE)
|
|
||||||
bProcess = true;
|
|
||||||
break;
|
|
||||||
case CONDITION_ACTIVE_EVENT: // event_id 0
|
|
||||||
if (IsHolidayActive(HolidayIds((*itr).Event.event_param3)))
|
|
||||||
bProcess = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bProcess)
|
|
||||||
{
|
{
|
||||||
sLog.outDebug("CreatureEventAI: ReceiveEmote CreatureEventAI: Condition ok, processing");
|
sLog.outDebug("CreatureEventAI: ReceiveEmote CreatureEventAI: Condition ok, processing");
|
||||||
ProcessEvent(*itr, pPlayer);
|
ProcessEvent(*itr, pPlayer);
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ enum EventAI_Type
|
||||||
EVENT_T_EVADE = 7, // NONE
|
EVENT_T_EVADE = 7, // NONE
|
||||||
EVENT_T_SPELLHIT = 8, // SpellID, School, RepeatMin, RepeatMax
|
EVENT_T_SPELLHIT = 8, // SpellID, School, RepeatMin, RepeatMax
|
||||||
EVENT_T_RANGE = 9, // MinDist, MaxDist, RepeatMin, RepeatMax
|
EVENT_T_RANGE = 9, // MinDist, MaxDist, RepeatMin, RepeatMax
|
||||||
EVENT_T_OOC_LOS = 10, // NoHostile, NoFriendly, RepeatMin, RepeatMax
|
EVENT_T_OOC_LOS = 10, // NoHostile, MaxRnage, RepeatMin, RepeatMax
|
||||||
EVENT_T_SPAWNED = 11, // NONE
|
EVENT_T_SPAWNED = 11, // NONE
|
||||||
EVENT_T_TARGET_HP = 12, // HPMax%, HPMin%, RepeatMin, RepeatMax
|
EVENT_T_TARGET_HP = 12, // HPMax%, HPMin%, RepeatMin, RepeatMax
|
||||||
EVENT_T_TARGET_CASTING = 13, // RepeatMin, RepeatMax
|
EVENT_T_TARGET_CASTING = 13, // RepeatMin, RepeatMax
|
||||||
|
|
@ -376,23 +376,116 @@ struct CreatureEventAI_Event
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
uint32 event_param1;
|
// EVENT_T_TIMER = 0
|
||||||
int32 event_param1_s;
|
// EVENT_T_TIMER_OOC = 1
|
||||||
};
|
struct
|
||||||
union
|
{
|
||||||
{
|
uint32 initialMin;
|
||||||
uint32 event_param2;
|
uint32 initialMax;
|
||||||
int32 event_param2_s;
|
uint32 repeatMin;
|
||||||
};
|
uint32 repeatMax;
|
||||||
union
|
} timer;
|
||||||
{
|
// EVENT_T_HP = 2
|
||||||
uint32 event_param3;
|
// EVENT_T_MANA = 3
|
||||||
int32 event_param3_s;
|
// EVENT_T_TARGET_HP = 12
|
||||||
};
|
// EVENT_T_TARGET_MANA = 18
|
||||||
union
|
struct
|
||||||
{
|
{
|
||||||
uint32 event_param4;
|
uint32 percentMax;
|
||||||
int32 event_param4_s;
|
uint32 percentMin;
|
||||||
|
uint32 repeatMin;
|
||||||
|
uint32 repeatMax;
|
||||||
|
} percent_range;
|
||||||
|
// EVENT_T_KILL = 5
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 repeatMin;
|
||||||
|
uint32 repeatMax;
|
||||||
|
} kill;
|
||||||
|
// EVENT_T_SPELLHIT = 8
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 spellId;
|
||||||
|
uint32 schoolMask; // -1 (==0xffffffff) is ok value for full mask, or must be more limited mask like (0 < 1) = 1 for normal/physical school
|
||||||
|
uint32 repeatMin;
|
||||||
|
uint32 repeatMax;
|
||||||
|
} spell_hit;
|
||||||
|
// EVENT_T_RANGE = 9
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 minDist;
|
||||||
|
uint32 maxDist;
|
||||||
|
uint32 repeatMin;
|
||||||
|
uint32 repeatMax;
|
||||||
|
} range;
|
||||||
|
// EVENT_T_OOC_LOS = 10
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 noHostile;
|
||||||
|
uint32 maxRange;
|
||||||
|
uint32 repeatMin;
|
||||||
|
uint32 repeatMax;
|
||||||
|
} ooc_los;
|
||||||
|
// EVENT_T_TARGET_CASTING = 13
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 repeatMin;
|
||||||
|
uint32 repeatMax;
|
||||||
|
} target_casting;
|
||||||
|
// EVENT_T_FRIENDLY_HP = 14
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 hpDeficit;
|
||||||
|
uint32 radius;
|
||||||
|
uint32 repeatMin;
|
||||||
|
uint32 repeatMax;
|
||||||
|
} friendly_hp;
|
||||||
|
// EVENT_T_FRIENDLY_IS_CC = 15
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 dispelType; // unused ?
|
||||||
|
uint32 radius;
|
||||||
|
uint32 repeatMin;
|
||||||
|
uint32 repeatMax;
|
||||||
|
} friendly_is_cc;
|
||||||
|
// EVENT_T_FRIENDLY_MISSING_BUFF = 16
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 spellId;
|
||||||
|
uint32 radius;
|
||||||
|
uint32 repeatMin;
|
||||||
|
uint32 repeatMax;
|
||||||
|
} friendly_buff;
|
||||||
|
// EVENT_T_SUMMONED_UNIT = 17
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 creatureId;
|
||||||
|
uint32 repeatMin;
|
||||||
|
uint32 repeatMax;
|
||||||
|
} summon_unit;
|
||||||
|
// EVENT_T_QUEST_ACCEPT = 19
|
||||||
|
// EVENT_T_QUEST_COMPLETE = 20
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 questId;
|
||||||
|
} quest;
|
||||||
|
// EVENT_T_RECEIVE_EMOTE = 22
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 emoteId;
|
||||||
|
uint32 condition;
|
||||||
|
uint32 conditionValue1;
|
||||||
|
uint32 conditionValue2;
|
||||||
|
} receive_emote;
|
||||||
|
|
||||||
|
// RAW
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 param1;
|
||||||
|
uint32 param2;
|
||||||
|
uint32 param3;
|
||||||
|
uint32 param4;
|
||||||
|
} raw;
|
||||||
};
|
};
|
||||||
|
|
||||||
CreatureEventAI_Action action[MAX_ACTIONS];
|
CreatureEventAI_Action action[MAX_ACTIONS];
|
||||||
|
|
@ -421,6 +514,9 @@ struct CreatureEventAIHolder
|
||||||
CreatureEventAI_Event Event;
|
CreatureEventAI_Event Event;
|
||||||
uint32 Time;
|
uint32 Time;
|
||||||
bool Enabled;
|
bool Enabled;
|
||||||
|
|
||||||
|
// helper
|
||||||
|
bool UpdateRepeatTimer(Creature* creature, uint32 repeatMin, uint32 repeatMax);
|
||||||
};
|
};
|
||||||
|
|
||||||
class MANGOS_DLL_SPEC CreatureEventAI : public CreatureAI
|
class MANGOS_DLL_SPEC CreatureEventAI : public CreatureAI
|
||||||
|
|
|
||||||
|
|
@ -205,10 +205,10 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
|
||||||
temp.event_inverse_phase_mask = fields[3].GetUInt32();
|
temp.event_inverse_phase_mask = fields[3].GetUInt32();
|
||||||
temp.event_chance = fields[4].GetUInt8();
|
temp.event_chance = fields[4].GetUInt8();
|
||||||
temp.event_flags = fields[5].GetUInt8();
|
temp.event_flags = fields[5].GetUInt8();
|
||||||
temp.event_param1 = fields[6].GetUInt32();
|
temp.raw.param1 = fields[6].GetUInt32();
|
||||||
temp.event_param2 = fields[7].GetUInt32();
|
temp.raw.param2 = fields[7].GetUInt32();
|
||||||
temp.event_param3 = fields[8].GetUInt32();
|
temp.raw.param3 = fields[8].GetUInt32();
|
||||||
temp.event_param4 = fields[9].GetUInt32();
|
temp.raw.param4 = fields[9].GetUInt32();
|
||||||
|
|
||||||
//Creature does not exist in database
|
//Creature does not exist in database
|
||||||
if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.creature_id))
|
if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.creature_id))
|
||||||
|
|
@ -232,87 +232,97 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
|
||||||
{
|
{
|
||||||
case EVENT_T_TIMER:
|
case EVENT_T_TIMER:
|
||||||
case EVENT_T_TIMER_OOC:
|
case EVENT_T_TIMER_OOC:
|
||||||
{
|
if (temp.timer.initialMax < temp.timer.initialMin)
|
||||||
if (temp.event_param2 < temp.event_param1)
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using timed event(%u) with param2 < param1 (InitialMax < InitialMin). Event will never repeat.", temp.creature_id, i);
|
sLog.outErrorDb("CreatureEventAI: Creature %u are using timed event(%u) with param2 < param1 (InitialMax < InitialMin). Event will never repeat.", temp.creature_id, i);
|
||||||
|
if (temp.timer.repeatMax < temp.timer.repeatMin)
|
||||||
if (temp.event_param4 < temp.event_param3)
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case EVENT_T_HP:
|
case EVENT_T_HP:
|
||||||
case EVENT_T_MANA:
|
case EVENT_T_MANA:
|
||||||
case EVENT_T_TARGET_HP:
|
case EVENT_T_TARGET_HP:
|
||||||
{
|
case EVENT_T_TARGET_MANA:
|
||||||
if (temp.event_param2 > 100)
|
if (temp.percent_range.percentMax > 100)
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using percentage event(%u) with param2 (MinPercent) > 100. Event will never trigger! ", temp.creature_id, i);
|
sLog.outErrorDb("CreatureEventAI: Creature %u are using percentage event(%u) with param2 (MinPercent) > 100. Event will never trigger! ", temp.creature_id, i);
|
||||||
|
|
||||||
if (temp.event_param1 <= temp.event_param2)
|
if (temp.percent_range.percentMax <= temp.percent_range.percentMin)
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using percentage event(%u) with param1 <= param2 (MaxPercent <= MinPercent). Event will never trigger! ", temp.creature_id, i);
|
sLog.outErrorDb("CreatureEventAI: Creature %u are using percentage event(%u) with param1 <= param2 (MaxPercent <= MinPercent). Event will never trigger! ", temp.creature_id, i);
|
||||||
|
|
||||||
if (temp.event_flags & EFLAG_REPEATABLE && !temp.event_param3 && !temp.event_param4)
|
if (temp.event_flags & EFLAG_REPEATABLE && !temp.percent_range.repeatMin && !temp.percent_range.repeatMax)
|
||||||
{
|
{
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u has param3 and param4=0 (RepeatMin/RepeatMax) but cannot be repeatable without timers. Removing EFLAG_REPEATABLE for event %u.", temp.creature_id, i);
|
sLog.outErrorDb("CreatureEventAI: Creature %u has param3 and param4=0 (RepeatMin/RepeatMax) but cannot be repeatable without timers. Removing EFLAG_REPEATABLE for event %u.", temp.creature_id, i);
|
||||||
temp.event_flags &= ~EFLAG_REPEATABLE;
|
temp.event_flags &= ~EFLAG_REPEATABLE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case EVENT_T_SPELLHIT:
|
case EVENT_T_SPELLHIT:
|
||||||
{
|
if (temp.spell_hit.spellId)
|
||||||
if (temp.event_param1)
|
|
||||||
{
|
{
|
||||||
SpellEntry const* pSpell = sSpellStore.LookupEntry(temp.event_param1);
|
SpellEntry const* pSpell = sSpellStore.LookupEntry(temp.spell_hit.spellId);
|
||||||
if (!pSpell)
|
if (!pSpell)
|
||||||
{
|
{
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u has non-existant SpellID(%u) defined in event %u.", temp.creature_id, temp.event_param1, i);
|
sLog.outErrorDb("CreatureEventAI: Creature %u has non-existant SpellID(%u) defined in event %u.", temp.creature_id, temp.spell_hit.spellId, i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (temp.event_param2_s != -1 && temp.event_param2 != pSpell->SchoolMask)
|
if ((temp.spell_hit.schoolMask & pSpell->SchoolMask) != pSpell->SchoolMask)
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u has param1(spellId %u) but param2 is not -1 and not equal to spell's school mask. Event %u can never trigger.", temp.creature_id, temp.event_param1, i);
|
sLog.outErrorDb("CreatureEventAI: Creature %u has param1(spellId %u) but param2 is not -1 and not equal to spell's school mask. Event %u can never trigger.", temp.creature_id, temp.spell_hit.schoolMask, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: fix this system with SPELL_SCHOOL_MASK. Current complicate things, using int32(-1) instead of just 0
|
if (!temp.spell_hit.schoolMask)
|
||||||
//SPELL_SCHOOL_MASK_NONE = 0 and does not exist, thus it can not ever trigger or be used in SpellHit()
|
sLog.outErrorDb("CreatureEventAI: Creature %u is using invalid SpellSchoolMask(%u) defined in event %u.", temp.creature_id, temp.spell_hit.schoolMask, i);
|
||||||
if (temp.event_param2_s != -1 && temp.event_param2_s > SPELL_SCHOOL_MASK_ALL)
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u is using invalid SpellSchoolMask(%u) defined in event %u.", temp.creature_id, temp.event_param2, i);
|
|
||||||
|
|
||||||
if (temp.event_param4 < temp.event_param3)
|
if (temp.spell_hit.repeatMax < temp.spell_hit.repeatMin)
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case EVENT_T_RANGE:
|
case EVENT_T_RANGE:
|
||||||
|
if (temp.range.maxDist < temp.range.minDist)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with param2 < param1 (MaxDist < MinDist). Event will never repeat.", temp.creature_id, i);
|
||||||
|
if (temp.range.repeatMax < temp.range.repeatMin)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
||||||
|
break;
|
||||||
case EVENT_T_OOC_LOS:
|
case EVENT_T_OOC_LOS:
|
||||||
|
if (temp.ooc_los.repeatMax < temp.ooc_los.repeatMin)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
||||||
|
break;
|
||||||
case EVENT_T_FRIENDLY_HP:
|
case EVENT_T_FRIENDLY_HP:
|
||||||
|
if (temp.friendly_hp.repeatMax < temp.friendly_hp.repeatMin)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
||||||
|
break;
|
||||||
case EVENT_T_FRIENDLY_IS_CC:
|
case EVENT_T_FRIENDLY_IS_CC:
|
||||||
|
if (temp.friendly_is_cc.repeatMax < temp.friendly_is_cc.repeatMin)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
||||||
|
break;
|
||||||
case EVENT_T_FRIENDLY_MISSING_BUFF:
|
case EVENT_T_FRIENDLY_MISSING_BUFF:
|
||||||
{
|
{
|
||||||
//Disabled check for now. Check code related to events and adjust accordingly before enable.
|
SpellEntry const* pSpell = sSpellStore.LookupEntry(temp.spell_hit.spellId);
|
||||||
//Events should have min/max or alternative set to a static value.
|
if (!pSpell)
|
||||||
/*if (!temp.event_param3 && !temp.event_param4)
|
|
||||||
{
|
{
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) without param3/param4 (RepeatMin/RepeatMax). Using minimum values.", temp.creature_id, i);
|
sLog.outErrorDb("CreatureEventAI: Creature %u has non-existant SpellID(%u) defined in event %u.", temp.creature_id, temp.spell_hit.spellId, i);
|
||||||
temp.event_param3 = 2500;
|
continue;
|
||||||
temp.event_param4 = 2500;
|
}
|
||||||
}*/
|
if (temp.friendly_buff.repeatMax < temp.friendly_buff.repeatMin)
|
||||||
|
|
||||||
if (temp.event_param4 < temp.event_param3)
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case EVENT_T_KILL:
|
case EVENT_T_KILL:
|
||||||
case EVENT_T_TARGET_CASTING:
|
if (temp.kill.repeatMax < temp.kill.repeatMin)
|
||||||
{
|
|
||||||
if (temp.event_param2 < temp.event_param1)
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with param2 < param1 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with param2 < param1 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
case EVENT_T_TARGET_CASTING:
|
||||||
|
if (temp.target_casting.repeatMax < temp.target_casting.repeatMin)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with param2 < param1 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
||||||
|
break;
|
||||||
|
case EVENT_T_SUMMONED_UNIT:
|
||||||
|
if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.summon_unit.creatureId))
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with not existed creature template id (%u) in param1, skipped.", temp.creature_id, i, temp.summon_unit.creatureId);
|
||||||
|
if (temp.summon_unit.repeatMax < temp.summon_unit.repeatMin)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with param2 < param1 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
||||||
|
break;
|
||||||
|
case EVENT_T_QUEST_ACCEPT:
|
||||||
|
case EVENT_T_QUEST_COMPLETE:
|
||||||
|
if (!objmgr.GetQuestTemplate(temp.quest.questId))
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with not existed qyest id (%u) in param1, skipped.", temp.creature_id, i, temp.quest.questId);
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Creature %u using not implemented event (%u) in event %u.", temp.creature_id, temp.event_id, i);
|
||||||
|
continue;
|
||||||
|
|
||||||
case EVENT_T_AGGRO:
|
case EVENT_T_AGGRO:
|
||||||
case EVENT_T_DEATH:
|
case EVENT_T_DEATH:
|
||||||
|
|
@ -331,21 +341,15 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
|
||||||
|
|
||||||
case EVENT_T_RECEIVE_EMOTE:
|
case EVENT_T_RECEIVE_EMOTE:
|
||||||
{
|
{
|
||||||
if (!sEmotesTextStore.LookupEntry(temp.event_param1))
|
if (!sEmotesTextStore.LookupEntry(temp.receive_emote.emoteId))
|
||||||
{
|
{
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param1 (EmoteTextId: %u) are not valid.",temp.creature_id, i, temp.event_param1);
|
sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param1 (EmoteTextId: %u) are not valid.",temp.creature_id, i, temp.receive_emote.emoteId);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (temp.event_param2 == CONDITION_AD_COMMISSION_AURA || temp.event_param2 == CONDITION_NO_AURA)
|
if (!PlayerCondition::IsValid(ConditionType(temp.receive_emote.condition), temp.receive_emote.conditionValue1, temp.receive_emote.conditionValue2))
|
||||||
{
|
{
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param2 (Condition: %u) are not implemented for EventAI.",temp.creature_id, i, temp.event_param2);
|
sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param2 (Condition: %u) are not valid.",temp.creature_id, i, temp.receive_emote.condition);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!PlayerCondition::IsValid(ConditionType(temp.event_param2), temp.event_param3, temp.event_param4))
|
|
||||||
{
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param2 (Condition: %u) are not valid.",temp.creature_id, i, temp.event_param2);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -358,21 +362,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case EVENT_T_SUMMONED_UNIT:
|
|
||||||
{
|
|
||||||
if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.event_param1))
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with not existed creature template id (%u) in param1, skipped.", temp.creature_id, i, temp.event_param1);
|
|
||||||
|
|
||||||
if (temp.event_param3 < temp.event_param2)
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param3 < param2 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case EVENT_T_QUEST_ACCEPT:
|
|
||||||
case EVENT_T_QUEST_COMPLETE:
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using not implemented event (%u) in event %u.", temp.creature_id, temp.event_id, i);
|
|
||||||
continue;
|
|
||||||
default:
|
default:
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using not checked at load event (%u) in event %u. Need check code update?", temp.creature_id, temp.event_id, i);
|
sLog.outErrorDb("CreatureEventAI: Creature %u using not checked at load event (%u) in event %u. Need check code update?", temp.creature_id, temp.event_id, i);
|
||||||
break;
|
break;
|
||||||
|
|
@ -486,6 +475,7 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
|
||||||
const SpellEntry *spell = sSpellStore.LookupEntry(action.cast.spellId);
|
const SpellEntry *spell = sSpellStore.LookupEntry(action.cast.spellId);
|
||||||
if (!spell)
|
if (!spell)
|
||||||
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent SpellID %u.", i, j+1, action.cast.spellId);
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent SpellID %u.", i, j+1, action.cast.spellId);
|
||||||
|
/* FIXME: temp.raw.param3 not have event tipes with recovery time in it....
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (spell->RecoveryTime > 0 && temp.event_flags & EFLAG_REPEATABLE)
|
if (spell->RecoveryTime > 0 && temp.event_flags & EFLAG_REPEATABLE)
|
||||||
|
|
@ -495,6 +485,7 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
|
||||||
sLog.outDebug("CreatureEventAI: Event %u Action %u uses SpellID %u but cooldown is longer(%u) than minumum defined in event param3(%u).", i, j+1,action.cast.spellId, spell->RecoveryTime, temp.event_param3);
|
sLog.outDebug("CreatureEventAI: Event %u Action %u uses SpellID %u but cooldown is longer(%u) than minumum defined in event param3(%u).", i, j+1,action.cast.spellId, spell->RecoveryTime, temp.event_param3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
//Cast is always triggered if target is forced to cast on self
|
//Cast is always triggered if target is forced to cast on self
|
||||||
if (action.cast.castFlags & CAST_FORCE_TARGET_SELF)
|
if (action.cast.castFlags & CAST_FORCE_TARGET_SELF)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "7851"
|
#define REVISION_NR "7852"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue