[9241] Implement AI/EventAI calls at summoned creature die/despawn

* New CreatureAI::SummonedCreatureJustDie called for owner at temporary summoned creature die.
* New EVENT_T_SUMMONED_JUST_DIE (25) for proccess CreatureAI::SummonedCreatureJustDie event
* New EVENT_T_SUMMONED_JUST_DESPAWN (26) for proccess CreatureAI::SummonedCreatureJustDespawn event
* Some code cleanups.
This commit is contained in:
VladimirMangos 2010-01-23 14:37:07 +03:00
parent 75381e31f8
commit 36d90d6040
9 changed files with 110 additions and 42 deletions

View file

@ -85,6 +85,8 @@ Some events such as EVENT_T_AGGRO, EVENT_T_DEATH, EVENT_T_SPAWNED, and EVENT_T_E
22 EVENT_T_RECEIVE_EMOTE EmoteId, Condition, CondValue1, CondValue2 Expires when a creature receives an emote with emote text id (enum TextEmotes) in (Param1). Conditions can be defined (Param2) with optional values (Param3,Param4), see enum ConditionType. 22 EVENT_T_RECEIVE_EMOTE EmoteId, Condition, CondValue1, CondValue2 Expires when a creature receives an emote with emote text id (enum TextEmotes) in (Param1). Conditions can be defined (Param2) with optional values (Param3,Param4), see enum ConditionType.
23 EVENT_T_BUFFED SpellID, AmmountInStack, RepeatMin, RepeatMax Expires when a creature has spell (Param1) auras applied in a stack greater or equal to value provided in (Param2). Will repeat every (Param3) and (Param4). 23 EVENT_T_BUFFED SpellID, AmmountInStack, RepeatMin, RepeatMax Expires when a creature has spell (Param1) auras applied in a stack greater or equal to value provided in (Param2). Will repeat every (Param3) and (Param4).
24 EVENT_T_TARGET_BUFFED SpellID, AmmountInStack, RepeatMin, RepeatMax Expires when a target unit has spell (Param1) auras applied in a stack greater or equal to value provided in (Param2). Will repeat every (Param3) and (Param4). 24 EVENT_T_TARGET_BUFFED SpellID, AmmountInStack, RepeatMin, RepeatMax Expires when a target unit has spell (Param1) auras applied in a stack greater or equal to value provided in (Param2). Will repeat every (Param3) and (Param4).
25 EVENT_T_SUMMONED_JUST_DIE CreatureId, RepeatMin, RepeatMax Expires after creature with entry = (Param1) is die (Param1 = 0 means all spawns). Will repeat every (Param2) and (Param3).
26 EVENT_T_SUMMONED_JUST_DESPAWN CreatureId, RepeatMin, RepeatMax Expires before creature with entry = (Param1) is despawn (Param1 = 0 means all spawns). Will repeat every (Param2) and (Param3).
========================================= =========================================
@ -381,6 +383,27 @@ CONDITION_QUESTREWARDED (8) quest_id 0, if quest are rewarded
CONDITION_QUESTTAKEN (9) quest_id 0, while quest active(incomplete) CONDITION_QUESTTAKEN (9) quest_id 0, while quest active(incomplete)
CONDITION_ACTIVE_EVENT (12) event_id 0, note this is id from dbc, also defined in Mangos source(enum HolidayIds) NOT id of game_event in database CONDITION_ACTIVE_EVENT (12) event_id 0, note this is id from dbc, also defined in Mangos source(enum HolidayIds) NOT id of game_event in database
---------------------------
25 = EVENT_T_SUMMONED_JUST_DIE:
---------------------------
Parameter 1: CreatureId - The CreatureID that the NPC is watching die to trigger this event
Parameter 2: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 3: RepeatMax - Maximum Time used to calculate Random Repeat Expire
BOTH - Expires after creature with entry(Param1) is die or for all spawns if param1 = 0. Will repeat every (Param2) and (Param3) .
This is commonly used for NPC's who will do something special once another NPC is die. Usually used is Complex Scripts or Special Events.
---------------------------
26 = EVENT_T_SUMMONED_JUST_DESPAWN:
---------------------------
Parameter 1: CreatureId - The CreatureID that the NPC is watching despawn to trigger this event
Parameter 2: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 3: RepeatMax - Maximum Time used to calculate Random Repeat Expire
BOTH - Expires before creature with entry(Param1) is dwspawned or for all spawns if param1 = 0. Will repeat every (Param2) and (Param3) .
This is commonly used for NPC's who will do something special once another NPC is despawn. Usually used is Complex Scripts or Special Events.
NOTE: called before despawn happens, so summoned creature still in world at expire moment.
========================================= =========================================
Action Types Action Types
========================================= =========================================

View file

@ -95,12 +95,16 @@ class MANGOS_DLL_SPEC CreatureAI
// Called when the creature is killed // Called when the creature is killed
virtual void JustDied(Unit *) {} virtual void JustDied(Unit *) {}
// Called when the creature summon is killed
virtual void SummonedCreatureJustDie(Creature* /*unit*/) {}
// Called when the creature kills a unit // Called when the creature kills a unit
virtual void KilledUnit(Unit *) {} virtual void KilledUnit(Unit *) {}
// Called when the creature summon successfully other creature // Called when the creature summon successfully other creature
virtual void JustSummoned(Creature* ) {} virtual void JustSummoned(Creature* ) {}
// Called when the creature summon despawn
virtual void SummonedCreatureDespawn(Creature* /*unit*/) {} virtual void SummonedCreatureDespawn(Creature* /*unit*/) {}
// Called when hit by a spell // Called when hit by a spell

View file

@ -257,17 +257,19 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
break; break;
} }
case EVENT_T_SUMMONED_UNIT: case EVENT_T_SUMMONED_UNIT:
case EVENT_T_SUMMONED_JUST_DIE:
case EVENT_T_SUMMONED_JUST_DESPAWN:
{ {
//Prevent event from occuring on no unit or non creatures //Prevent event from occuring on no unit or non creatures
if (!pActionInvoker || pActionInvoker->GetTypeId()!=TYPEID_UNIT) if (!pActionInvoker || pActionInvoker->GetTypeId()!=TYPEID_UNIT)
return false; return false;
//Creature id doesn't match up //Creature id doesn't match up
if (((Creature*)pActionInvoker)->GetEntry() != event.summon_unit.creatureId) if (((Creature*)pActionInvoker)->GetEntry() != event.summoned.creatureId)
return false; return false;
//Repeat Timers //Repeat Timers
pHolder.UpdateRepeatTimer(m_creature,event.summon_unit.repeatMin,event.summon_unit.repeatMax); pHolder.UpdateRepeatTimer(m_creature,event.summoned.repeatMin,event.summoned.repeatMax);
break; break;
} }
case EVENT_T_TARGET_MANA: case EVENT_T_TARGET_MANA:
@ -911,6 +913,30 @@ void CreatureEventAI::JustSummoned(Creature* pUnit)
} }
} }
void CreatureEventAI::SummonedCreatureJustDie(Creature* pUnit)
{
if (bEmptyList || !pUnit)
return;
for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
{
if ((*i).Event.event_type == EVENT_T_SUMMONED_JUST_DIE)
ProcessEvent(*i, pUnit);
}
}
void CreatureEventAI::SummonedCreatureDespawn(Creature* pUnit)
{
if (bEmptyList || !pUnit)
return;
for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
{
if ((*i).Event.event_type == EVENT_T_SUMMONED_JUST_DESPAWN)
ProcessEvent(*i, pUnit);
}
}
void CreatureEventAI::EnterCombat(Unit *enemy) void CreatureEventAI::EnterCombat(Unit *enemy)
{ {
//Check for on combat start events //Check for on combat start events

View file

@ -58,6 +58,8 @@ enum EventAI_Type
EVENT_T_RECEIVE_EMOTE = 22, // EmoteId, Condition, CondValue1, CondValue2 EVENT_T_RECEIVE_EMOTE = 22, // EmoteId, Condition, CondValue1, CondValue2
EVENT_T_BUFFED = 23, // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 Repeat Min/Max EVENT_T_BUFFED = 23, // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 Repeat Min/Max
EVENT_T_TARGET_BUFFED = 24, // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 Repeat Min/Max EVENT_T_TARGET_BUFFED = 24, // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 Repeat Min/Max
EVENT_T_SUMMONED_JUST_DIE = 25, // CreatureId, RepeatMin, RepeatMax
EVENT_T_SUMMONED_JUST_DESPAWN = 26, // CreatureId, RepeatMin, RepeatMax
EVENT_T_END, EVENT_T_END,
}; };
@ -486,12 +488,14 @@ struct CreatureEventAI_Event
uint32 repeatMax; uint32 repeatMax;
} friendly_buff; } friendly_buff;
// EVENT_T_SUMMONED_UNIT = 17 // EVENT_T_SUMMONED_UNIT = 17
//EVENT_T_SUMMONED_JUST_DIE = 25
//EVENT_T_SUMMONED_JUST_DESPAWN = 26
struct struct
{ {
uint32 creatureId; uint32 creatureId;
uint32 repeatMin; uint32 repeatMin;
uint32 repeatMax; uint32 repeatMax;
} summon_unit; } summoned;
// EVENT_T_QUEST_ACCEPT = 19 // EVENT_T_QUEST_ACCEPT = 19
// EVENT_T_QUEST_COMPLETE = 20 // EVENT_T_QUEST_COMPLETE = 20
struct struct
@ -582,6 +586,9 @@ class MANGOS_DLL_SPEC CreatureEventAI : public CreatureAI
void UpdateAI(const uint32 diff); void UpdateAI(const uint32 diff);
bool IsVisible(Unit *) const; bool IsVisible(Unit *) const;
void ReceiveEmote(Player* pPlayer, uint32 text_emote); void ReceiveEmote(Player* pPlayer, uint32 text_emote);
void SummonedCreatureJustDie(Creature* unit);
void SummonedCreatureDespawn(Creature* unit);
static int Permissible(const Creature *); static int Permissible(const Creature *);
bool ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pActionInvoker = NULL); bool ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pActionInvoker = NULL);

View file

@ -404,9 +404,11 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
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_SUMMONED_UNIT: case EVENT_T_SUMMONED_UNIT:
if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.summon_unit.creatureId)) case EVENT_T_SUMMONED_JUST_DIE:
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); case EVENT_T_SUMMONED_JUST_DESPAWN:
if (temp.summon_unit.repeatMax < temp.summon_unit.repeatMin) if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.summoned.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.summoned.creatureId);
if (temp.summoned.repeatMax < temp.summoned.repeatMin)
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_QUEST_ACCEPT: case EVENT_T_QUEST_ACCEPT:

View file

@ -98,13 +98,9 @@ void PointMovementGenerator<Creature>::MovementInform(Creature &unit)
{ {
TemporarySummon* pSummon = (TemporarySummon*)(&unit); TemporarySummon* pSummon = (TemporarySummon*)(&unit);
if (IS_CREATURE_GUID(pSummon->GetSummonerGUID())) if (IS_CREATURE_GUID(pSummon->GetSummonerGUID()))
{ if(Creature* pSummoner = unit.GetMap()->GetCreature(pSummon->GetSummonerGUID()))
if (Unit* pSummoner = pSummon->GetSummoner()) if (pSummoner->AI())
{ pSummoner->AI()->SummonedMovementInform(&unit, POINT_MOTION_TYPE, id);
if (((Creature*)pSummoner)->AI())
((Creature*)pSummoner)->AI()->SummonedMovementInform(&unit, POINT_MOTION_TYPE, id);
}
}
} }
} }

View file

@ -165,11 +165,10 @@ void TemporarySummon::UnSummon()
{ {
CombatStop(); CombatStop();
Unit* sum = m_summoner ? ObjectAccessor::GetUnit(*this, m_summoner) : NULL; if (IS_CREATURE_GUID(GetSummonerGUID()))
if (sum && sum->GetTypeId() == TYPEID_UNIT && ((Creature*)sum)->AI()) if(Creature* sum = GetMap()->GetCreature(GetSummonerGUID()))
{ if (sum->AI())
((Creature*)sum)->AI()->SummonedCreatureDespawn(this); sum->AI()->SummonedCreatureDespawn(this);
}
AddObjectToRemoveList(); AddObjectToRemoveList();
} }

View file

@ -35,6 +35,7 @@
#include "MapManager.h" #include "MapManager.h"
#include "ObjectAccessor.h" #include "ObjectAccessor.h"
#include "CreatureAI.h" #include "CreatureAI.h"
#include "TemporarySummon.h"
#include "Formulas.h" #include "Formulas.h"
#include "Pet.h" #include "Pet.h"
#include "Util.h" #include "Util.h"
@ -684,6 +685,16 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
if (cVictim->AI()) if (cVictim->AI())
cVictim->AI()->JustDied(this); cVictim->AI()->JustDied(this);
if (cVictim->isTemporarySummon())
{
TemporarySummon* pSummon = (TemporarySummon*)cVictim;
if (IS_CREATURE_GUID(pSummon->GetSummonerGUID()))
if(Creature* pSummoner = cVictim->GetMap()->GetCreature(pSummon->GetSummonerGUID()))
if (pSummoner->AI())
pSummoner->AI()->SummonedCreatureJustDie(cVictim);
}
// Dungeon specific stuff, only applies to players killing creatures // Dungeon specific stuff, only applies to players killing creatures
if(cVictim->GetInstanceId()) if(cVictim->GetInstanceId())
{ {

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "9240" #define REVISION_NR "9241"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__