mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 22:37:03 +00:00
Merge branch 'master' into 310
Conflicts: src/game/Unit.cpp
This commit is contained in:
commit
14e9afa46f
43 changed files with 4445 additions and 271 deletions
794
doc/EventAI.txt
Normal file
794
doc/EventAI.txt
Normal file
|
|
@ -0,0 +1,794 @@
|
||||||
|
=========================================
|
||||||
|
EventAI documentation
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
EventAI allows users to create new creature scripts entierly within the database.
|
||||||
|
|
||||||
|
For the AI to be used, you must first make sure to set AIname for each creature that should use this AI.
|
||||||
|
|
||||||
|
UPDATE creature_template SET AIName = 'EventAI' WHERE entry IN (...);
|
||||||
|
|
||||||
|
=========================================
|
||||||
|
Basic Structure of EventAI
|
||||||
|
=========================================
|
||||||
|
EventAI follows a basic if (Event) then do (Action) format.
|
||||||
|
Below is a the list of current fields within the creature_ai_scripts table.
|
||||||
|
|
||||||
|
(Field_Name Discription)
|
||||||
|
id This value is mearly an incrementing counter of the current Event number. Required for sql queries.
|
||||||
|
creature_id Creature id which this event should occur on.
|
||||||
|
|
||||||
|
event_type Type of event (See Event Types below)
|
||||||
|
event_inverse_phase_mask Mask which phases this event should NOT trigger in*
|
||||||
|
event_chance Percent chance of this event occuring (1 - 100)
|
||||||
|
event_flags Event flags such as if the event is repeatable (see below)
|
||||||
|
event_param1 Variable for event (dependant on Event type)
|
||||||
|
event_param2
|
||||||
|
event_param3
|
||||||
|
event_param4
|
||||||
|
|
||||||
|
action1_type First Type of Action to take when event occurs (See Action Types below)
|
||||||
|
action1_param1 Variables used for Action1 (dependant on Action type)
|
||||||
|
action1_param2
|
||||||
|
action1_param3
|
||||||
|
|
||||||
|
action2_type Second Type of Action to take when event occurs (See Action Types below)
|
||||||
|
action2_param1 Variables used for Action2 (dependant on Action type)
|
||||||
|
action2_param2
|
||||||
|
action2_param3
|
||||||
|
|
||||||
|
action3_type Third Type of Action to take when event occurs (See Action Types below)
|
||||||
|
action3_param1 Variables used for Action3 (dependant on Action type)
|
||||||
|
action3_param2
|
||||||
|
action3_param3
|
||||||
|
|
||||||
|
All params are signed 32 bit values (+/- 2147483647). If param specifies time then time is in milliseconds.
|
||||||
|
If param specifies percentage then percentages are value/100 (ex: if param = 500 then that means 500%, -50 = -50%)
|
||||||
|
|
||||||
|
*Phase mask is a bit mask of which phases this event should not trigger in. Example: Phase mask value of 12 (1100)
|
||||||
|
would mean that this event would trigger 0, 1 and all other phases except for 2 and 3 (0 counts as the first phase).
|
||||||
|
|
||||||
|
=========================================
|
||||||
|
Event Types
|
||||||
|
=========================================
|
||||||
|
Below is the list of current Event types that EventAI can handle.
|
||||||
|
Each event type has its own specific interpretation of the params that accompany it.
|
||||||
|
Params are always read from Param1, then Param2, then Param3.
|
||||||
|
Events will not repeat until the creature exits combat unless EFLAG_REPEATABLE is set.
|
||||||
|
Some events such as EVENT_T_AGGRO, EVENT_T_DEATH, EVENT_T_SPAWNED, and EVENT_T_EVADE cannot repeat.
|
||||||
|
|
||||||
|
# Internal Name Pamarm usage Description
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
0 EVENT_T_TIMER InitialMin, InitialMax, RepeatMin, RepeatMax Expires first between (Param1) and (Param2) and then between every (Param3) and (Param4). but only in combat.
|
||||||
|
1 EVENT_T_TIMER_OOC InitialMin, InitialMax, RepeatMin, RepeatMax Expires first between (Param1) and (Param2) and then between every (Param3) and (Param4). but only out of combat.
|
||||||
|
2 EVENT_T_HP HPMax%, HPMin%, RepeatMin, RepeatMax Expires when HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
|
||||||
|
3 EVENT_T_MANA ManaMax%,ManaMin% RepeatMin, RepeatMax Expires once Mana% is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
|
||||||
|
4 EVENT_T_AGGRO NONE Expires upon initial aggro (does not repeat).
|
||||||
|
5 EVENT_T_KILL RepeatMin, RepeatMax Expires upon killing a player. Will repeat between every (Param1) and (Param2).
|
||||||
|
6 EVENT_T_DEATH NONE Expires upon Death of the Creature.
|
||||||
|
7 EVENT_T_EVADE NONE Expires upon creature EnterEvadeMode().
|
||||||
|
8 EVENT_T_SPELLHIT SpellID, School, RepeatMin, RepeatMax Expires upon Spell hit. If (param1) is set will only expire on that spell. If (param2) will only expire on spells of that school (-1 for all). Will repeat every (Param3) and (Param4) .
|
||||||
|
9 EVENT_T_RANGE MinDist, MaxDist, RepeatMin, RepeatMax Expires when the highest threat target distance is greater than (Param1) and less than (Param2). Will repeat every (Param3) and (Param4) .
|
||||||
|
10 EVENT_T_OOC_LOS Hostile-or-Not, MaxAllowedRange, RepeatMin, RepeatMax Expires when a Unit moves within distance(MaxAllowedRange) to creature. If Param1=0 it will expire if Unit are Hostile. If Param1=1 it will only expire if Unit are not Hostile(generally determined by faction). Will repeat every (Param3) and (Param4). Does not expire when the creature is in combat.
|
||||||
|
11 EVENT_T_SPAWNED NONE Expires at initial spawn and at creature respawn (useful for setting ranged movement type)
|
||||||
|
12 EVENT_T_TARGET_HP HPMax%, HPMin%, RepeatMin, RepeatMax Expires when Current Target's HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4) .
|
||||||
|
13 EVENT_T_TARGET_CASTING RepeatMin, RepeatatMax Expires when the current target is casting a spell. Will repeat every (Param1) and (Param2) .
|
||||||
|
14 EVENT_T_FRIENDLY_HP HPDeficit, Radius, RepeatMin, RepeatMax Expires when a friendly unit in radius has at least (param1) hp missing. Will repeat every (Param3) and (Param4) .
|
||||||
|
15 EVENT_T_FRIENDLY_IS_CC DispelType, Radius, RepeatMin, RepeatMax Expires when a friendly unit is Crowd controlled within the given radius (param2). Will repeat every (Param3) and (Param4) .
|
||||||
|
16 EVENT_T_MISSING_BUFF SpellId, Radius, RepeatMin, RepeatMax Expires when a friendly unit is missing aura's given by spell (param1) within radius (param2). Will repeat every (Param3) and (Param4) .
|
||||||
|
17 EVENT_T_SUMMONED_UNIT CreatureId, RepeatMin, RepeatMax Expires after creature with entry = (param1) is spawned or for all spawns if param1 = 0. Will repeat every (Param2) and (Param3).
|
||||||
|
18 EVENT_T_TARGET_MANA ManaMax%, ManaMin%, RepeatMin, RepeatMax
|
||||||
|
21 EVENT_T_REACHED_HOME NONE Expires when creature reach it's home(spawn) location after Evade.
|
||||||
|
22 EVENT_T_RECEIVE_EMOTE EmoteId, Condition, CondValue1, CondValue2 Expires when creature receive emote with text emote id(enum TextEmotes). Condition can be defined. If set, then most conditions has additional value (see enum ConditionType)
|
||||||
|
|
||||||
|
=========================================
|
||||||
|
Action Types
|
||||||
|
=========================================
|
||||||
|
Below is the list of current Action types that EventAI can handle.
|
||||||
|
Each event type has its own specific interpretation of the params that accompany it.
|
||||||
|
Params are always read from Param1, then Param2, then Param3.
|
||||||
|
|
||||||
|
(# Internal Name Param usage Discription)
|
||||||
|
0 ACTION_T_NONE No Action Does Nothing
|
||||||
|
1 ACTION_T_TEXT -TextId1, -TextId2, -TextId3 Displays the -TextId as defined. In case -TextId2 and optionally -TextId3, the output will be randomized. Type text are defined in the text table itself(say, yell, whisper, etc) along with other options for the text. All values are required to be negative.
|
||||||
|
2 ACTION_T_SET_FACTION FactionId Change faction for creature. If param1==0, creature will revert to default faction.
|
||||||
|
3 ACTION_T_MORPH_TO_ENTRY_OR_MODEL CreatureEntry, ModelId Set model from creature_template.entry(param1) OR set explicit modelId(param2). If param1 AND param2 both 0, demorph and revert to default model for creature.
|
||||||
|
4 ACTION_T_SOUND SoundId Plays Sound
|
||||||
|
5 ACTION_T_EMOTE EmoteId Does emote
|
||||||
|
6 ACTION_T_RANDOM_SAY UNUSED
|
||||||
|
7 ACTION_T_RANDOM_YELL UNUSED
|
||||||
|
8 ACTION_T_RANDOM_TEXTEMOTE UNUSED
|
||||||
|
9 ACTION_T_RANDOM_SOUND SoundId1, SoundId2, SoundId3 Plays random sound between 3 params*
|
||||||
|
10 ACTION_T_RANDOM_EMOTE EmoteId1, EmoteId2, EmoteId3 Emotes random emote between 3 params
|
||||||
|
11 ACTION_T_CAST SpellId, Target, CastFlags Casts spell (param1) on target type (param2). Uses Cast Flags (specified below target types)
|
||||||
|
12 ACTION_T_SUMMON CreatureID, Target, Duration Summons creature (param1) to attack target (param2) for (param3) duration. Spawns on top of current creature.
|
||||||
|
13 ACTION_T_THREAT_SINGLE_PCT Threat%, Target Modifies threat by (param1) on target type (param2)
|
||||||
|
14 ACTION_T_THREAT_ALL_PCT Threat% Modifies threat by (param1) on all targets (using -100% on all will result in full aggro dump)
|
||||||
|
15 ACTION_T_QUEST_EVENT QuestID, Target Calls AreaExploredOrEventHappens with (param1) for target type (Param2)
|
||||||
|
16 ACTION_T_QUEST_CASTCREATUREGO CreatureID, SpellId, Target Sends CastCreatureOrGo for CreatureId (param1) with SpellId (param2) for target (param3)
|
||||||
|
17 ACTION_T_SET_UNIT_FIELD Field_Number, Value, Target Sets Unit Field (param1) to Value (param2) on target type (param3)
|
||||||
|
18 ACTION_T_SET_UNIT_FLAG Flags, Target Sets flag (flags can be binary OR together to modify multiple flags at once) on for Target type (param2)
|
||||||
|
19 ACTION_T_REMOVE_UNIT_FLAG Flags, Target Removes flag (flags can be binary OR together to modify multiple flags at once) on for Target type (param2)
|
||||||
|
20 ACTION_T_AUTO_ATTACK AllowAutoAttack 0 = stop melee attack, anything else means continue attacking/allow melee attacking
|
||||||
|
21 ACTION_T_COMBAT_MOVEMENT AllowCombatMovement 0 = stop combat based movement, anything else continue/allow combat based movement (targeted movement generator)
|
||||||
|
22 ACTION_T_SET_PHASE Phase Sets the current phase to (param1)
|
||||||
|
23 ACTION_T_INC_PHASE Value Increments the phase by (param1). May be negative to decrement phase but should not be 0.
|
||||||
|
24 ACTION_T_EVADE No Params Forces the creature to evade. Wiping all threat and dropping combat.
|
||||||
|
25 ACTION_T_FLEE No Params Causes the .creature to flee. Please use this action instead of directly casting this spell so we may change this when a more correct approach is found.
|
||||||
|
26 ACTION_T_QUEST_EVENT_ALL QuestId Calls GroupEventHappens with (param1). Only used if it's _expected_ event should complete for all players in current party
|
||||||
|
27 ACTION_T_CASTCREATUREGO_ALL QuestId, SpellId Calls CastedCreatureOrGo for all players on the threat list with QuestID(Param1) and SpellId(Param2)
|
||||||
|
28 ACTION_T_REMOVEAURASFROMSPELL Target, Spellid Removes all auras on Target caused by Spellid
|
||||||
|
29 ACTION_T_RANGED_MOVEMENT Distance, Angle Changes the movement generator type to a ranged type. Note: Default melee type can still be done with this. Specify 0 angle and 0 distance.
|
||||||
|
30 ACTION_T_RANDOM_PHASE PhaseId1, PhaseId2, PhaseId3 Sets the phase to the id between 3 params*
|
||||||
|
31 ACTION_T_RANDOM_PHASE_RANGE PhaseMin, PhaseMax Sets the phase to a random id (Phase = PhaseMin + rnd % PhaseMin-PhaseMax). PhaseMax must be greater than PhaseMin.
|
||||||
|
32 ACTION_T_SUMMON CreatureID, Target, SummonID Summons creature (param1) to attack target (param2) at location specified by EventAI_Summons (param3).
|
||||||
|
33 ACTION_T_KILLED_MONSTER CreatureID, Target Calls KilledMonster (param1) for target of type (param2)
|
||||||
|
34 ACTION_T_SET_INST_DATA Field, Data Calls ScriptedInstance::SetData with field (param1) and data (param2)
|
||||||
|
35 ACTION_T_SET_INST_DATA64 Field, Target Calls ScriptedInstance::SetData64 with field (param1) and data (param2) target's GUID.
|
||||||
|
36 ACTION_T_UPDATE_TEMPLATE TemplateId, Team Changes the creature to a new creature template of (param1) with team = Alliance if (param2) = false or Horde if (param2) = true
|
||||||
|
37 ACTION_T_DIE No Params Kills the creature
|
||||||
|
38 ACTION_T_ZONE_COMBAT_PULSE No Params Places all players within the instance into combat with the creature. Only works in combat and only works inside of instances.
|
||||||
|
|
||||||
|
* = Use -1 to specify that if this param is picked to do nothing. Random is constant between actions within an event. So if you have a random Yell and a random Sound they will match up (ex: param2 with param2)
|
||||||
|
|
||||||
|
=========================================
|
||||||
|
Event Types
|
||||||
|
=========================================
|
||||||
|
Note:
|
||||||
|
COMBAT ONLY - Means that this event will only trigger durring combat.
|
||||||
|
OUT OF COMBAT ONLY - Means that this event will only trigger while out of combat.
|
||||||
|
BOTH - This event can trigger both in and out of combat.
|
||||||
|
|
||||||
|
Events that do not have lables on them are events that are directly involved with the in and out of combat state.
|
||||||
|
|
||||||
|
------------------
|
||||||
|
0 = EVENT_T_TIMER:
|
||||||
|
------------------
|
||||||
|
Parameter 1: InitialMin - Minumum Time used to calculate Random Initial Expire
|
||||||
|
Parameter 2: InitialMax - Maximum Time used to calculate Random Initial Expire
|
||||||
|
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
|
||||||
|
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
|
||||||
|
|
||||||
|
COMBAT ONLY! - Expires first between (Param1) and (Param2) and then between every (Param3) and (Param4) from then on.
|
||||||
|
This is commonly used for spells that repeat cast during combat (Simulate Spell Cooldown).
|
||||||
|
|
||||||
|
----------------------
|
||||||
|
1 = EVENT_T_TIMER_OOC:
|
||||||
|
----------------------
|
||||||
|
Parameter 1: InitialMin - Minumum Time used to calculate Random Initial Expire
|
||||||
|
Parameter 2: InitialMax - Maximum Time used to calculate Random Initial Expire
|
||||||
|
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
|
||||||
|
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
|
||||||
|
|
||||||
|
OUT OF COMBAT ONLY! - Expires first between (Param1) and (Param2) and then between every (Param3) and (Param4) from then on.
|
||||||
|
This is commonly used for events that occur and repeat outside of combat.
|
||||||
|
|
||||||
|
---------------
|
||||||
|
2 = EVENT_T_HP:
|
||||||
|
---------------
|
||||||
|
Parameter 1: HPMax% - Maximum HP% That this Event will Expire
|
||||||
|
Parameter 2: HPMin% - Minimum HP% That this Event will Expire
|
||||||
|
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
|
||||||
|
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
|
||||||
|
|
||||||
|
BOTH - Expires when HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
|
||||||
|
This is commonly used for events that trigger at a specific HP% (Such as Heal/Enrage Spells or NPC's that Flee).
|
||||||
|
|
||||||
|
-----------------
|
||||||
|
3 = EVENT_T_MANA:
|
||||||
|
-----------------
|
||||||
|
Parameter 1: ManaMax% - Maximum Mana% That this Event will Expire
|
||||||
|
Parameter 2: ManaMin% - Minimum Mana% That this Event will Expire
|
||||||
|
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
|
||||||
|
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
|
||||||
|
|
||||||
|
BOTH - Expires once Mana% is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
|
||||||
|
This is commonly used for events where an NPC low on Mana will do something (Such as stop casting spells and switch to melee).
|
||||||
|
|
||||||
|
------------------
|
||||||
|
4 = EVENT_T_AGGRO:
|
||||||
|
------------------
|
||||||
|
This Event Expires upon initial aggro (does not repeat).
|
||||||
|
|
||||||
|
-----------------
|
||||||
|
5 = EVENT_T_KILL:
|
||||||
|
-----------------
|
||||||
|
Parameter 1: RepeatMin - Minimum Time used to calculate Random Repeat Expire
|
||||||
|
Parameter 2: RepeatMax - Maximum Time used to calculate Random Repeat Expire
|
||||||
|
|
||||||
|
COMBAT ONLY! - Expires upon killing a player. Will repeat every (Param1) and (Param2).
|
||||||
|
This Event Expires upon killing a player. It is commonly used for NPC's who yell or do something after killing a player.
|
||||||
|
|
||||||
|
------------------
|
||||||
|
6 = EVENT_T_DEATH:
|
||||||
|
------------------
|
||||||
|
This Event Expires upon Death of the Scripted NPC.
|
||||||
|
This is commonly used for NPC's who have a yell on death or cast some kind if summon spell when they die.
|
||||||
|
|
||||||
|
------------------
|
||||||
|
7 = EVENT_T_EVADE:
|
||||||
|
------------------
|
||||||
|
This Event Expires upon the creature EnterEvadeMode().
|
||||||
|
This is commonly used for NPC's who use phases, allows you to reset their phase to 0 upon evade to prevent possible strange behavior.
|
||||||
|
|
||||||
|
---------------------
|
||||||
|
8 = EVENT_T_SPELLHIT:
|
||||||
|
---------------------
|
||||||
|
Parameter 1: SpellID - The Spell ID that will trigger the event to occur (NOTE: If you use Spell School as the trigger set this value to 0)
|
||||||
|
Parameter 2: School - Spell School to trigger the event (NOTE: If you use a SpellID then set this value to -1) - *See Below for Spell School Bitmask Values*
|
||||||
|
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
|
||||||
|
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
|
||||||
|
|
||||||
|
BOTH - Expires upon Spell hit. If (param1) is set will only expire on that spell. If (param2) will only expire on spells of that school. Will repeat every (Param3) and (Param4).
|
||||||
|
This Event is commonly used for NPC's who can do special things when you cast a spell (Or specific spell) on them.
|
||||||
|
|
||||||
|
------------------
|
||||||
|
9 = EVENT_T_RANGE:
|
||||||
|
------------------
|
||||||
|
Parameter 1: MinDist - This Distance is the Minimum Distance between the NPC and it's target to allow this Event to Expire
|
||||||
|
Parameter 2: MaxDist - This Distance is the Maximum Distance between the NPC and it's target to allow this Event to Expire
|
||||||
|
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
|
||||||
|
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
|
||||||
|
|
||||||
|
COMBAT ONLY! - Expires when the highest threat target distance is greater than (Param1) and less than (Param2). Will repeat every (Param3) and (Param4).
|
||||||
|
This Event is commonly used for NPC's who have Ranged Combat and will Throw/Shoot between a certian distance.
|
||||||
|
|
||||||
|
---------------------
|
||||||
|
10 = EVENT_T_OOC_LOS:
|
||||||
|
---------------------
|
||||||
|
Parameter 1: Hostile-or-Not - This will expire if Unit are hostile. If Param1=1 it will only expire if Unit are not Hostile(generally determined by faction)
|
||||||
|
Parameter 2: MaxAllowedRange - Expires when a Unit moves within this distance to creature
|
||||||
|
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
|
||||||
|
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
|
||||||
|
|
||||||
|
OUT OF COMBAT!
|
||||||
|
This Event is commonly used for NPC's who do something or say something to you when you walk past them Out of Combat.
|
||||||
|
|
||||||
|
---------------------
|
||||||
|
11 = EVENT_T_SPAWNED:
|
||||||
|
---------------------
|
||||||
|
Expires at initial spawn and at creature respawn.
|
||||||
|
This Event is commonly used for setting ranged movement type or Summoning a Pet on Spawn
|
||||||
|
|
||||||
|
-----------------------
|
||||||
|
12 = EVENT_T_TARGET_HP:
|
||||||
|
-----------------------
|
||||||
|
Parameter 1: HPMax% - Maximum HP% That this Event will Expire
|
||||||
|
Parameter 2: HPMin% - Minimum HP% That this Event will Expire
|
||||||
|
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
|
||||||
|
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
|
||||||
|
|
||||||
|
COMBAT ONLY! - Expires when Current NPC's Target's HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
|
||||||
|
This Event is commonly used for NPC's who have a special ability (Like Execute) that only casts when a Player HP is low.
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
13 = EVENT_T_TARGET_CASTING:
|
||||||
|
----------------------------
|
||||||
|
Parameter 1: RepeatMin - Minimum Time used to calculate Random Repeat Expire
|
||||||
|
Parameter 2: RepeatMax - Maximum Time used to calculate Random Repeat Expire
|
||||||
|
|
||||||
|
COMBAT ONLY! - Expires when the current target is casting a spell. Will repeat every (Param1) and (Param2).
|
||||||
|
This event is commonly used for NPC's who will cast a counter spell when their target starts to cast a spell.
|
||||||
|
|
||||||
|
-------------------------
|
||||||
|
14 = EVENT_T_FRIENDLY_HP:
|
||||||
|
-------------------------
|
||||||
|
Parameter 1: HPDeficit - This is the Amount of HP Missing from Full HP to trigger this event (You would need to calculate the amount of HP the event happens and subtract that from Full HP Value to get this number)
|
||||||
|
Parameter 2: Radius - This is the Range in Yards the NPC will scan for nearby Friendlies (Faction is Friendly To) for the missing amount of HP in Param1.
|
||||||
|
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
|
||||||
|
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
|
||||||
|
|
||||||
|
COMBAT ONLY! - Expires when a friendly unit in radius(param2) has at least (param1) hp missing. Will repeat every (Param3) and (Param4).
|
||||||
|
This is commonly used when an NPC in Combat will heal a nearby Friendly NPC in Combat with a Heal/Renew Spell.
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
15 = EVENT_T_FRIENDLY_IS_CC:
|
||||||
|
----------------------------
|
||||||
|
Parameter 1: DispelType - Dispel Type to trigger the event - *See Below for Dispel Bitmask Values*
|
||||||
|
Parameter 2: Radius - This is the Range in Yards the NPC will scan for nearby Friendlies being Crowd Controlled
|
||||||
|
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
|
||||||
|
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
|
||||||
|
|
||||||
|
COMBAT ONLY! - Expires when a friendly unit is Crowd controlled within the given radius (param2). Will repeat every (Param3) and (Param4).
|
||||||
|
This is commonly used for NPC's who can come to the resule of other Friendly NPC's if being Crowd Controlled
|
||||||
|
|
||||||
|
--------------------------
|
||||||
|
16 = EVENT_T_MISSING_BUFF:
|
||||||
|
--------------------------
|
||||||
|
Parameter 1: SpellId - This is the SpellID That the Aura Check will look for (If it is missing this Aura)
|
||||||
|
Parameter 2: Radius - This is the Range in Yards the NPC will scan for nearby Friendlies (Faction is Friendly To) for the missing Aura.
|
||||||
|
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
|
||||||
|
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
|
||||||
|
|
||||||
|
BOTH - Expires when a friendly unit is missing aura's given by spell (param1) within radius (param2). Will repeat every (Param3) and (Param4).
|
||||||
|
This is commonly used for NPC's who watch friendly units for a debuff to end so they can recast it on them again.
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
17 = EVENT_T_SUMMONED_UNIT:
|
||||||
|
---------------------------
|
||||||
|
Parameter 1: CreatureId - The CreatureID that the NPC is watching to spawn 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 spawned 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 summoned. Usually used is Complex Scripts or Special Events.
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
21 = EVENT_T_REACHED_HOME:
|
||||||
|
---------------------------
|
||||||
|
Expires only when creature has returned to it's home location after Evade. Out of combat event.
|
||||||
|
Most commonly used to cast spells that can not be casted in EVENT_T_EVADE and other effects that does not fit in while still running back to spawn/home location.
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
22 = EVENT_T_RECEIVE_EMOTE:
|
||||||
|
---------------------------
|
||||||
|
Expires only when creature receive emote from player. Valid text emote id's are in Mangos source (enum TextEmotes)
|
||||||
|
Event does not require any conditions to process, however many are ecpected to have condition.
|
||||||
|
|
||||||
|
EventAI use conditions from available in Mangos (enum ConditionType)
|
||||||
|
Current implemented conditions:
|
||||||
|
CONDITION_NONE (0) 0 0
|
||||||
|
CONDITION_AURA (1) spell_id effindex
|
||||||
|
CONDITION_ITEM (2) item_id count
|
||||||
|
CONDITION_ITEM_EQUIPPED (3) item_id count
|
||||||
|
CONDITION_ZONEID (4) zone_id 0
|
||||||
|
CONDITION_REPUTATION_RANK (5) faction_id min_rank
|
||||||
|
CONDITION_TEAM (6) player_team 0 (469-Alliance / 67-Horde)
|
||||||
|
CONDITION_SKILL (7) skill_id min_skill_value
|
||||||
|
CONDITION_QUESTREWARDED (8) quest_id 0, if quest are rewarded
|
||||||
|
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
|
||||||
|
|
||||||
|
=========================================
|
||||||
|
Action Types
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
-----------------
|
||||||
|
1 = ACTION_T_TEXT:
|
||||||
|
-----------------
|
||||||
|
Parameter 1: The entry of the text that the NPC should use from eventai_texts table. Optionally a entry from other tables can be used (such as custom_texts).
|
||||||
|
Entry are required to be negative and exist in a *_texts-table. The type text to be displayed are defined in the texts-table itself (Say, Yell, Whisper, Emote Text, Boss Whisper, Boss Emote)
|
||||||
|
Other options are also to be defined in the texts-table, such as a sound to be heard with the text and the language used in output (common, dwarvish, etc).
|
||||||
|
In case this entry has a localized version of the text, the localized text will be displayed in client that support this locale.
|
||||||
|
|
||||||
|
Parameter 2: Optional. TextId can be defined in addition. The same apply to this as explained above, however eventAI will randomize between the two.
|
||||||
|
Parameter 3: Optional, if Parameter 2 exist. In this case, eventAI will randomize between three.
|
||||||
|
|
||||||
|
Read at bottom for documentation of creature_ai_texts-table.
|
||||||
|
|
||||||
|
------------------
|
||||||
|
2 = ACTION_T_SET_FACTION:
|
||||||
|
------------------
|
||||||
|
Parameter 1: FactionId from Faction.dbc OR 0. Changes faction for creature. If 0, creature will revert to it's default faction if previously changed.
|
||||||
|
|
||||||
|
-----------------------
|
||||||
|
3 = ACTION_T_MORPH_TO_ENTRY_OR_MODEL:
|
||||||
|
-----------------------
|
||||||
|
Parameter 1: Creature entry from creature_template. Action will then change to the model this creature are using.
|
||||||
|
Parameter 2: If parameter 1 is 0, then this modelId will be used (in case parameter 1 exist, parameter 2 will not be used)
|
||||||
|
|
||||||
|
If both parameter 1 and 2 is 0, the creature will DeMorph, and use it's default model.
|
||||||
|
|
||||||
|
-------------------
|
||||||
|
4 = ACTION_T_SOUND:
|
||||||
|
-------------------
|
||||||
|
Parameter 1: The Sound ID to be played. (Sound IDs are contained in the DBC files.)
|
||||||
|
|
||||||
|
The creature will play the specified sound.
|
||||||
|
This is commonly used for Bosses who Yell and then also have a Voice for the same thing.
|
||||||
|
|
||||||
|
-------------------
|
||||||
|
5 = ACTION_T_EMOTE:
|
||||||
|
-------------------
|
||||||
|
Parameter 1: The Emote ID that the creature should perform. (Emote IDs are also contained in the DBC but they can be found in the mangos source as well).
|
||||||
|
|
||||||
|
The creature will perform a visual emote. Unlike a text emote, a visual emote is one where the creature will actually move or perform a gesture.
|
||||||
|
This is commonly used for NPC's who may perform a special action (Salute, Roar, ect...). Not all player emotes work for creature models.
|
||||||
|
|
||||||
|
------------------------
|
||||||
|
6 = ACTION_T_RANDOM_SAY:
|
||||||
|
------------------------
|
||||||
|
UNUSED Can be reused to create new action type
|
||||||
|
|
||||||
|
-------------------------
|
||||||
|
7 = ACTION_T_RANDOM_YELL:
|
||||||
|
-------------------------
|
||||||
|
UNUSED Can be reused to create new action type
|
||||||
|
|
||||||
|
------------------------------
|
||||||
|
8 = ACTION_T_RANDOM_TEXTEMOTE:
|
||||||
|
------------------------------
|
||||||
|
UNUSED Can be reused to create new action type
|
||||||
|
|
||||||
|
--------------------------
|
||||||
|
9 = ACTION_T_RANDOM_SOUND:
|
||||||
|
--------------------------
|
||||||
|
Parameter 1: The Sound ID to be played as Random Choice #1.
|
||||||
|
Parameter 2: The Sound ID to be played as Random Choice #2.
|
||||||
|
Parameter 3: The Sound ID to be played as Random Choice #3.
|
||||||
|
|
||||||
|
Similar to the ACTION_T_SOUND action, it will choose at random a sound to play.
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
10 = ACTION_T_RANDOM_EMOTE:
|
||||||
|
---------------------------
|
||||||
|
Parameter 1: The Emote ID to be played as Random Choice #1.
|
||||||
|
Parameter 2: The Emote ID to be played as Random Choice #2.
|
||||||
|
Parameter 3: The Emote ID to be played as Random Choice #3.
|
||||||
|
|
||||||
|
Similar to the ACTION_T_EMOTE action, it will choose at random an Emote to Visually Perform.
|
||||||
|
|
||||||
|
-------------------
|
||||||
|
11 = ACTION_T_CAST:
|
||||||
|
-------------------
|
||||||
|
Parameter 1: SpellId - The Spell ID to use for the NPC to cast. The value used in this field needs to be a valid Spell ID.
|
||||||
|
Parameter 2: Target - The Target Type defining who the creature should cast the spell at. The value in this field needs to be a valid Target Type as specified in the reference tables below.
|
||||||
|
Parameter 3: CastFlags - See Table Below for Cast Flag Bitmask Values. If you are unsure what to set this value at leave it at 0.
|
||||||
|
|
||||||
|
The creature will cast a spell specified by a spell ID on a target specified by the target type.
|
||||||
|
This is commonly used for NPC's who cast spells.
|
||||||
|
|
||||||
|
---------------------
|
||||||
|
12 = ACTION_T_SUMMON:
|
||||||
|
---------------------
|
||||||
|
Parameter 1: CreatureID - The Creature Template ID to be Summoned. The value here needs to be a valid Creature Template ID.
|
||||||
|
Parameter 2: Target - The Target Type defining who the Summoned creature will attack once spawned. The value in this field needs to be a valid Target Type as specified in the reference tables below.
|
||||||
|
Parameter 3: Duration - The duration until the summoned creature should be unsummoned AFTER Combat ends. The value in this field is in milliseconds or 0.
|
||||||
|
|
||||||
|
The NPC will Summon another creature at the same spot as itself that will attack the specified target.
|
||||||
|
NOTE: Almost all Creature Summons have proper Summon Spells that should be used when possible. This Action is a powerful last resort option only to be used if nothing else works.
|
||||||
|
NOTE: Using Target Type 0 will cause the Summoned creature to not attack anyone.
|
||||||
|
NOTE: If Duration is set at 0, then the summoned creature will not despawn until it has died.
|
||||||
|
This is used as a manual way to force an NPC to Summon.
|
||||||
|
--------------------------------
|
||||||
|
13 = ACTION_T_THREAT_SINGLE_PCT:
|
||||||
|
--------------------------------
|
||||||
|
Parameter 1: Threat% - Threat percent that should be modified. The value in this field can range from -100 to +100. If it is negative, threat will be taken away and if positive, threat will be added.
|
||||||
|
Parameter 2: Target - The Target Type defining on whom the threat change should occur. The value in this field needs to be a valid target type as specified in the reference tables below.
|
||||||
|
|
||||||
|
This action will modify the threat of a target in the creature's threat list by the specified percent.
|
||||||
|
This is commonly used to allow an NPC to adjust the Threat to a single player.
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
14 = ACTION_T_THREAT_ALL_PCT:
|
||||||
|
-----------------------------
|
||||||
|
Parameter 1: Threat% - The percent that should be used in modifying everyone's threat in the creature's threat list. The value here can range from -100 to +100.
|
||||||
|
|
||||||
|
This action will modify the threat for everyone in the creature's threat list by the specified percent.
|
||||||
|
NOTE: Using -100 will cause the creature to reset everyone's threat to 0 so that everyone has the same amount of threat. It will NOT remove anyone from the threat list.
|
||||||
|
This is commonly used to allow an NPC to drop threat for all players to zero.
|
||||||
|
|
||||||
|
--------------------------
|
||||||
|
15 = ACTION_T_QUEST_EVENT:
|
||||||
|
--------------------------
|
||||||
|
Parameter 1: QuestID - The Quest Template ID. The value here must be a valid quest template ID. Furthermore, the quest should have SpecialFlags | 2 as it would need to be completed by an external event which is the activation of this action.
|
||||||
|
Parameter 2: Target - The Target Type defining whom the quest should be completed for. The value in this field needs to be a valid target type as specified in the reference tables below.
|
||||||
|
|
||||||
|
This action will satisfy the external completion requirement for the quest for the specified target defined by the target type.
|
||||||
|
NOTE: This action can only be used with player targets so it must be ensured that the target type will point to a player.
|
||||||
|
This is commonly used for Quests where only ONE player will gain credit for the quest.
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
16 = ACTION_T_CASTCREATUREGO:
|
||||||
|
-----------------------------
|
||||||
|
Parameter 1: CreatureID - The Creature Template ID to be Summoned. The value here needs to be a valid Creature Template ID.
|
||||||
|
Parameter 2: SpellId - The Spell ID to use to simulate the cast. The value used in this field needs to be a valid Spell ID.
|
||||||
|
Parameter 3: Target - The Target Type defining whom the quest credit should be given to. The value in this field needs to be a valid target type as specified in the reference tables below.
|
||||||
|
|
||||||
|
This action will call CastedCreatureOrGO() function for the player. It can be used to give quest credit for casting a spell on the creature.
|
||||||
|
This is commonly used for NPC's who have a special requirement to have a Spell cast on them to complete a quest.
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
17 = ACTION_T_SET_UNIT_FIELD:
|
||||||
|
-----------------------------
|
||||||
|
Parameter 1: Field_Number - The index of the Field Number to be changed. Use (http://wiki.udbforums.org/index.php/Character_data) for a list of indeces and what they control. Creatures only contain the OBJECT_FIELD_* and UNIT_FIELD_* fields. They do not contain the PLAYER_FIELD_* fields.
|
||||||
|
Parameter 2: Value - The new value to be put in the field.
|
||||||
|
Parameter 3: Target - The Target Type defining for whom the unit field should be changed. The value in this field needs to be a valid target type as specified in the reference tables below.
|
||||||
|
|
||||||
|
When activated, this action can change the target's unit field values. More information on the field value indeces can be found at (http://wiki.udbforums.org/index.php/Character_data)
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
18 = ACTION_T_SET_UNIT_FLAG:
|
||||||
|
----------------------------
|
||||||
|
Parameter 1: Flags - The flag(s) to be set. Multiple flags can be set by using bitwise-OR on them (adding them together).
|
||||||
|
Parameter 2: Target - The Target Type defining for whom the flags should be changed. The value in this field needs to be a valid Target Type as specified in the reference tables below.
|
||||||
|
|
||||||
|
When activated, this action changes the target's flags by adding (turning on) more flags. For example, this action can make the creature unattackable/unselectable if the right flags are used.
|
||||||
|
|
||||||
|
-------------------------------
|
||||||
|
19 = ACTION_T_REMOVE_UNIT_FLAG:
|
||||||
|
-------------------------------
|
||||||
|
Parameter 1: Flags - The flag(s) to be removed. Multiple flags can be set by using bitwise-OR on them (adding them together).
|
||||||
|
Parameter 2: Target - The target type defining for whom the flags should be changed. The value in this field needs to be a valid Target Type as specified in the reference tables below.
|
||||||
|
|
||||||
|
When activated, this action changes the target's flags by removing (turning off) flags. For example, this action can make the creature normal after it was unattackable/unselectable if the right flags are used.
|
||||||
|
|
||||||
|
--------------------------
|
||||||
|
20 = ACTION_T_AUTO_ATTACK:
|
||||||
|
--------------------------
|
||||||
|
Parameter 1: AllowAutoAttack - If zero, then the creature will stop its melee attacks. If non-zero, then the creature will either continue its melee attacks (the action would then have no effect) or it will start its melee attacks on the target with the top threat if its melee attacks were previously stopped.
|
||||||
|
|
||||||
|
This action controls whether or not the creature should stop or start the auto melee attack.
|
||||||
|
NOTE: The ACID Dev Team has conformed to using either 0 or 1 for the Param values (0 = Stop Melee, 1 = Start Melee).
|
||||||
|
This is commonly used in combination with EVENT_T_RANGE and ACTION_T_COMBAT_MOVEMENT for Ranged Combat for Mages and Spell Casters.
|
||||||
|
|
||||||
|
------------------------------
|
||||||
|
21 = ACTION_T_COMBAT_MOVEMENT:
|
||||||
|
------------------------------
|
||||||
|
Parameter 1: If zero, then the creature will stop moving towards its victim (if its victim gets out of melee range) and will be stationary. If non-zero, then the creature will either continue to follow its victim (the action would have no effect) or it will start to follow the target with the top threat if its movement was disabled before.
|
||||||
|
|
||||||
|
This action controls whether or not the creature will always move towards its target.
|
||||||
|
NOTE: The ACID Dev Team has conformed to using either 0 or 1 for the Param values. (0 = Stop Movement, 1 = Start Movement)
|
||||||
|
This is commonly used with EVENT_T_RANGE and ACTION_T_AUTO_ATTACK for NPC's who engage in Ranged Comabt (Either Spells or Ranged Attacks)
|
||||||
|
|
||||||
|
------------------------
|
||||||
|
22 = ACTION_T_SET_PHASE:
|
||||||
|
------------------------
|
||||||
|
Parameter 1: The new phase to set the creature in. This number must be an integer between 0 and 31. Numbers outside of that range will result in an error.
|
||||||
|
|
||||||
|
When activated, this action sets the creature's event to the specified value.
|
||||||
|
NOTE: The creature's current Phase is NOT reset at creature evade. You must manually set the phase back to 0 at EVENT_T_RESET.
|
||||||
|
NOTE: The value used for the Param is the actual Phase Number (Not The Event_Inverse_Phase_Mask)
|
||||||
|
This is commonly used for complex scripts with several phases and you need to switch to a different phase.
|
||||||
|
|
||||||
|
------------------------
|
||||||
|
23 = ACTION_T_INC_PHASE:
|
||||||
|
------------------------
|
||||||
|
Parameter 1: Value - The number of phases to increase or decrease. Use negative values to decrease the current phase.
|
||||||
|
|
||||||
|
When activated, this action will increase (or decrease) the current creature's phase.
|
||||||
|
NOTE: After increasing or decreasing the phase by this action, the current phase must NOT be lower than 0 or exceed 31.
|
||||||
|
This can be used instead of ACTION_T_SET_PHASE to change phases in scripts. Just a user friendly option for changing phases.
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
24 = ACTION_T_EVADE:
|
||||||
|
--------------------
|
||||||
|
When activated, the creature will immediately exit out of combat, clear its threat list, and move back to its spawn point. Basically, this action will reset the whole encounter.
|
||||||
|
NOTE: All Param Values Are 0 for this Action.
|
||||||
|
|
||||||
|
-------------------
|
||||||
|
25 = ACTION_T_FLEE:
|
||||||
|
-------------------
|
||||||
|
When activated, the creature will try to flee from combat. Currently this is done by it casting a fear-like spell on itself called "Run Away".
|
||||||
|
A Better Flee system is in Development.
|
||||||
|
NOTE: All Param Values Are 0 for this Action.
|
||||||
|
|
||||||
|
------------------------------
|
||||||
|
26 = ACTION_T_QUEST_EVENT_ALL:
|
||||||
|
------------------------------
|
||||||
|
Parameter 1: QuestId - The quest ID to finish for everyone.
|
||||||
|
|
||||||
|
This action does the same thing as the ACTION_T_QUEST_EVENT does but it does it for all players in the creature's threat list.
|
||||||
|
NOTE: If a player is not in the NPC's threat list for whatever reason, he/she won't get the quest completed.
|
||||||
|
|
||||||
|
---------------------------------
|
||||||
|
27 = ACTION_T_CASTCREATUREGO_ALL:
|
||||||
|
---------------------------------
|
||||||
|
Parameter 1: QuestId - The quest template ID.
|
||||||
|
Parameter 2: SpellId - The spell ID used to simulate the cast.
|
||||||
|
|
||||||
|
This action does the same thing as the ACTION_T_CASTCREATUREGO does but it does it for all players in the creature's threat list.
|
||||||
|
NOTE: If a player is not in its threat list for whatever reason, he/she won't receive the cast emulation.
|
||||||
|
|
||||||
|
-----------------------------------
|
||||||
|
28 = ACTION_T_REMOVEAURASFROMSPELL:
|
||||||
|
-----------------------------------
|
||||||
|
Parameter 1: Target - The target type defining for whom the unit field should be changed. The value in this field needs to be a valid target type as specified in the reference tables below.
|
||||||
|
Parameter 2: SpellId - The spell ID whose auras will be removed.
|
||||||
|
|
||||||
|
This action will remove all auras from a specific spell from the target.
|
||||||
|
This is commonly used for NPC's who have an OOC Aura that is removed at combat start or a similar idea (Like Stealth or Shape Shift)
|
||||||
|
|
||||||
|
------------------------------
|
||||||
|
29 = ACTION_T_RANGED_MOVEMENT:
|
||||||
|
------------------------------
|
||||||
|
Parameter 1: Distance - The distance the mob should keep between it and its target.
|
||||||
|
Parameter 2: Angle - The angle the mob should use.
|
||||||
|
|
||||||
|
This action changes the movement type generator to ranged type using the specified values for angle and distance.
|
||||||
|
NOTE: Specifying zero angle and distance will make it just melee instead.
|
||||||
|
This is commonly used for NPC's who always attack at range and you can specify the distance they will maintain from the target.
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
30 = ACTION_T_RANDOM_PHASE:
|
||||||
|
---------------------------
|
||||||
|
Parameter 1: PhaseId1 - A possible random phase choice.
|
||||||
|
Parameter 2: PhaseId2 - A possible random phase choice.
|
||||||
|
Parameter 3: PhaseId3 - A possible random phase choice.
|
||||||
|
|
||||||
|
Randomly sets the phase to one from the three parameter choices.
|
||||||
|
NOTE: Use -1 to specify that if this param is picked to do nothing. Random is constant between actions within an event. So if you have a random Yell and a random Sound they will match up (ex: param2 with param2)
|
||||||
|
NOTE 2: PLEASE NOTE THAT EACH OF THE PARAM VALUES ARE ACTUAL PHASE NUMBERS NOT THE INVERSE PHASE MASK VALUE.
|
||||||
|
This is commonly used for Spellcasting NPC's who on Aggro may select at random a school of spells to use for the fight. Use this if you have up to 3 phases used, otherwise use Action 31 for more then 3 phases.
|
||||||
|
|
||||||
|
---------------------------------
|
||||||
|
31 = ACTION_T_RANDOM_PHASE_RANGE:
|
||||||
|
---------------------------------
|
||||||
|
Parameter 1: PhaseMin - The minimum of the phase range.
|
||||||
|
Parameter 2: PhaseMax - The maximum of the phase range. The number here must be greater than PhaseMin.
|
||||||
|
|
||||||
|
Randomly sets the phase between a range of phases controlled by the parameters. Sets the phase to a random id (Phase = PhaseMin + rnd % PhaseMin-PhaseMax).
|
||||||
|
NOTE: PhaseMax must be greater than PhaseMin.
|
||||||
|
NOTE 2: PLEASE NOTE THAT EACH OF THE PARAM VALUES ARE ACTUAL PHASE NUMBERS NOT THE INVERSE PHASE MASK VALUE.
|
||||||
|
This is commonly used for Spellcasting NPC's who on Aggro may select at random a school of spells to use for the fight. Use this if you have MORE then 3 phases used, otherwise use Action 30.
|
||||||
|
|
||||||
|
---------------------
|
||||||
|
32 = ACTION_T_SUMMON:
|
||||||
|
---------------------
|
||||||
|
Parameter 1: CreatureID - The creature template ID to be summoned. The value here needs to be a valid creature template ID.
|
||||||
|
Parameter 2: Target - The target type defining who the summoned creature will attack. The value in this field needs to be a valid target type as specified in the reference tables below. NOTE: Using target type 0 will cause the summoned creature to not attack anyone.
|
||||||
|
Parameter 3: SummonID - The summon ID from the creature_ai_summons table controlling the position (and spawntime) where the summoned mob should be spawned at.
|
||||||
|
|
||||||
|
Summons creature (param1) to attack target (param2) at location specified by creature_ai_summons (param3).
|
||||||
|
NOTE: Param3 Value is the ID Value used for the entry used in creature_ai_summons for this action. You MUST have an creature_ai_summons entry to use this action.
|
||||||
|
This is commonly used for NPC's who need to Summon a creature at a specific location. (Normally used for complex events)
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
33 = ACTION_T_KILLED_MONSTER:
|
||||||
|
-----------------------------
|
||||||
|
Parameter 1: CreatureID - The creature template ID. The value here must be a valid creature template ID.
|
||||||
|
Parameter 2: Target - The target type defining whom the quest kill count should be given to. The value in this field needs to be a valid target type as specified in the reference tables below.
|
||||||
|
|
||||||
|
When activated, this action will call KilledMonster() function for the player. It can be used to give creature credit for killing a creature. In general if the quest is set to be accompished on different creatures (e.g. "Credit" templates).
|
||||||
|
NOTE: It can be ANY creature including certain quest specific triggers
|
||||||
|
This is commonly used for giving the player Quest Credits for NPC kills (Many NPC's may use the same CreatureID for the Kill Credit)
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
34 = ACTION_T_SET_INST_DATA:
|
||||||
|
----------------------------
|
||||||
|
Parameter 1: Field - The field to change in the instance script. Again, this field needs to be a valid field that has been already defined in the instance's script.
|
||||||
|
Parameter 2: Data - The value to put at that field index.
|
||||||
|
|
||||||
|
Sets data for the instance. Note that this will only work when the creature is inside an instantiable zone that has a valid script (ScriptedInstance) assigned.
|
||||||
|
This is commonly used to link an EventAI script with a existing Script Library C++ Script. You make make things happen like opening doors on specific events that happen.
|
||||||
|
|
||||||
|
------------------------------
|
||||||
|
35 = ACTION_T_SET_INST_DATA64:
|
||||||
|
------------------------------
|
||||||
|
Parameter 1: Field - The field to change in the instance script. Again, this field needs to be a valid field that has been already defined in the instance's script.
|
||||||
|
Parameter 2: Target - The target type to use to get the GUID that will be stored at the field index. The value in this field needs to be a valid target type as specified in the reference tables below.
|
||||||
|
|
||||||
|
Sets GUID (64 bits) data for the instance based on the target. Note that this will only work when the creature is inside an instantiable zone that has a valid script (ScriptedInstance) assigned.
|
||||||
|
Calls ScriptedInstance::SetData64 with field (param1) and data (param2) target's GUID.
|
||||||
|
|
||||||
|
------------------------------
|
||||||
|
36 = ACTION_T_UPDATE_TEMPLATE:
|
||||||
|
------------------------------
|
||||||
|
Parameter 1: TemplateId - The creature template ID. The value here must be a valid creature template ID.
|
||||||
|
Parameter 2: Team - Use model_id from team : Alliance(0) or Horde (1).
|
||||||
|
|
||||||
|
This function temporarily changes creature entry to new entry, display is changed, loot is changed, but AI is not changed. At respawn creature will be reverted to original entry.
|
||||||
|
Changes the creature to a new creature template of (param1) with team = Alliance if (param2) = false or Horde if (param2) = true
|
||||||
|
|
||||||
|
------------------
|
||||||
|
37 = ACTION_T_DIE:
|
||||||
|
------------------
|
||||||
|
Kills the creature
|
||||||
|
This is commonly used if you need to Instakill the creature for one reason or another.
|
||||||
|
|
||||||
|
--------------------------------
|
||||||
|
38 = ACTION_T_ZONE_COMBAT_PULSE:
|
||||||
|
--------------------------------
|
||||||
|
Places all players within the instance into combat with the creature. Only works in combat and only works inside of instances.
|
||||||
|
|
||||||
|
|
||||||
|
=========================================
|
||||||
|
Target Types
|
||||||
|
=========================================
|
||||||
|
Below is the list of current Target types that EventAI can handle.
|
||||||
|
Target types are used by certain actions and may effect actions differently
|
||||||
|
|
||||||
|
(# Internal Name Discription)
|
||||||
|
0 TARGET_T_SELF Self cast
|
||||||
|
1 TARGET_T_HOSTILE Our current target (ie: highest aggro)
|
||||||
|
2 TARGET_T_HOSTILE_SECOND_AGGRO Second highest aggro (generaly used for cleaves and some special attacks)
|
||||||
|
3 TARGET_T_HOSTILE_LAST_AGGRO Dead last on aggro (no idea what this could be used for)
|
||||||
|
4 TARGET_T_HOSTILE_RANDOM Just any random target on our threat list
|
||||||
|
5 TARGET_T_HOSTILE_RANDOM_NOT_TOP Any random target except top threat
|
||||||
|
6 TARGET_T_ACTION_INVOKER Unit who caused this Event to occur (only works for EVENT_T_AGGRO, EVENT_T_KILL, EVENT_T_DEATH, EVENT_T_SPELLHIT, EVENT_T_OOC_LOS, EVENT_T_FRIENDLY_HP)
|
||||||
|
|
||||||
|
=========================================
|
||||||
|
Cast Flags
|
||||||
|
=========================================
|
||||||
|
Below is the list of current Cast Flags that EventAI's spell casting can handle.
|
||||||
|
Cast flags are handled bitwise. Bit 0 is Interrupt Previous, bit 1 is triggered, etc.
|
||||||
|
So for example the number "3" (11 in Binary, selecting first 2 options) would mean that this cast has both CAST_INTURRUPT_PREVIOUS and CAST_TRIGGERED.
|
||||||
|
Another example: the number "5" (101 in Binary, selecting first and third options) would mean that this cast has CAST_INTURRUPT_PREVIOUS and CAST_FORCE_CAST.
|
||||||
|
|
||||||
|
(bit# Decimal Internal Name Discription)
|
||||||
|
0 1 CAST_INTURRUPT_PREVIOUS Interrupts any previous spell casting (basicaly makes sure that this spell goes off)
|
||||||
|
1 2 CAST_TRIGGERED Forces the spell to be instant cast and require no mana/reagents.
|
||||||
|
2 4 CAST_FORCE_CAST Forces spell to cast even if the target is possibly out of range or the creature is possibly out of mana
|
||||||
|
3 8 CAST_NO_MELEE_IF_OOM Prevents creature from entering melee if out of mana or out of range
|
||||||
|
4 16 CAST_FORCE_TARGET_SELF Forces the target to cast this spell on itself
|
||||||
|
5 32 CAST_AURA_NOT_PRESENT Only casts the spell on the target if the target does not have the aura from that spell on itself already.
|
||||||
|
|
||||||
|
NOTE: You can add the numbers in the decimal column to combine flags.
|
||||||
|
For example if you wanted to use CAST_NO_MELEE_IF_OOM(8) and CAST_TRIGGERED(2) you would simply use 10 in the cast flags field (8 + 2 = 10).
|
||||||
|
|
||||||
|
=========================================
|
||||||
|
Event Flags
|
||||||
|
=========================================
|
||||||
|
Below is the list of current Event Flags that EventAI can handle. Event flags are handled bitwise.
|
||||||
|
|
||||||
|
(bit# Decimal Internal Name Discription)
|
||||||
|
0 1 EFLAG_REPEATABLE Event repeats (Does not repeat if this flag is not set)
|
||||||
|
1 2 EFLAG_NORMAL Event occurs in Normal instance difficulty (will not occur in Normal if not set)
|
||||||
|
2 4 EFLAG_HEROIC Event occurs in Heroic instance difficulty (will not occur in Heroic if not set)
|
||||||
|
3 8
|
||||||
|
4 16
|
||||||
|
5 32
|
||||||
|
6 64
|
||||||
|
7 128 EFLAG_DEBUG_ONLY Prevents events from occuring on Release builds. Useful for testing new features.
|
||||||
|
|
||||||
|
NOTE: You can add the numbers in the decimal column to combine flags.
|
||||||
|
|
||||||
|
|
||||||
|
=========================================
|
||||||
|
Basic Structure of creature_ai_texts
|
||||||
|
=========================================
|
||||||
|
Below is a the list of current fields within the texts tables.
|
||||||
|
|
||||||
|
Field_Name Description
|
||||||
|
-----------------------------------------------------------
|
||||||
|
entry This value is mearly an NEGATIVE identifier of the current text number. Required for sql queries. Valid range are -1 to -999999
|
||||||
|
content_default This is the actual text presented in the default language (English).
|
||||||
|
|
||||||
|
content_loc1 This is the actual text presented in the Localization #1 Clients (Korean)
|
||||||
|
content_loc2 This is the actual text presented in the Localization #2 Clients (French)
|
||||||
|
content_loc3 This is the actual text presented in the Localization #3 Clients (German)
|
||||||
|
content_loc4 This is the actual text presented in the Localization #4 Clients (Chinese)
|
||||||
|
content_loc5 This is the actual text presented in the Localization #5 Clients (Taiwanese)
|
||||||
|
content_loc6 This is the actual text presented in the Localization #6 Clients (Spanish)
|
||||||
|
content_loc7 This is the actual text presented in the Localization #7 Clients (Spanish Mexico)
|
||||||
|
content_loc8 This is the actual text presented in the Localization #8 Clients (Russian)
|
||||||
|
|
||||||
|
sound This value is the Sound ID that corresponds to the actual text used.
|
||||||
|
type Variables used to define type of text (Say/Yell/Textemote/Whisper).
|
||||||
|
language This value is the Language that the text is native in.
|
||||||
|
emote Value from enum Emote. Only source of text will play this emote (not target, if target are defined in DoScriptText)
|
||||||
|
comment This is a comment regarding the text entry
|
||||||
|
|
||||||
|
Note: Fields `content_loc1` to `content_loc8` are NULL values by default and are normally handled by seperate localization projects.
|
||||||
|
|
||||||
|
=========================================
|
||||||
|
Text Types (type)
|
||||||
|
=========================================
|
||||||
|
Below is the list of current Text types that texts tables can handle. These were previously seperate Actions in ACID.
|
||||||
|
|
||||||
|
# Internal Name Description
|
||||||
|
-----------------------------------------------------------
|
||||||
|
0 CHAT_TYPE_SAY This type sets the text to be displayed as a Say (Speech Bubble).
|
||||||
|
1 CHAT_TYPE_YELL This type sets the text to be displayed as a Yell (Red Speech Bubble) and usually has a matching Sound ID.
|
||||||
|
2 CHAT_TYPE_TEXT_EMOTE This type sets the text to be displayed as a text emote in orange in the chat log.
|
||||||
|
3 CHAT_TYPE_BOSS_EMOTE This type sets the text to be displayed as a text emote in orange in the chat log (Used only for specific Bosses).
|
||||||
|
4 CHAT_TYPE_WHISPER This type sets the text to be displayed as a whisper to the player in the chat log.
|
||||||
|
5 CHAT_TYPE_BOSS_WHISPER This type sets the text to be displayed as a whisper to the player in the chat log (Used only for specific Bosses).
|
||||||
|
6 CHAT_TYPE_ZONE_YELL Same as CHAT_TYPE_YELL but will display to all players in current zone.
|
||||||
|
|
||||||
|
=========================================
|
||||||
|
Language Types (language)
|
||||||
|
=========================================
|
||||||
|
Below is the list of current Language types that are allowed.
|
||||||
|
This is the Race Language that the text is native to (So it will display properly)
|
||||||
|
|
||||||
|
# Internal Name Description
|
||||||
|
-----------------------------------------------------------
|
||||||
|
0 UNIVERSAL Text in this language is understood by ALL Races.
|
||||||
|
1 ORCISH Text in this language is understood ONLY by Horde Races.
|
||||||
|
2 DARNASSIAN Text in this language is understood ONLY by the Night Elf Race.
|
||||||
|
3 TAURAHE Text in this language is understood ONLY by the Tauren Race.
|
||||||
|
6 DWARVISH Text in this language is understood ONLY by the Dwarf Race.
|
||||||
|
7 COMMON Text in this language is understood ONLY by Alliance Races.
|
||||||
|
8 DEMONIC Text in this language is understood ONLY by the Demon Race (Not Implimented).
|
||||||
|
9 TITAN This language was used by Sargeras to speak with other Titians (Not Implemented).
|
||||||
|
10 THALASSIAN Text in this language is understood ONLY by the Blood Elf Race.
|
||||||
|
11 DRACONIC Text in this language is understood ONLY by the Dragon Race.
|
||||||
|
12 KALIMAG Text will display as Kalimag (not readable by players, language of all elementals)
|
||||||
|
13 GNOMISH Text in this language is understood ONLY by the Gnome Race.
|
||||||
|
14 TROLL Text in this language is understood ONLY by the Troll Race.
|
||||||
|
33 GUTTERSPEAK Text in this language is understood ONLY by the Undead Race.
|
||||||
|
35 DRAENEI Text in this language is understood ONLY by the Draenai Race.
|
||||||
|
36 ZOMBIE (not currently used?)
|
||||||
|
37 GNOMISH BINARY Binary language used by Alliance when drinking Binary Brew
|
||||||
|
38 GOBLIN BINARY Binary language used by Horce when drinking Binary Brew
|
||||||
141
sql/mangos.sql
141
sql/mangos.sql
|
|
@ -22,7 +22,7 @@
|
||||||
DROP TABLE IF EXISTS `db_version`;
|
DROP TABLE IF EXISTS `db_version`;
|
||||||
CREATE TABLE `db_version` (
|
CREATE TABLE `db_version` (
|
||||||
`version` varchar(120) default NULL,
|
`version` varchar(120) default NULL,
|
||||||
`required_7568_01_mangos_spell_proc_event` bit(1) default NULL
|
`required_7627_01_mangos_achievement_criteria_data` bit(1) default NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
@ -36,6 +36,28 @@ INSERT INTO `db_version` VALUES
|
||||||
/*!40000 ALTER TABLE `db_version` ENABLE KEYS */;
|
/*!40000 ALTER TABLE `db_version` ENABLE KEYS */;
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `achievement_criteria_data`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `achievement_criteria_data`;
|
||||||
|
CREATE TABLE `achievement_criteria_data` (
|
||||||
|
`criteria_id` mediumint(8) NOT NULL,
|
||||||
|
`type` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`value1` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`value2` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||||
|
PRIMARY KEY (`criteria_id`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Achievment system';
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Dumping data for table `achievement_criteria_data`
|
||||||
|
--
|
||||||
|
|
||||||
|
LOCK TABLES `achievement_criteria_data` WRITE;
|
||||||
|
/*!40000 ALTER TABLE `achievement_criteria_data` DISABLE KEYS */;
|
||||||
|
/*!40000 ALTER TABLE `achievement_criteria_data` ENABLE KEYS */;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Table structure for table `achievement_reward`
|
-- Table structure for table `achievement_reward`
|
||||||
--
|
--
|
||||||
|
|
@ -50,7 +72,7 @@ CREATE TABLE `achievement_reward` (
|
||||||
`subject` varchar(255) default NULL,
|
`subject` varchar(255) default NULL,
|
||||||
`text` text,
|
`text` text,
|
||||||
PRIMARY KEY (`entry`)
|
PRIMARY KEY (`entry`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System';
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Achievment system';
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Dumping data for table `achievement_reward`
|
-- Dumping data for table `achievement_reward`
|
||||||
|
|
@ -267,7 +289,9 @@ INSERT INTO `command` VALUES
|
||||||
('debug arena',3,'Syntax: .debug arena\r\n\r\nToggle debug mode for arenas. In debug mode GM can start arena with single player.'),
|
('debug arena',3,'Syntax: .debug arena\r\n\r\nToggle debug mode for arenas. In debug mode GM can start arena with single player.'),
|
||||||
('debug bg',3,'Syntax: .debug bg\r\n\r\nToggle debug mode for battlegrounds. In debug mode GM can start battleground with single player.'),
|
('debug bg',3,'Syntax: .debug bg\r\n\r\nToggle debug mode for battlegrounds. In debug mode GM can start battleground with single player.'),
|
||||||
('debug getvalue',3,'Syntax: .debug getvalue #field #isInt\r\n\r\nGet the field #field of the selected creature. If no creature is selected, get the content of your field.\r\n\r\nUse a #isInt of value 1 if the expected field content is an integer.'),
|
('debug getvalue',3,'Syntax: .debug getvalue #field #isInt\r\n\r\nGet the field #field of the selected creature. If no creature is selected, get the content of your field.\r\n\r\nUse a #isInt of value 1 if the expected field content is an integer.'),
|
||||||
('debug playsound',1,'Syntax: .debug playsound #soundid\r\n\r\nPlay sound with #soundid.\r\nSound will be play only for you. Other players do not hear this.\r\nWarning: client may have more 5000 sounds...'),
|
('debug play cinematic',1,'Syntax: .debug play cinematic #cinematicid\r\n\r\nPlay cinematic #cinematicid for you. You stay at place while your mind fly.\r\n'),
|
||||||
|
('debug play movie',1,'Syntax: .debug play movie #movieid\r\n\r\nPlay movie #movieid for you.'),
|
||||||
|
('debug play sound',1,'Syntax: .debug play sound #soundid\r\n\r\nPlay sound with #soundid.\r\nSound will be play only for you. Other players do not hear this.\r\nWarning: client may have more 5000 sounds...'),
|
||||||
('debug setvalue',3,'Syntax: .debug setvalue #field #value #isInt\r\n\r\nSet the field #field of the selected creature with value #value. If no creature is selected, set the content of your field.\r\n\r\nUse a #isInt of value 1 if #value is an integer.'),
|
('debug setvalue',3,'Syntax: .debug setvalue #field #value #isInt\r\n\r\nSet the field #field of the selected creature with value #value. If no creature is selected, set the content of your field.\r\n\r\nUse a #isInt of value 1 if #value is an integer.'),
|
||||||
('debug update',3,'Syntax: .debug update #field #value\r\n\r\nUpdate the field #field of the selected character or creature with value #value.\r\n\r\nIf no #value is provided, display the content of field #field.'),
|
('debug update',3,'Syntax: .debug update #field #value\r\n\r\nUpdate the field #field of the selected character or creature with value #value.\r\n\r\nIf no #value is provided, display the content of field #field.'),
|
||||||
('debug Mod32Value',3,'Syntax: .debug Mod32Value #field #value\r\n\r\nAdd #value to field #field of your character.'),
|
('debug Mod32Value',3,'Syntax: .debug Mod32Value #field #value\r\n\r\nAdd #value to field #field of your character.'),
|
||||||
|
|
@ -441,10 +465,10 @@ INSERT INTO `command` VALUES
|
||||||
('revive',3,'Syntax: .revive\r\n\r\nRevive the selected player. If no player is selected, it will revive you.'),
|
('revive',3,'Syntax: .revive\r\n\r\nRevive the selected player. If no player is selected, it will revive you.'),
|
||||||
('save',0,'Syntax: .save\r\n\r\nSaves your character.'),
|
('save',0,'Syntax: .save\r\n\r\nSaves your character.'),
|
||||||
('saveall',1,'Syntax: .saveall\r\n\r\nSave all characters in game.'),
|
('saveall',1,'Syntax: .saveall\r\n\r\nSave all characters in game.'),
|
||||||
('senditems',3,'Syntax: .senditems #playername "#subject" "#text" itemid1[:count1] itemid2[:count2] ... itemidN[:countN]\r\n\r\nSend a mail to a player. Subject and mail text must be in "". If for itemid not provided related count values then expected 1, if count > max items in stack then items will be send in required amount stacks. All stacks amount in mail limited to 12.'),
|
('send items',3,'Syntax: .send items #playername "#subject" "#text" itemid1[:count1] itemid2[:count2] ... itemidN[:countN]\r\n\r\nSend a mail to a player. Subject and mail text must be in "". If for itemid not provided related count values then expected 1, if count > max items in stack then items will be send in required amount stacks. All stacks amount in mail limited to 12.'),
|
||||||
('sendmail',1,'Syntax: .sendmail #playername "#subject" "#text"\r\n\r\nSend a mail to a player. Subject and mail text must be in "".'),
|
('send mail',1,'Syntax: .send mail #playername "#subject" "#text"\r\n\r\nSend a mail to a player. Subject and mail text must be in "".'),
|
||||||
('sendmoney','3','Syntax: .sendmoney #playername "#subject" "#text" #money\r\n\r\nSend mail with money to a player. Subject and mail text must be in "".'),
|
('send message',3,'Syntax: .send message $playername $message\r\n\r\nSend screen message to player from ADMINISTRATOR.'),
|
||||||
('sendmessage',3,'Syntax: .sendmessage $playername $message\r\n\r\nSend screen message to player from ADMINISTRATOR.'),
|
('send money','3','Syntax: .send money #playername "#subject" "#text" #money\r\n\r\nSend mail with money to a player. Subject and mail text must be in "".'),
|
||||||
('server corpses',2,'Syntax: .server corpses\r\n\r\nTriggering corpses expire check in world.'),
|
('server corpses',2,'Syntax: .server corpses\r\n\r\nTriggering corpses expire check in world.'),
|
||||||
('server exit',4,'Syntax: .server exit\r\n\r\nTerminate mangosd NOW. Exit code 0.'),
|
('server exit',4,'Syntax: .server exit\r\n\r\nTerminate mangosd NOW. Exit code 0.'),
|
||||||
('server info',0,'Syntax: .server info\r\n\r\nDisplay server version and the number of connected players.'),
|
('server info',0,'Syntax: .server info\r\n\r\nDisplay server version and the number of connected players.'),
|
||||||
|
|
@ -918,6 +942,105 @@ LOCK TABLES `disenchant_loot_template` WRITE;
|
||||||
/*!40000 ALTER TABLE `disenchant_loot_template` ENABLE KEYS */;
|
/*!40000 ALTER TABLE `disenchant_loot_template` ENABLE KEYS */;
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `creature_ai_scripts`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `creature_ai_scripts`;
|
||||||
|
CREATE TABLE `creature_ai_scripts` (
|
||||||
|
`id` int(11) unsigned NOT NULL COMMENT 'Identifier' AUTO_INCREMENT,
|
||||||
|
`creature_id` int(11) unsigned NOT NULL default '0' COMMENT 'Creature Template Identifier',
|
||||||
|
`event_type` tinyint(5) unsigned NOT NULL default '0' COMMENT 'Event Type',
|
||||||
|
`event_inverse_phase_mask` int(11) signed NOT NULL default '0' COMMENT 'Mask which phases this event will not trigger in',
|
||||||
|
`event_chance` int(3) unsigned NOT NULL default '100',
|
||||||
|
`event_flags` int(3) unsigned NOT NULL default '0',
|
||||||
|
`event_param1` int(11) signed NOT NULL default '0',
|
||||||
|
`event_param2` int(11) signed NOT NULL default '0',
|
||||||
|
`event_param3` int(11) signed NOT NULL default '0',
|
||||||
|
`event_param4` int(11) signed NOT NULL default '0',
|
||||||
|
`action1_type` tinyint(5) unsigned NOT NULL default '0' COMMENT 'Action Type',
|
||||||
|
`action1_param1` int(11) signed NOT NULL default '0',
|
||||||
|
`action1_param2` int(11) signed NOT NULL default '0',
|
||||||
|
`action1_param3` int(11) signed NOT NULL default '0',
|
||||||
|
`action2_type` tinyint(5) unsigned NOT NULL default '0' COMMENT 'Action Type',
|
||||||
|
`action2_param1` int(11) signed NOT NULL default '0',
|
||||||
|
`action2_param2` int(11) signed NOT NULL default '0',
|
||||||
|
`action2_param3` int(11) signed NOT NULL default '0',
|
||||||
|
`action3_type` tinyint(5) unsigned NOT NULL default '0' COMMENT 'Action Type',
|
||||||
|
`action3_param1` int(11) signed NOT NULL default '0',
|
||||||
|
`action3_param2` int(11) signed NOT NULL default '0',
|
||||||
|
`action3_param3` int(11) signed NOT NULL default '0',
|
||||||
|
`comment` varchar(255) NOT NULL default '' COMMENT 'Event Comment',
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='EventAI Scripts';
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Dumping data for table `creature_ai_scripts`
|
||||||
|
--
|
||||||
|
|
||||||
|
LOCK TABLES `creature_ai_scripts` WRITE;
|
||||||
|
/*!40000 ALTER TABLE `creature_ai_scripts` DISABLE KEYS */;
|
||||||
|
/*!40000 ALTER TABLE `creature_ai_scripts` ENABLE KEYS */;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `creature_ai_summons`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `creature_ai_summons`;
|
||||||
|
CREATE TABLE `creature_ai_summons` (
|
||||||
|
`id` int(11) unsigned NOT NULL COMMENT 'Location Identifier' AUTO_INCREMENT,
|
||||||
|
`position_x` float NOT NULL default '0',
|
||||||
|
`position_y` float NOT NULL default '0',
|
||||||
|
`position_z` float NOT NULL default '0',
|
||||||
|
`orientation` float NOT NULL default '0',
|
||||||
|
`spawntimesecs` int(11) unsigned NOT NULL default '120',
|
||||||
|
`comment` varchar(255) NOT NULL default '' COMMENT 'Summon Comment',
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='EventAI Summoning Locations';
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Dumping data for table `creature_ai_summons`
|
||||||
|
--
|
||||||
|
|
||||||
|
LOCK TABLES `creature_ai_summons` WRITE;
|
||||||
|
/*!40000 ALTER TABLE `creature_ai_summons` DISABLE KEYS */;
|
||||||
|
/*!40000 ALTER TABLE `creature_ai_summons` ENABLE KEYS */;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `creature_ai_texts`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `creature_ai_texts`;
|
||||||
|
CREATE TABLE `creature_ai_texts` (
|
||||||
|
`entry` mediumint(8) NOT NULL,
|
||||||
|
`content_default` text NOT NULL,
|
||||||
|
`content_loc1` text,
|
||||||
|
`content_loc2` text,
|
||||||
|
`content_loc3` text,
|
||||||
|
`content_loc4` text,
|
||||||
|
`content_loc5` text,
|
||||||
|
`content_loc6` text,
|
||||||
|
`content_loc7` text,
|
||||||
|
`content_loc8` text,
|
||||||
|
`sound` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`type` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`language` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`emote` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`comment` text,
|
||||||
|
PRIMARY KEY (`entry`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Script Texts';
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Dumping data for table `creature_ai_texts`
|
||||||
|
--
|
||||||
|
|
||||||
|
LOCK TABLES `creature_ai_texts` WRITE;
|
||||||
|
/*!40000 ALTER TABLE `creature_ai_texts` DISABLE KEYS */;
|
||||||
|
/*!40000 ALTER TABLE `creature_ai_texts` ENABLE KEYS */;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Table structure for table `event_scripts`
|
-- Table structure for table `event_scripts`
|
||||||
--
|
--
|
||||||
|
|
@ -2924,7 +3047,9 @@ INSERT INTO `mangos_string` VALUES
|
||||||
(1124,'Wrong pet type',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(1124,'Wrong pet type',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(1125,'Your pet learned all talents',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(1125,'Your pet learned all talents',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(1126,'Your pet talents have been reset.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
(1126,'Your pet talents have been reset.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
(1127,'Talents of %s\'s pet reset.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
(1127,'Talents of %s\'s pet reset.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
|
(1200,'You try to view cinemitic %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
|
(1201,'You try to view movie %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
||||||
/*!40000 ALTER TABLE `mangos_string` ENABLE KEYS */;
|
/*!40000 ALTER TABLE `mangos_string` ENABLE KEYS */;
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
|
|
||||||
|
|
|
||||||
9
sql/updates/7615_01_mangos_command.sql
Normal file
9
sql/updates/7615_01_mangos_command.sql
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_7568_01_mangos_spell_proc_event required_7615_01_mangos_command bit;
|
||||||
|
|
||||||
|
DELETE FROM `command` WHERE `name` IN ('senditems','sendmail','sendmoney','sendmessage','send items','send mail','send money','send message');
|
||||||
|
|
||||||
|
INSERT INTO `command` VALUES
|
||||||
|
('send items',3,'Syntax: .send items #playername "#subject" "#text" itemid1[:count1] itemid2[:count2] ... itemidN[:countN]\r\n\r\nSend a mail to a player. Subject and mail text must be in "". If for itemid not provided related count values then expected 1, if count > max items in stack then items will be send in required amount stacks. All stacks amount in mail limited to 12.'),
|
||||||
|
('send mail',1,'Syntax: .send mail #playername "#subject" "#text"\r\n\r\nSend a mail to a player. Subject and mail text must be in "".'),
|
||||||
|
('send message',3,'Syntax: .send message $playername $message\r\n\r\nSend screen message to player from ADMINISTRATOR.'),
|
||||||
|
('send money','3','Syntax: .send money #playername "#subject" "#text" #money\r\n\r\nSend mail with money to a player. Subject and mail text must be in "".');
|
||||||
6
sql/updates/7616_01_mangos_mangos_string.sql
Normal file
6
sql/updates/7616_01_mangos_mangos_string.sql
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_7615_01_mangos_command required_7616_01_mangos_mangos_string bit;
|
||||||
|
|
||||||
|
DELETE FROM mangos_string WHERE entry IN(1200,1201);
|
||||||
|
INSERT INTO mangos_string VALUES
|
||||||
|
(1200,'You try to view cinemitic %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||||
|
(1201,'You try to view movie %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
||||||
8
sql/updates/7616_02_mangos_command.sql
Normal file
8
sql/updates/7616_02_mangos_command.sql
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_7616_01_mangos_mangos_string required_7616_02_mangos_command bit;
|
||||||
|
|
||||||
|
DELETE FROM `command` WHERE `name` IN ('debug playsound','debug play sound','debug play cinematic','debug play movie');
|
||||||
|
|
||||||
|
INSERT INTO `command` VALUES
|
||||||
|
('debug play cinematic',1,'Syntax: .debug play cinematic #cinematicid\r\n\r\nPlay cinematic #cinematicid for you. You stay at place while your mind fly.\r\n'),
|
||||||
|
('debug play movie',1,'Syntax: .debug play movie #movieid\r\n\r\nPlay movie #movieid for you.'),
|
||||||
|
('debug play sound',1,'Syntax: .debug play sound #soundid\r\n\r\nPlay sound with #soundid.\r\nSound will be play only for you. Other players do not hear this.\r\nWarning: client may have more 5000 sounds...');
|
||||||
30
sql/updates/7622_01_mangos_creature_ai_scripts.sql
Normal file
30
sql/updates/7622_01_mangos_creature_ai_scripts.sql
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_7616_02_mangos_command required_7622_01_mangos_creature_ai_scripts bit;
|
||||||
|
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `creature_ai_scripts`;
|
||||||
|
CREATE TABLE `creature_ai_scripts` (
|
||||||
|
`id` int(11) unsigned NOT NULL COMMENT 'Identifier' AUTO_INCREMENT,
|
||||||
|
`creature_id` int(11) unsigned NOT NULL default '0' COMMENT 'Creature Template Identifier',
|
||||||
|
`event_type` tinyint(5) unsigned NOT NULL default '0' COMMENT 'Event Type',
|
||||||
|
`event_inverse_phase_mask` int(11) signed NOT NULL default '0' COMMENT 'Mask which phases this event will not trigger in',
|
||||||
|
`event_chance` int(3) unsigned NOT NULL default '100',
|
||||||
|
`event_flags` int(3) unsigned NOT NULL default '0',
|
||||||
|
`event_param1` int(11) signed NOT NULL default '0',
|
||||||
|
`event_param2` int(11) signed NOT NULL default '0',
|
||||||
|
`event_param3` int(11) signed NOT NULL default '0',
|
||||||
|
`event_param4` int(11) signed NOT NULL default '0',
|
||||||
|
`action1_type` tinyint(5) unsigned NOT NULL default '0' COMMENT 'Action Type',
|
||||||
|
`action1_param1` int(11) signed NOT NULL default '0',
|
||||||
|
`action1_param2` int(11) signed NOT NULL default '0',
|
||||||
|
`action1_param3` int(11) signed NOT NULL default '0',
|
||||||
|
`action2_type` tinyint(5) unsigned NOT NULL default '0' COMMENT 'Action Type',
|
||||||
|
`action2_param1` int(11) signed NOT NULL default '0',
|
||||||
|
`action2_param2` int(11) signed NOT NULL default '0',
|
||||||
|
`action2_param3` int(11) signed NOT NULL default '0',
|
||||||
|
`action3_type` tinyint(5) unsigned NOT NULL default '0' COMMENT 'Action Type',
|
||||||
|
`action3_param1` int(11) signed NOT NULL default '0',
|
||||||
|
`action3_param2` int(11) signed NOT NULL default '0',
|
||||||
|
`action3_param3` int(11) signed NOT NULL default '0',
|
||||||
|
`comment` varchar(255) NOT NULL default '' COMMENT 'Event Comment',
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='EventAI Scripts';
|
||||||
14
sql/updates/7622_02_mangos_creature_ai_summons.sql
Normal file
14
sql/updates/7622_02_mangos_creature_ai_summons.sql
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_7622_01_mangos_creature_ai_scripts required_7622_02_mangos_creature_ai_summons bit;
|
||||||
|
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `creature_ai_summons`;
|
||||||
|
CREATE TABLE `creature_ai_summons` (
|
||||||
|
`id` int(11) unsigned NOT NULL COMMENT 'Location Identifier' AUTO_INCREMENT,
|
||||||
|
`position_x` float NOT NULL default '0',
|
||||||
|
`position_y` float NOT NULL default '0',
|
||||||
|
`position_z` float NOT NULL default '0',
|
||||||
|
`orientation` float NOT NULL default '0',
|
||||||
|
`spawntimesecs` int(11) unsigned NOT NULL default '120',
|
||||||
|
`comment` varchar(255) NOT NULL default '' COMMENT 'Summon Comment',
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='EventAI Summoning Locations';
|
||||||
22
sql/updates/7622_03_mangos_creature_ai_texts.sql
Normal file
22
sql/updates/7622_03_mangos_creature_ai_texts.sql
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_7622_02_mangos_creature_ai_summons required_7622_03_mangos_creature_ai_texts bit;
|
||||||
|
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `creature_ai_texts`;
|
||||||
|
CREATE TABLE `creature_ai_texts` (
|
||||||
|
`entry` mediumint(8) NOT NULL,
|
||||||
|
`content_default` text NOT NULL,
|
||||||
|
`content_loc1` text,
|
||||||
|
`content_loc2` text,
|
||||||
|
`content_loc3` text,
|
||||||
|
`content_loc4` text,
|
||||||
|
`content_loc5` text,
|
||||||
|
`content_loc6` text,
|
||||||
|
`content_loc7` text,
|
||||||
|
`content_loc8` text,
|
||||||
|
`sound` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`type` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`language` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`emote` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`comment` text,
|
||||||
|
PRIMARY KEY (`entry`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Script Texts';
|
||||||
10
sql/updates/7627_01_mangos_achievement_criteria_data.sql
Normal file
10
sql/updates/7627_01_mangos_achievement_criteria_data.sql
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_7622_03_mangos_creature_ai_texts required_7627_01_mangos_achievement_criteria_data bit;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `achievement_criteria_data`;
|
||||||
|
CREATE TABLE `achievement_criteria_data` (
|
||||||
|
`criteria_id` mediumint(8) NOT NULL,
|
||||||
|
`type` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`value1` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`value2` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||||
|
PRIMARY KEY (`criteria_id`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Achievment system';
|
||||||
|
|
@ -211,6 +211,13 @@ pkgdata_DATA = \
|
||||||
7560_01_mangos_gameobject_template.sql \
|
7560_01_mangos_gameobject_template.sql \
|
||||||
7565_01_mangos_mangos_string.sql \
|
7565_01_mangos_mangos_string.sql \
|
||||||
7568_01_mangos_spell_proc_event.sql \
|
7568_01_mangos_spell_proc_event.sql \
|
||||||
|
7615_01_mangos_command.sql \
|
||||||
|
7616_01_mangos_mangos_string.sql \
|
||||||
|
7616_02_mangos_command.sql \
|
||||||
|
7622_01_mangos_creature_ai_scripts.sql \
|
||||||
|
7622_02_mangos_creature_ai_summons.sql \
|
||||||
|
7622_03_mangos_creature_ai_texts.sql \
|
||||||
|
7627_01_mangos_achievement_criteria_data.sql \
|
||||||
README
|
README
|
||||||
|
|
||||||
## Additional files to include when running 'make dist'
|
## Additional files to include when running 'make dist'
|
||||||
|
|
@ -402,4 +409,11 @@ EXTRA_DIST = \
|
||||||
7560_01_mangos_gameobject_template.sql \
|
7560_01_mangos_gameobject_template.sql \
|
||||||
7565_01_mangos_mangos_string.sql \
|
7565_01_mangos_mangos_string.sql \
|
||||||
7568_01_mangos_spell_proc_event.sql \
|
7568_01_mangos_spell_proc_event.sql \
|
||||||
|
7615_01_mangos_command.sql \
|
||||||
|
7616_01_mangos_mangos_string.sql \
|
||||||
|
7616_02_mangos_command.sql \
|
||||||
|
7622_01_mangos_creature_ai_scripts.sql \
|
||||||
|
7622_02_mangos_creature_ai_summons.sql \
|
||||||
|
7622_03_mangos_creature_ai_texts.sql \
|
||||||
|
7627_01_mangos_achievement_criteria_data.sql \
|
||||||
README
|
README
|
||||||
|
|
|
||||||
|
|
@ -37,56 +37,6 @@
|
||||||
|
|
||||||
INSTANTIATE_SINGLETON_1(AchievementGlobalMgr);
|
INSTANTIATE_SINGLETON_1(AchievementGlobalMgr);
|
||||||
|
|
||||||
const CriteriaCastSpellRequirement AchievementGlobalMgr::m_criteriaCastSpellRequirements[CRITERIA_CAST_SPELL_REQ_COUNT] =
|
|
||||||
{
|
|
||||||
{5272, 3057, 0, 0},
|
|
||||||
{5273, 2784, 0, 0},
|
|
||||||
{5752, 9099, 0, 0},
|
|
||||||
{5753, 8403, 0, 0},
|
|
||||||
{5772, 0, 0, RACE_GNOME},
|
|
||||||
{5774, 0, 0, RACE_BLOODELF},
|
|
||||||
{5775, 0, 0, RACE_DRAENEI},
|
|
||||||
{5776, 0, 0, RACE_DWARF},
|
|
||||||
{5777, 0, 0, RACE_HUMAN},
|
|
||||||
{5778, 0, 0, RACE_NIGHTELF},
|
|
||||||
{5779, 0, 0, RACE_ORC},
|
|
||||||
{5780, 0, 0, RACE_TAUREN},
|
|
||||||
{5781, 0, 0, RACE_TROLL},
|
|
||||||
{5782, 0, 0, RACE_UNDEAD_PLAYER},
|
|
||||||
{6225, 5661, 0, 0},
|
|
||||||
{6226, 26044, 0, 0},
|
|
||||||
{6228, 739, 0, 0},
|
|
||||||
{6229, 927, 0, 0},
|
|
||||||
{6230, 1444, 0, 0},
|
|
||||||
{6231, 8140, 0, 0},
|
|
||||||
{6232, 5489, 0, 0},
|
|
||||||
{6233,12336, 0, 0},
|
|
||||||
{6234, 1351, 0, 0},
|
|
||||||
{6235, 5484, 0, 0},
|
|
||||||
{6236, 1182, 0, 0},
|
|
||||||
{6237, 0, CLASS_DEATH_KNIGHT, RACE_ORC},
|
|
||||||
{6238, 0, CLASS_WARRIOR, RACE_HUMAN},
|
|
||||||
{6239, 0, CLASS_SHAMAN, RACE_TAUREN},
|
|
||||||
{6240, 0, CLASS_DRUID, RACE_NIGHTELF},
|
|
||||||
{6241, 0, CLASS_ROGUE, RACE_UNDEAD_PLAYER},
|
|
||||||
{6242, 0, CLASS_HUNTER, RACE_TROLL},
|
|
||||||
{6243, 0, CLASS_MAGE, RACE_GNOME},
|
|
||||||
{6244, 0, CLASS_PALADIN, RACE_DWARF},
|
|
||||||
{6245, 0, CLASS_WARLOCK, RACE_BLOODELF},
|
|
||||||
{6246, 0, CLASS_PRIEST, RACE_DRAENEI},
|
|
||||||
{6312, 0, CLASS_WARLOCK, RACE_GNOME},
|
|
||||||
{6313, 0, CLASS_DEATH_KNIGHT, RACE_HUMAN},
|
|
||||||
{6314, 0, CLASS_PRIEST, RACE_NIGHTELF},
|
|
||||||
{6315, 0, CLASS_SHAMAN, RACE_ORC},
|
|
||||||
{6316, 0, CLASS_DRUID, RACE_TAUREN},
|
|
||||||
{6317, 0, CLASS_ROGUE, RACE_TROLL},
|
|
||||||
{6318, 0, CLASS_WARRIOR, RACE_UNDEAD_PLAYER},
|
|
||||||
{6319, 0, CLASS_MAGE, RACE_BLOODELF},
|
|
||||||
{6320, 0, CLASS_PALADIN, RACE_DRAENEI},
|
|
||||||
{6321, 0, CLASS_HUNTER, RACE_DWARF},
|
|
||||||
{6662, 31261, 0, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace MaNGOS
|
namespace MaNGOS
|
||||||
{
|
{
|
||||||
class AchievementChatBuilder
|
class AchievementChatBuilder
|
||||||
|
|
@ -117,6 +67,114 @@ namespace MaNGOS
|
||||||
};
|
};
|
||||||
} // namespace MaNGOS
|
} // namespace MaNGOS
|
||||||
|
|
||||||
|
|
||||||
|
bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
|
||||||
|
{
|
||||||
|
if(dataType >= MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb( "Table `achievement_criteria_data` for criteria (Entry: %u) have wrong data type (%u), ignore.", criteria->ID,dataType);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(criteria->requiredType)
|
||||||
|
{
|
||||||
|
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
|
||||||
|
switch(dataType)
|
||||||
|
{
|
||||||
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE:
|
||||||
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE:
|
||||||
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_CLASS_RACE:
|
||||||
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sLog.outErrorDb( "Table `achievement_criteria_data` for criteria (Entry: %u Type: %u) have wrong data type (%u), ignore.", criteria->ID, criteria->requiredType,dataType);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sLog.outErrorDb( "Table `achievement_criteria_data` have data for not supported criteria type (Entry: %u Type: %u), ignore.", criteria->ID, criteria->requiredType);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(dataType)
|
||||||
|
{
|
||||||
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE:
|
||||||
|
return true;
|
||||||
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE:
|
||||||
|
if(!creature.id || !objmgr.GetCreatureTemplate(creature.id))
|
||||||
|
{
|
||||||
|
sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE (%u) have not existed creature id in value1 (%u), ignore.",
|
||||||
|
criteria->ID, criteria->requiredType,dataType,creature.id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_CLASS_RACE:
|
||||||
|
if(!classRace.class_id && !classRace.race_id)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_CLASS_RACE (%u) must have not 0 in one from value fields, ignore.",
|
||||||
|
criteria->ID, criteria->requiredType,dataType);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(classRace.class_id && ((1 << (classRace.class_id-1)) & CLASSMASK_ALL_PLAYABLE)==0)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE (%u) have not existed class in value1 (%u), ignore.",
|
||||||
|
criteria->ID, criteria->requiredType,dataType,classRace.class_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(classRace.race_id && ((1 << (classRace.race_id-1)) & RACEMASK_ALL_PLAYABLE)==0)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE (%u) have not existed race in value2 (%u), ignore.",
|
||||||
|
criteria->ID, criteria->requiredType,dataType,classRace.race_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH:
|
||||||
|
if(health.percent < 1 || health.percent > 100)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH (%u) have prong percent value in value1 (%u), ignore.",
|
||||||
|
criteria->ID, criteria->requiredType,dataType,health.percent);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) have data for not supported data type (%u), ignore.", criteria->ID, criteria->requiredType,dataType);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AchievementCriteriaData::Meets( Unit const* target ) const
|
||||||
|
{
|
||||||
|
if (!target)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch(dataType)
|
||||||
|
{
|
||||||
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE:
|
||||||
|
return true;
|
||||||
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE:
|
||||||
|
if (target->GetTypeId()!=TYPEID_UNIT)
|
||||||
|
return false;
|
||||||
|
if (target->GetEntry() != creature.id)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_CLASS_RACE:
|
||||||
|
if (target->GetTypeId()!=TYPEID_PLAYER)
|
||||||
|
return false;
|
||||||
|
if(classRace.class_id && classRace.class_id != ((Player*)target)->getClass())
|
||||||
|
return false;
|
||||||
|
if(classRace.race_id && classRace.race_id != ((Player*)target)->getRace())
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
case ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH:
|
||||||
|
if (target->GetTypeId()!=TYPEID_PLAYER)
|
||||||
|
return false;
|
||||||
|
return target->GetHealth()*100 <= health.percent*target->GetMaxHealth();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
AchievementMgr::AchievementMgr(Player *player)
|
AchievementMgr::AchievementMgr(Player *player)
|
||||||
{
|
{
|
||||||
m_player = player;
|
m_player = player;
|
||||||
|
|
@ -884,25 +942,20 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
||||||
break;
|
break;
|
||||||
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
|
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
|
||||||
{
|
{
|
||||||
|
if (!miscvalue1)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!miscvalue1 || miscvalue1 != achievementCriteria->cast_spell.spellID)
|
if (!miscvalue1 || miscvalue1 != achievementCriteria->cast_spell.spellID)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// those requirements couldn't be found in the dbc
|
// those requirements couldn't be found in the dbc
|
||||||
if (CriteriaCastSpellRequirement const* requirement = AchievementGlobalMgr::GetCriteriaCastSpellRequirement(achievementCriteria))
|
AchievementCriteriaData const* data = achievementmgr.GetCriteriaData(achievementCriteria);
|
||||||
{
|
if(!data)
|
||||||
if (!unit)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (requirement->creatureEntry && unit->GetEntry() != requirement->creatureEntry)
|
if(!data->Meets(unit))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (requirement->playerRace && (unit->GetTypeId() != TYPEID_PLAYER || unit->getRace()!=requirement->playerRace))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (requirement->playerClass && (unit->GetTypeId() != TYPEID_PLAYER || unit->getClass()!=requirement->playerClass))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
|
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1107,8 +1160,7 @@ void AchievementMgr::CompletedCriteria(AchievementCriteriaEntry const* criteria,
|
||||||
if (m_completedAchievements.find(achievement->ID)!=m_completedAchievements.end())
|
if (m_completedAchievements.find(achievement->ID)!=m_completedAchievements.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((criteria->referredAchievement==achievement->ID && (criteria->completionFlag & ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL)) ||
|
if (IsCompletedAchievement(achievement))
|
||||||
IsCompletedAchievement(achievement))
|
|
||||||
CompletedAchievement(achievement);
|
CompletedAchievement(achievement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1138,13 +1190,6 @@ bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry)
|
||||||
else
|
else
|
||||||
completed_all = false;
|
completed_all = false;
|
||||||
|
|
||||||
if(achievmentForTestId == entry->ID) // not referenced achievement
|
|
||||||
{
|
|
||||||
// completed as single req. criteria
|
|
||||||
if(completed && criteria->completionFlag & ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// completed as have req. count of completed criterias
|
// completed as have req. count of completed criterias
|
||||||
if(achievmentForTestCount > 0 && achievmentForTestCount <= count)
|
if(achievmentForTestCount > 0 && achievmentForTestCount <= count)
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1396,6 +1441,72 @@ void AchievementGlobalMgr::LoadAchievementReferenceList()
|
||||||
sLog.outString(">> Loaded %u achievement references.",count);
|
sLog.outString(">> Loaded %u achievement references.",count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AchievementGlobalMgr::LoadAchievementCriteriaData()
|
||||||
|
{
|
||||||
|
m_criteriaDataMap.clear(); // need for reload case
|
||||||
|
|
||||||
|
QueryResult *result = WorldDatabase.Query("SELECT criteria_id, type, value1, value2 FROM achievement_criteria_data");
|
||||||
|
|
||||||
|
if(!result)
|
||||||
|
{
|
||||||
|
barGoLink bar(1);
|
||||||
|
bar.step();
|
||||||
|
|
||||||
|
sLog.outString();
|
||||||
|
sLog.outString(">> Loaded 0 additional achievement criteria data. DB table `achievement_criteria_data` is empty.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 count = 0;
|
||||||
|
barGoLink bar(result->GetRowCount());
|
||||||
|
do
|
||||||
|
{
|
||||||
|
bar.step();
|
||||||
|
Field *fields = result->Fetch();
|
||||||
|
uint32 criteria_id = fields[0].GetUInt32();
|
||||||
|
|
||||||
|
AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(criteria_id);
|
||||||
|
|
||||||
|
if (!criteria)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb( "Table `achievement_criteria_data` have data for not existed criteria (Entry: %u), ignore.", criteria_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AchievementCriteriaData data(fields[1].GetUInt32(),fields[2].GetUInt32(),fields[3].GetUInt32());
|
||||||
|
|
||||||
|
if(!data.IsValid(criteria))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
m_criteriaDataMap[criteria_id] = data;
|
||||||
|
++count;
|
||||||
|
} while(result->NextRow());
|
||||||
|
|
||||||
|
delete result;
|
||||||
|
|
||||||
|
// post loading checks
|
||||||
|
for (uint32 entryId = 0; entryId < sAchievementCriteriaStore.GetNumRows(); ++entryId)
|
||||||
|
{
|
||||||
|
AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId);
|
||||||
|
if(!criteria)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch(criteria->requiredType)
|
||||||
|
{
|
||||||
|
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
|
||||||
|
if(!GetCriteriaData(criteria))
|
||||||
|
sLog.outErrorDb( "Table `achievement_criteria_data` not have expected data for for criteria (Entry: %u Type: %u).", criteria->ID, criteria->requiredType);
|
||||||
|
break;
|
||||||
|
default: // unexpected case processed in IsValid check
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sLog.outString();
|
||||||
|
sLog.outString(">> Loaded %u additional achievement criteria data.",count);
|
||||||
|
}
|
||||||
|
|
||||||
void AchievementGlobalMgr::LoadCompletedAchievements()
|
void AchievementGlobalMgr::LoadCompletedAchievements()
|
||||||
{
|
{
|
||||||
QueryResult *result = CharacterDatabase.Query("SELECT achievement FROM character_achievement GROUP BY achievement");
|
QueryResult *result = CharacterDatabase.Query("SELECT achievement FROM character_achievement GROUP BY achievement");
|
||||||
|
|
@ -1442,6 +1553,7 @@ void AchievementGlobalMgr::LoadRewards()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 count = 0;
|
||||||
barGoLink bar(result->GetRowCount());
|
barGoLink bar(result->GetRowCount());
|
||||||
|
|
||||||
do
|
do
|
||||||
|
|
@ -1525,13 +1637,14 @@ void AchievementGlobalMgr::LoadRewards()
|
||||||
}
|
}
|
||||||
|
|
||||||
m_achievementRewards[entry] = reward;
|
m_achievementRewards[entry] = reward;
|
||||||
|
++count;
|
||||||
|
|
||||||
} while (result->NextRow());
|
} while (result->NextRow());
|
||||||
|
|
||||||
delete result;
|
delete result;
|
||||||
|
|
||||||
sLog.outString();
|
sLog.outString();
|
||||||
sLog.outString( ">> Loaded %lu achievement reward locale strings", (unsigned long)m_achievementRewardLocales.size() );
|
sLog.outString( ">> Loaded %u achievement rewards", count );
|
||||||
}
|
}
|
||||||
|
|
||||||
void AchievementGlobalMgr::LoadRewardLocales()
|
void AchievementGlobalMgr::LoadRewardLocales()
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,6 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#define CRITERIA_CAST_SPELL_REQ_COUNT 46
|
|
||||||
#define ACHIEVEMENT_REWARD_COUNT 57
|
|
||||||
|
|
||||||
typedef std::list<AchievementCriteriaEntry const*> AchievementCriteriaEntryList;
|
typedef std::list<AchievementCriteriaEntry const*> AchievementCriteriaEntryList;
|
||||||
typedef std::list<AchievementEntry const*> AchievementEntryList;
|
typedef std::list<AchievementEntry const*> AchievementEntryList;
|
||||||
|
|
||||||
|
|
@ -43,14 +40,66 @@ struct CriteriaProgress
|
||||||
bool changed;
|
bool changed;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CriteriaCastSpellRequirement
|
enum AchievementCriteriaDataType
|
||||||
{
|
{ // value1 value2 for the Condition enumed
|
||||||
uint32 achievementCriteriaId;
|
ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE = 0, // 0 0
|
||||||
uint32 creatureEntry;
|
ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE = 1, // creature_id
|
||||||
uint8 playerClass;
|
ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_CLASS_RACE = 2, // class_id race_id
|
||||||
uint8 playerRace;
|
ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH = 3, // health_percent
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 4 // maximum value in AchievementCriteriaDataType enum
|
||||||
|
|
||||||
|
class Unit;
|
||||||
|
|
||||||
|
struct AchievementCriteriaData
|
||||||
|
{
|
||||||
|
AchievementCriteriaDataType dataType;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
// ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 id;
|
||||||
|
} creature;
|
||||||
|
// ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_CLASS_RACE
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 class_id;
|
||||||
|
uint32 race_id;
|
||||||
|
} classRace;
|
||||||
|
// ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 percent;
|
||||||
|
} health;
|
||||||
|
// ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 value1;
|
||||||
|
uint32 value2;
|
||||||
|
} raw;
|
||||||
|
};
|
||||||
|
|
||||||
|
AchievementCriteriaData() : dataType(ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE)
|
||||||
|
{
|
||||||
|
raw.value1 = 0;
|
||||||
|
raw.value2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
AchievementCriteriaData(uint32 _dataType, uint32 _value1, uint32 _value2) : dataType(AchievementCriteriaDataType(_dataType))
|
||||||
|
{
|
||||||
|
raw.value1 = _value1;
|
||||||
|
raw.value2 = _value2;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsValid(AchievementCriteriaEntry const* criteria);
|
||||||
|
// Checks correctness of values
|
||||||
|
bool Meets(Unit const* target) const;// Checks if the target meets the requirement
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::map<uint32,AchievementCriteriaData> AchievementCriteriaDataMap;
|
||||||
|
|
||||||
struct AchievementReward
|
struct AchievementReward
|
||||||
{
|
{
|
||||||
uint32 titleId[2];
|
uint32 titleId[2];
|
||||||
|
|
@ -145,13 +194,10 @@ class AchievementGlobalMgr
|
||||||
return iter!=m_achievementRewardLocales.end() ? &iter->second : NULL;
|
return iter!=m_achievementRewardLocales.end() ? &iter->second : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CriteriaCastSpellRequirement const * GetCriteriaCastSpellRequirement(AchievementCriteriaEntry const *achievementCriteria)
|
AchievementCriteriaData const* GetCriteriaData(AchievementCriteriaEntry const *achievementCriteria)
|
||||||
{
|
{
|
||||||
for (uint32 i=0; i < CRITERIA_CAST_SPELL_REQ_COUNT; ++i)
|
AchievementCriteriaDataMap::const_iterator iter = m_criteriaDataMap.find(achievementCriteria->ID);
|
||||||
if (m_criteriaCastSpellRequirements[i].achievementCriteriaId == achievementCriteria->ID)
|
return iter!=m_criteriaDataMap.end() ? &iter->second : NULL;
|
||||||
return &m_criteriaCastSpellRequirements[i];
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsRealmCompleted(AchievementEntry const* achievement) const
|
bool IsRealmCompleted(AchievementEntry const* achievement) const
|
||||||
|
|
@ -165,12 +211,13 @@ class AchievementGlobalMgr
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadAchievementCriteriaList();
|
void LoadAchievementCriteriaList();
|
||||||
|
void LoadAchievementCriteriaData();
|
||||||
void LoadAchievementReferenceList();
|
void LoadAchievementReferenceList();
|
||||||
void LoadCompletedAchievements();
|
void LoadCompletedAchievements();
|
||||||
void LoadRewards();
|
void LoadRewards();
|
||||||
void LoadRewardLocales();
|
void LoadRewardLocales();
|
||||||
private:
|
private:
|
||||||
static const CriteriaCastSpellRequirement m_criteriaCastSpellRequirements[];
|
AchievementCriteriaDataMap m_criteriaDataMap;
|
||||||
|
|
||||||
// store achievement criterias by type to speed up lookup
|
// store achievement criterias by type to speed up lookup
|
||||||
AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL];
|
AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL];
|
||||||
|
|
|
||||||
|
|
@ -204,41 +204,63 @@ void WorldSession::HandleBattleGroundPlayerPositionsOpcode( WorldPacket & /*recv
|
||||||
if(!bg) // can't be received if player not in battleground
|
if(!bg) // can't be received if player not in battleground
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(bg->GetTypeID() == BATTLEGROUND_WS)
|
switch( bg->GetTypeID() )
|
||||||
{
|
{
|
||||||
uint32 count1 = 0;
|
case BATTLEGROUND_WS:
|
||||||
uint32 count2 = 0;
|
{
|
||||||
|
uint32 count1 = 0; //always constant zero?
|
||||||
|
uint32 count2 = 0; //count of next fields
|
||||||
|
|
||||||
Player *ap = objmgr.GetPlayer(((BattleGroundWS*)bg)->GetAllianceFlagPickerGUID());
|
Player *ali_plr = objmgr.GetPlayer(((BattleGroundWS*)bg)->GetAllianceFlagPickerGUID());
|
||||||
if(ap) ++count2;
|
if( ali_plr )
|
||||||
|
++count2;
|
||||||
|
|
||||||
Player *hp = objmgr.GetPlayer(((BattleGroundWS*)bg)->GetHordeFlagPickerGUID());
|
Player *horde_plr = objmgr.GetPlayer(((BattleGroundWS*)bg)->GetHordeFlagPickerGUID());
|
||||||
if(hp) ++count2;
|
if( horde_plr )
|
||||||
|
++count2;
|
||||||
|
|
||||||
WorldPacket data(MSG_BATTLEGROUND_PLAYER_POSITIONS, (4+4+16*count1+16*count2));
|
WorldPacket data(MSG_BATTLEGROUND_PLAYER_POSITIONS, (4+4+16*count1+16*count2));
|
||||||
data << count1; // alliance flag holders count
|
data << count1; // alliance flag holders count - obsolete, now always 0
|
||||||
/*for(uint8 i = 0; i < count1; i++)
|
/*for(uint8 i = 0; i < count1; i++)
|
||||||
{
|
{
|
||||||
data << uint64(0); // guid
|
data << uint64(0); // guid
|
||||||
data << (float)0; // x
|
data << (float)0; // x
|
||||||
data << (float)0; // y
|
data << (float)0; // y
|
||||||
}*/
|
}*/
|
||||||
data << count2; // horde flag holders count
|
data << count2; // horde flag holders count - obsolete, now count of next fields
|
||||||
if(ap)
|
if( ali_plr )
|
||||||
{
|
{
|
||||||
data << (uint64)ap->GetGUID();
|
data << (uint64)ali_plr->GetGUID();
|
||||||
data << (float)ap->GetPositionX();
|
data << (float)ali_plr->GetPositionX();
|
||||||
data << (float)ap->GetPositionY();
|
data << (float)ali_plr->GetPositionY();
|
||||||
}
|
}
|
||||||
if(hp)
|
if( horde_plr )
|
||||||
{
|
{
|
||||||
data << (uint64)hp->GetGUID();
|
data << (uint64)horde_plr->GetGUID();
|
||||||
data << (float)hp->GetPositionX();
|
data << (float)horde_plr->GetPositionX();
|
||||||
data << (float)hp->GetPositionY();
|
data << (float)horde_plr->GetPositionY();
|
||||||
}
|
}
|
||||||
|
|
||||||
SendPacket(&data);
|
SendPacket(&data);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case BATTLEGROUND_EY:
|
||||||
|
//TODO : fix me!
|
||||||
|
break;
|
||||||
|
case BATTLEGROUND_AB:
|
||||||
|
case BATTLEGROUND_AV:
|
||||||
|
{
|
||||||
|
//for other BG types - send default
|
||||||
|
WorldPacket data(MSG_BATTLEGROUND_PLAYER_POSITIONS, (4+4));
|
||||||
|
data << uint32(0);
|
||||||
|
data << uint32(0);
|
||||||
|
SendPacket(&data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//maybe it is sent also in arena - do nothing
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleBattleGroundPVPlogdataOpcode( WorldPacket & /*recv_data*/ )
|
void WorldSession::HandleBattleGroundPVPlogdataOpcode( WorldPacket & /*recv_data*/ )
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,14 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||||
{ NULL, 0, false, NULL, "", NULL }
|
{ NULL, 0, false, NULL, "", NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static ChatCommand debugPlayCommandTable[] =
|
||||||
|
{
|
||||||
|
{ "cinematic", SEC_MODERATOR, false, &ChatHandler::HandleDebugPlayCinematicCommand, "", NULL },
|
||||||
|
{ "movie", SEC_MODERATOR, false, &ChatHandler::HandleDebugPlayMovieCommand, "", NULL },
|
||||||
|
{ "sound", SEC_MODERATOR, false, &ChatHandler::HandleDebugPlaySoundCommand, "", NULL },
|
||||||
|
{ NULL, 0, false, NULL, "", NULL }
|
||||||
|
};
|
||||||
|
|
||||||
static ChatCommand debugSendCommandTable[] =
|
static ChatCommand debugSendCommandTable[] =
|
||||||
{
|
{
|
||||||
{ "buyerror", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendBuyErrorCommand, "", NULL },
|
{ "buyerror", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendBuyErrorCommand, "", NULL },
|
||||||
|
|
@ -131,7 +139,7 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||||
{ "lootrecipient", SEC_GAMEMASTER, false, &ChatHandler::HandleDebugGetLootRecipient, "", NULL },
|
{ "lootrecipient", SEC_GAMEMASTER, false, &ChatHandler::HandleDebugGetLootRecipient, "", NULL },
|
||||||
{ "getvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugGetValue, "", NULL },
|
{ "getvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugGetValue, "", NULL },
|
||||||
{ "Mod32Value", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugMod32Value, "", NULL },
|
{ "Mod32Value", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugMod32Value, "", NULL },
|
||||||
{ "playsound", SEC_MODERATOR, false, &ChatHandler::HandleDebugPlaySoundCommand, "", NULL },
|
{ "play", SEC_MODERATOR, false, NULL, "", debugPlayCommandTable },
|
||||||
{ "send", SEC_ADMINISTRATOR, false, NULL, "", debugSendCommandTable },
|
{ "send", SEC_ADMINISTRATOR, false, NULL, "", debugSendCommandTable },
|
||||||
{ "setitemflag", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetItemFlagCommand, "", NULL },
|
{ "setitemflag", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetItemFlagCommand, "", NULL },
|
||||||
{ "setvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetValue, "", NULL },
|
{ "setvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetValue, "", NULL },
|
||||||
|
|
@ -351,6 +359,7 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||||
static ChatCommand reloadCommandTable[] =
|
static ChatCommand reloadCommandTable[] =
|
||||||
{
|
{
|
||||||
{ "all", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllCommand, "", NULL },
|
{ "all", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllCommand, "", NULL },
|
||||||
|
{ "all_achievement",SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllAchievementCommand,"", NULL },
|
||||||
{ "all_area", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllAreaCommand, "", NULL },
|
{ "all_area", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllAreaCommand, "", NULL },
|
||||||
{ "all_loot", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllLootCommand, "", NULL },
|
{ "all_loot", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllLootCommand, "", NULL },
|
||||||
{ "all_npc", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllNpcCommand, "", NULL },
|
{ "all_npc", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllNpcCommand, "", NULL },
|
||||||
|
|
@ -362,6 +371,8 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||||
|
|
||||||
{ "config", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadConfigCommand, "", NULL },
|
{ "config", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadConfigCommand, "", NULL },
|
||||||
|
|
||||||
|
{ "achievement_criteria_data", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAchievementCriteriaDataCommand, "", NULL },
|
||||||
|
{ "achievement_reward", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAchievementRewardCommand, "", NULL },
|
||||||
{ "areatrigger_tavern", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAreaTriggerTavernCommand, "", NULL },
|
{ "areatrigger_tavern", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAreaTriggerTavernCommand, "", NULL },
|
||||||
{ "areatrigger_teleport", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAreaTriggerTeleportCommand, "", NULL },
|
{ "areatrigger_teleport", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAreaTriggerTeleportCommand, "", NULL },
|
||||||
{ "areatrigger_involvedrelation",SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestAreaTriggersCommand, "", NULL },
|
{ "areatrigger_involvedrelation",SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestAreaTriggersCommand, "", NULL },
|
||||||
|
|
@ -381,6 +392,7 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||||
{ "gameobject_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGameObjectScriptsCommand, "", NULL },
|
{ "gameobject_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGameObjectScriptsCommand, "", NULL },
|
||||||
{ "item_enchantment_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadItemEnchantementsCommand, "", NULL },
|
{ "item_enchantment_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadItemEnchantementsCommand, "", NULL },
|
||||||
{ "item_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesItemCommand, "", NULL },
|
{ "item_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesItemCommand, "", NULL },
|
||||||
|
{ "locales_achievement_reward", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesAchievementRewardCommand,"", NULL },
|
||||||
{ "locales_creature", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesCreatureCommand, "", NULL },
|
{ "locales_creature", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesCreatureCommand, "", NULL },
|
||||||
{ "locales_gameobject", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesGameobjectCommand, "", NULL },
|
{ "locales_gameobject", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesGameobjectCommand, "", NULL },
|
||||||
{ "locales_item", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesItemCommand, "", NULL },
|
{ "locales_item", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesItemCommand, "", NULL },
|
||||||
|
|
@ -437,6 +449,15 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||||
{ NULL, 0, false, NULL, "", NULL }
|
{ NULL, 0, false, NULL, "", NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static ChatCommand sendCommandTable[] =
|
||||||
|
{
|
||||||
|
{ "items", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendItemsCommand, "", NULL },
|
||||||
|
{ "mail", SEC_MODERATOR, true, &ChatHandler::HandleSendMailCommand, "", NULL },
|
||||||
|
{ "message", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendMessageCommand, "", NULL },
|
||||||
|
{ "money", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendMoneyCommand, "", NULL },
|
||||||
|
{ NULL, 0, false, NULL, "", NULL }
|
||||||
|
};
|
||||||
|
|
||||||
static ChatCommand serverIdleRestartCommandTable[] =
|
static ChatCommand serverIdleRestartCommandTable[] =
|
||||||
{
|
{
|
||||||
{ "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
|
{ "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
|
||||||
|
|
@ -589,9 +610,7 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||||
{ "password", SEC_PLAYER, false, &ChatHandler::HandlePasswordCommand, "", NULL },
|
{ "password", SEC_PLAYER, false, &ChatHandler::HandlePasswordCommand, "", NULL },
|
||||||
{ "lockaccount", SEC_PLAYER, false, &ChatHandler::HandleLockAccountCommand, "", NULL },
|
{ "lockaccount", SEC_PLAYER, false, &ChatHandler::HandleLockAccountCommand, "", NULL },
|
||||||
{ "respawn", SEC_ADMINISTRATOR, false, &ChatHandler::HandleRespawnCommand, "", NULL },
|
{ "respawn", SEC_ADMINISTRATOR, false, &ChatHandler::HandleRespawnCommand, "", NULL },
|
||||||
{ "senditems", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendItemsCommand, "", NULL },
|
{ "send", SEC_MODERATOR, true, NULL, "", sendCommandTable },
|
||||||
{ "sendmail", SEC_MODERATOR, true, &ChatHandler::HandleSendMailCommand, "", NULL },
|
|
||||||
{ "sendmoney", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendMoneyCommand, "", NULL },
|
|
||||||
{ "rename", SEC_GAMEMASTER, true, &ChatHandler::HandleRenameCommand, "", NULL },
|
{ "rename", SEC_GAMEMASTER, true, &ChatHandler::HandleRenameCommand, "", NULL },
|
||||||
{ "customize", SEC_GAMEMASTER, true, &ChatHandler::HandleCustomizeCommand, "", NULL },
|
{ "customize", SEC_GAMEMASTER, true, &ChatHandler::HandleCustomizeCommand, "", NULL },
|
||||||
{ "loadscripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLoadScriptsCommand, "", NULL },
|
{ "loadscripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLoadScriptsCommand, "", NULL },
|
||||||
|
|
@ -603,7 +622,6 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||||
{ "combatstop", SEC_GAMEMASTER, false, &ChatHandler::HandleCombatStopCommand, "", NULL },
|
{ "combatstop", SEC_GAMEMASTER, false, &ChatHandler::HandleCombatStopCommand, "", NULL },
|
||||||
{ "flusharenapoints",SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlushArenaPointsCommand, "", NULL },
|
{ "flusharenapoints",SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlushArenaPointsCommand, "", NULL },
|
||||||
{ "chardelete", SEC_CONSOLE, true, &ChatHandler::HandleCharacterDeleteCommand, "", NULL },
|
{ "chardelete", SEC_CONSOLE, true, &ChatHandler::HandleCharacterDeleteCommand, "", NULL },
|
||||||
{ "sendmessage", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendMessageCommand, "", NULL },
|
|
||||||
{ "repairitems", SEC_GAMEMASTER, false, &ChatHandler::HandleRepairitemsCommand, "", NULL },
|
{ "repairitems", SEC_GAMEMASTER, false, &ChatHandler::HandleRepairitemsCommand, "", NULL },
|
||||||
{ "waterwalk", SEC_GAMEMASTER, false, &ChatHandler::HandleWaterwalkCommand, "", NULL },
|
{ "waterwalk", SEC_GAMEMASTER, false, &ChatHandler::HandleWaterwalkCommand, "", NULL },
|
||||||
|
|
||||||
|
|
|
||||||
179
src/game/Chat.h
179
src/game/Chat.h
|
|
@ -95,27 +95,21 @@ class ChatHandler
|
||||||
bool HandleAccountSetGmLevelCommand(const char* args);
|
bool HandleAccountSetGmLevelCommand(const char* args);
|
||||||
bool HandleAccountSetPasswordCommand(const char* args);
|
bool HandleAccountSetPasswordCommand(const char* args);
|
||||||
|
|
||||||
bool HandleHelpCommand(const char* args);
|
bool HandleBanAccountCommand(const char* args);
|
||||||
bool HandleCommandsCommand(const char* args);
|
bool HandleBanCharacterCommand(const char* args);
|
||||||
bool HandleStartCommand(const char* args);
|
bool HandleBanIPCommand(const char* args);
|
||||||
bool HandleDismountCommand(const char* args);
|
bool HandleBanInfoAccountCommand(const char* args);
|
||||||
bool HandleSaveCommand(const char* args);
|
bool HandleBanInfoCharacterCommand(const char* args);
|
||||||
|
bool HandleBanInfoIPCommand(const char* args);
|
||||||
|
bool HandleBanListAccountCommand(const char* args);
|
||||||
|
bool HandleBanListCharacterCommand(const char* args);
|
||||||
|
bool HandleBanListIPCommand(const char* args);
|
||||||
|
|
||||||
bool HandleNamegoCommand(const char* args);
|
bool HandleCastCommand(const char *args);
|
||||||
bool HandleGonameCommand(const char* args);
|
bool HandleCastBackCommand(const char *args);
|
||||||
bool HandleGroupgoCommand(const char* args);
|
bool HandleCastDistCommand(const char *args);
|
||||||
bool HandleRecallCommand(const char* args);
|
bool HandleCastSelfCommand(const char *args);
|
||||||
bool HandleAnnounceCommand(const char* args);
|
bool HandleCastTargetCommand(const char *args);
|
||||||
bool HandleNotifyCommand(const char* args);
|
|
||||||
bool HandleGPSCommand(const char* args);
|
|
||||||
bool HandleTaxiCheatCommand(const char* args);
|
|
||||||
bool HandleWhispersCommand(const char* args);
|
|
||||||
bool HandleTeleNameCommand(const char* args);
|
|
||||||
bool HandleTeleGroupCommand(const char* args);
|
|
||||||
bool HandleModifyDrunkCommand(const char* args);
|
|
||||||
bool HandleSendItemsCommand(const char* args);
|
|
||||||
bool HandleSendMailCommand(const char* args);
|
|
||||||
bool HandleSendMoneyCommand(const char* args);
|
|
||||||
|
|
||||||
bool HandleDebugAnimCommand(const char* args);
|
bool HandleDebugAnimCommand(const char* args);
|
||||||
bool HandleDebugArenaCommand(const char * args);
|
bool HandleDebugArenaCommand(const char * args);
|
||||||
|
|
@ -124,13 +118,16 @@ class ChatHandler
|
||||||
bool HandleDebugGetLootRecipient(const char * args);
|
bool HandleDebugGetLootRecipient(const char * args);
|
||||||
bool HandleDebugGetValue(const char* args);
|
bool HandleDebugGetValue(const char* args);
|
||||||
bool HandleDebugMod32Value(const char* args);
|
bool HandleDebugMod32Value(const char* args);
|
||||||
bool HandleDebugPlaySoundCommand(const char* args);
|
|
||||||
bool HandleDebugSetValue(const char* args);
|
bool HandleDebugSetValue(const char* args);
|
||||||
bool HandleDebugSetItemFlagCommand(const char * args);
|
bool HandleDebugSetItemFlagCommand(const char * args);
|
||||||
bool HandleDebugSpawnVehicle(const char * args);
|
bool HandleDebugSpawnVehicle(const char * args);
|
||||||
bool HandleDebugUpdate(const char* args);
|
bool HandleDebugUpdate(const char* args);
|
||||||
bool HandleDebugUpdateWorldStateCommand(const char* args);
|
bool HandleDebugUpdateWorldStateCommand(const char* args);
|
||||||
|
|
||||||
|
bool HandleDebugPlayCinematicCommand(const char* args);
|
||||||
|
bool HandleDebugPlayMovieCommand(const char* args);
|
||||||
|
bool HandleDebugPlaySoundCommand(const char* args);
|
||||||
|
|
||||||
bool HandleDebugSendBuyErrorCommand(const char* args);
|
bool HandleDebugSendBuyErrorCommand(const char* args);
|
||||||
bool HandleDebugSendChannelNotifyCommand(const char* args);
|
bool HandleDebugSendChannelNotifyCommand(const char* args);
|
||||||
bool HandleDebugSendChatMsgCommand(const char* args);
|
bool HandleDebugSendChatMsgCommand(const char* args);
|
||||||
|
|
@ -149,6 +146,14 @@ class ChatHandler
|
||||||
bool HandleEventStopCommand(const char* args);
|
bool HandleEventStopCommand(const char* args);
|
||||||
bool HandleEventInfoCommand(const char* args);
|
bool HandleEventInfoCommand(const char* args);
|
||||||
|
|
||||||
|
bool HandleGameObjectAddCommand(const char* args);
|
||||||
|
bool HandleGameObjectDeleteCommand(const char* args);
|
||||||
|
bool HandleGameObjectMoveCommand(const char* args);
|
||||||
|
bool HandleGameObjectNearCommand(const char* args);
|
||||||
|
bool HandleGameObjectPhaseCommand(const char* args);
|
||||||
|
bool HandleGameObjectTargetCommand(const char* args);
|
||||||
|
bool HandleGameObjectTurnCommand(const char* args);
|
||||||
|
|
||||||
bool HandleGMCommand(const char* args);
|
bool HandleGMCommand(const char* args);
|
||||||
bool HandleGMChatCommand(const char* args);
|
bool HandleGMChatCommand(const char* args);
|
||||||
bool HandleGMFlyCommand(const char* args);
|
bool HandleGMFlyCommand(const char* args);
|
||||||
|
|
@ -156,6 +161,21 @@ class ChatHandler
|
||||||
bool HandleGMListIngameCommand(const char* args);
|
bool HandleGMListIngameCommand(const char* args);
|
||||||
bool HandleGMVisibleCommand(const char* args);
|
bool HandleGMVisibleCommand(const char* args);
|
||||||
|
|
||||||
|
bool HandleGuildCreateCommand(const char* args);
|
||||||
|
bool HandleGuildInviteCommand(const char* args);
|
||||||
|
bool HandleGuildUninviteCommand(const char* args);
|
||||||
|
bool HandleGuildRankCommand(const char* args);
|
||||||
|
bool HandleGuildDeleteCommand(const char* args);
|
||||||
|
|
||||||
|
bool HandleHonorAddCommand(const char* args);
|
||||||
|
bool HandleHonorAddKillCommand(const char* args);
|
||||||
|
bool HandleHonorUpdateCommand(const char* args);
|
||||||
|
|
||||||
|
bool HandleInstanceListBindsCommand(const char* args);
|
||||||
|
bool HandleInstanceUnbindCommand(const char* args);
|
||||||
|
bool HandleInstanceStatsCommand(const char* args);
|
||||||
|
bool HandleInstanceSaveDataCommand(const char * args);
|
||||||
|
|
||||||
bool HandleLearnCommand(const char* args);
|
bool HandleLearnCommand(const char* args);
|
||||||
bool HandleLearnAllCommand(const char* args);
|
bool HandleLearnAllCommand(const char* args);
|
||||||
bool HandleLearnAllGMCommand(const char* args);
|
bool HandleLearnAllGMCommand(const char* args);
|
||||||
|
|
@ -168,6 +188,11 @@ class ChatHandler
|
||||||
bool HandleLearnAllMySpellsCommand(const char* args);
|
bool HandleLearnAllMySpellsCommand(const char* args);
|
||||||
bool HandleLearnAllMyTalentsCommand(const char* args);
|
bool HandleLearnAllMyTalentsCommand(const char* args);
|
||||||
|
|
||||||
|
bool HandleListAurasCommand(const char * args);
|
||||||
|
bool HandleListCreatureCommand(const char* args);
|
||||||
|
bool HandleListItemCommand(const char* args);
|
||||||
|
bool HandleListObjectCommand(const char* args);
|
||||||
|
|
||||||
bool HandleLookupAreaCommand(const char* args);
|
bool HandleLookupAreaCommand(const char* args);
|
||||||
bool HandleLookupCreatureCommand(const char* args);
|
bool HandleLookupCreatureCommand(const char* args);
|
||||||
bool HandleLookupEventCommand(const char* args);
|
bool HandleLookupEventCommand(const char* args);
|
||||||
|
|
@ -240,7 +265,12 @@ class ChatHandler
|
||||||
bool HandleNpcSubNameCommand(const char* args);
|
bool HandleNpcSubNameCommand(const char* args);
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
|
|
||||||
|
bool HandleQuestAdd(const char * args);
|
||||||
|
bool HandleQuestRemove(const char * args);
|
||||||
|
bool HandleQuestComplete(const char * args);
|
||||||
|
|
||||||
bool HandleReloadAllCommand(const char* args);
|
bool HandleReloadAllCommand(const char* args);
|
||||||
|
bool HandleReloadAllAchievementCommand(const char* args);
|
||||||
bool HandleReloadAllAreaCommand(const char* args);
|
bool HandleReloadAllAreaCommand(const char* args);
|
||||||
bool HandleReloadAllItemCommand(const char* args);
|
bool HandleReloadAllItemCommand(const char* args);
|
||||||
bool HandleReloadAllLootCommand(const char* args);
|
bool HandleReloadAllLootCommand(const char* args);
|
||||||
|
|
@ -252,6 +282,8 @@ class ChatHandler
|
||||||
|
|
||||||
bool HandleReloadConfigCommand(const char* args);
|
bool HandleReloadConfigCommand(const char* args);
|
||||||
|
|
||||||
|
bool HandleReloadAchievementCriteriaDataCommand(const char* args);
|
||||||
|
bool HandleReloadAchievementRewardCommand(const char* args);
|
||||||
bool HandleReloadAreaTriggerTavernCommand(const char* args);
|
bool HandleReloadAreaTriggerTavernCommand(const char* args);
|
||||||
bool HandleReloadAreaTriggerTeleportCommand(const char* args);
|
bool HandleReloadAreaTriggerTeleportCommand(const char* args);
|
||||||
bool HandleReloadEventScriptsCommand(const char* args);
|
bool HandleReloadEventScriptsCommand(const char* args);
|
||||||
|
|
@ -265,6 +297,7 @@ class ChatHandler
|
||||||
bool HandleReloadGOQuestRelationsCommand(const char* args);
|
bool HandleReloadGOQuestRelationsCommand(const char* args);
|
||||||
bool HandleReloadGOQuestInvRelationsCommand(const char* args);
|
bool HandleReloadGOQuestInvRelationsCommand(const char* args);
|
||||||
bool HandleReloadItemEnchantementsCommand(const char* args);
|
bool HandleReloadItemEnchantementsCommand(const char* args);
|
||||||
|
bool HandleReloadLocalesAchievementRewardCommand(const char* args);
|
||||||
bool HandleReloadLocalesCreatureCommand(const char* args);
|
bool HandleReloadLocalesCreatureCommand(const char* args);
|
||||||
bool HandleReloadLocalesGameobjectCommand(const char* args);
|
bool HandleReloadLocalesGameobjectCommand(const char* args);
|
||||||
bool HandleReloadLocalesItemCommand(const char* args);
|
bool HandleReloadLocalesItemCommand(const char* args);
|
||||||
|
|
@ -312,10 +345,18 @@ class ChatHandler
|
||||||
bool HandleReloadSpellThreatsCommand(const char* args);
|
bool HandleReloadSpellThreatsCommand(const char* args);
|
||||||
bool HandleReloadSpellPetAurasCommand(const char* args);
|
bool HandleReloadSpellPetAurasCommand(const char* args);
|
||||||
|
|
||||||
bool HandleInstanceListBindsCommand(const char* args);
|
bool HandleResetAchievementsCommand(const char * args);
|
||||||
bool HandleInstanceUnbindCommand(const char* args);
|
bool HandleResetAllCommand(const char * args);
|
||||||
bool HandleInstanceStatsCommand(const char* args);
|
bool HandleResetHonorCommand(const char * args);
|
||||||
bool HandleInstanceSaveDataCommand(const char * args);
|
bool HandleResetLevelCommand(const char * args);
|
||||||
|
bool HandleResetSpellsCommand(const char * args);
|
||||||
|
bool HandleResetStatsCommand(const char * args);
|
||||||
|
bool HandleResetTalentsCommand(const char * args);
|
||||||
|
|
||||||
|
bool HandleSendItemsCommand(const char* args);
|
||||||
|
bool HandleSendMailCommand(const char* args);
|
||||||
|
bool HandleSendMessageCommand(const char * args);
|
||||||
|
bool HandleSendMoneyCommand(const char* args);
|
||||||
|
|
||||||
bool HandleServerCorpsesCommand(const char* args);
|
bool HandleServerCorpsesCommand(const char* args);
|
||||||
bool HandleServerExitCommand(const char* args);
|
bool HandleServerExitCommand(const char* args);
|
||||||
|
|
@ -329,9 +370,38 @@ class ChatHandler
|
||||||
bool HandleServerShutDownCommand(const char* args);
|
bool HandleServerShutDownCommand(const char* args);
|
||||||
bool HandleServerShutDownCancelCommand(const char* args);
|
bool HandleServerShutDownCancelCommand(const char* args);
|
||||||
|
|
||||||
bool HandleHonorAddCommand(const char* args);
|
bool HandleTeleCommand(const char * args);
|
||||||
bool HandleHonorAddKillCommand(const char* args);
|
bool HandleTeleAddCommand(const char * args);
|
||||||
bool HandleHonorUpdateCommand(const char* args);
|
bool HandleTeleDelCommand(const char * args);
|
||||||
|
bool HandleTeleGroupCommand(const char* args);
|
||||||
|
bool HandleTeleNameCommand(const char* args);
|
||||||
|
|
||||||
|
bool HandleUnBanAccountCommand(const char* args);
|
||||||
|
bool HandleUnBanCharacterCommand(const char* args);
|
||||||
|
bool HandleUnBanIPCommand(const char* args);
|
||||||
|
|
||||||
|
bool HandleWpAddCommand(const char* args);
|
||||||
|
bool HandleWpModifyCommand(const char* args);
|
||||||
|
bool HandleWpShowCommand(const char* args);
|
||||||
|
bool HandleWpExportCommand(const char* args);
|
||||||
|
bool HandleWpImportCommand(const char* args);
|
||||||
|
|
||||||
|
bool HandleHelpCommand(const char* args);
|
||||||
|
bool HandleCommandsCommand(const char* args);
|
||||||
|
bool HandleStartCommand(const char* args);
|
||||||
|
bool HandleDismountCommand(const char* args);
|
||||||
|
bool HandleSaveCommand(const char* args);
|
||||||
|
|
||||||
|
bool HandleNamegoCommand(const char* args);
|
||||||
|
bool HandleGonameCommand(const char* args);
|
||||||
|
bool HandleGroupgoCommand(const char* args);
|
||||||
|
bool HandleRecallCommand(const char* args);
|
||||||
|
bool HandleAnnounceCommand(const char* args);
|
||||||
|
bool HandleNotifyCommand(const char* args);
|
||||||
|
bool HandleGPSCommand(const char* args);
|
||||||
|
bool HandleTaxiCheatCommand(const char* args);
|
||||||
|
bool HandleWhispersCommand(const char* args);
|
||||||
|
bool HandleModifyDrunkCommand(const char* args);
|
||||||
|
|
||||||
bool HandleLoadScriptsCommand(const char* args);
|
bool HandleLoadScriptsCommand(const char* args);
|
||||||
|
|
||||||
|
|
@ -342,11 +412,6 @@ class ChatHandler
|
||||||
bool HandleGoObjectCommand(const char* args);
|
bool HandleGoObjectCommand(const char* args);
|
||||||
bool HandleGoTriggerCommand(const char* args);
|
bool HandleGoTriggerCommand(const char* args);
|
||||||
bool HandleGoGraveyardCommand(const char* args);
|
bool HandleGoGraveyardCommand(const char* args);
|
||||||
bool HandleGameObjectTargetCommand(const char* args);
|
|
||||||
bool HandleGameObjectDeleteCommand(const char* args);
|
|
||||||
bool HandleGameObjectMoveCommand(const char* args);
|
|
||||||
bool HandleGameObjectPhaseCommand(const char* args);
|
|
||||||
bool HandleGameObjectTurnCommand(const char* args);
|
|
||||||
bool HandlePInfoCommand(const char* args);
|
bool HandlePInfoCommand(const char* args);
|
||||||
bool HandlePLimitCommand(const char* args);
|
bool HandlePLimitCommand(const char* args);
|
||||||
bool HandleMuteCommand(const char* args);
|
bool HandleMuteCommand(const char* args);
|
||||||
|
|
@ -354,18 +419,6 @@ class ChatHandler
|
||||||
bool HandleMovegensCommand(const char* args);
|
bool HandleMovegensCommand(const char* args);
|
||||||
|
|
||||||
bool HandleCharacterDeleteCommand(const char* args);
|
bool HandleCharacterDeleteCommand(const char* args);
|
||||||
bool HandleBanAccountCommand(const char* args);
|
|
||||||
bool HandleBanCharacterCommand(const char* args);
|
|
||||||
bool HandleBanIPCommand(const char* args);
|
|
||||||
bool HandleUnBanAccountCommand(const char* args);
|
|
||||||
bool HandleUnBanCharacterCommand(const char* args);
|
|
||||||
bool HandleUnBanIPCommand(const char* args);
|
|
||||||
bool HandleBanInfoAccountCommand(const char* args);
|
|
||||||
bool HandleBanInfoCharacterCommand(const char* args);
|
|
||||||
bool HandleBanInfoIPCommand(const char* args);
|
|
||||||
bool HandleBanListAccountCommand(const char* args);
|
|
||||||
bool HandleBanListCharacterCommand(const char* args);
|
|
||||||
bool HandleBanListIPCommand(const char* args);
|
|
||||||
bool HandleGoXYCommand(const char* args);
|
bool HandleGoXYCommand(const char* args);
|
||||||
bool HandleGoXYZCommand(const char* args);
|
bool HandleGoXYZCommand(const char* args);
|
||||||
bool HandleGoZoneXYCommand(const char* args);
|
bool HandleGoZoneXYCommand(const char* args);
|
||||||
|
|
@ -376,7 +429,6 @@ class ChatHandler
|
||||||
bool HandleCooldownCommand(const char* args);
|
bool HandleCooldownCommand(const char* args);
|
||||||
bool HandleUnLearnCommand(const char* args);
|
bool HandleUnLearnCommand(const char* args);
|
||||||
bool HandleGetDistanceCommand(const char* args);
|
bool HandleGetDistanceCommand(const char* args);
|
||||||
bool HandleGameObjectAddCommand(const char* args);
|
|
||||||
bool HandleModifyStandStateCommand(const char* args);
|
bool HandleModifyStandStateCommand(const char* args);
|
||||||
bool HandleDieCommand(const char* args);
|
bool HandleDieCommand(const char* args);
|
||||||
bool HandleDamageCommand(const char *args);
|
bool HandleDamageCommand(const char *args);
|
||||||
|
|
@ -394,64 +446,29 @@ class ChatHandler
|
||||||
bool HandleAddItemCommand(const char* args);
|
bool HandleAddItemCommand(const char* args);
|
||||||
bool HandleAddItemSetCommand(const char* args);
|
bool HandleAddItemSetCommand(const char* args);
|
||||||
|
|
||||||
bool HandleGuildCreateCommand(const char* args);
|
|
||||||
bool HandleGuildInviteCommand(const char* args);
|
|
||||||
bool HandleGuildUninviteCommand(const char* args);
|
|
||||||
bool HandleGuildRankCommand(const char* args);
|
|
||||||
bool HandleGuildDeleteCommand(const char* args);
|
|
||||||
bool HandleBankCommand(const char* args);
|
bool HandleBankCommand(const char* args);
|
||||||
bool HandleChangeWeather(const char* args);
|
bool HandleChangeWeather(const char* args);
|
||||||
bool HandleKickPlayerCommand(const char * args);
|
bool HandleKickPlayerCommand(const char * args);
|
||||||
bool HandleTeleCommand(const char * args);
|
|
||||||
bool HandleTeleAddCommand(const char * args);
|
|
||||||
bool HandleTeleDelCommand(const char * args);
|
|
||||||
bool HandleListAurasCommand(const char * args);
|
|
||||||
|
|
||||||
bool HandleResetAchievementsCommand(const char * args);
|
|
||||||
bool HandleResetHonorCommand(const char * args);
|
|
||||||
bool HandleResetLevelCommand(const char * args);
|
|
||||||
bool HandleResetSpellsCommand(const char * args);
|
|
||||||
bool HandleResetStatsCommand(const char * args);
|
|
||||||
bool HandleResetTalentsCommand(const char * args);
|
|
||||||
bool HandleResetAllCommand(const char * args);
|
|
||||||
|
|
||||||
bool HandleTicketCommand(const char* args);
|
bool HandleTicketCommand(const char* args);
|
||||||
bool HandleDelTicketCommand(const char* args);
|
bool HandleDelTicketCommand(const char* args);
|
||||||
bool HandleMaxSkillCommand(const char* args);
|
bool HandleMaxSkillCommand(const char* args);
|
||||||
bool HandleSetSkillCommand(const char* args);
|
bool HandleSetSkillCommand(const char* args);
|
||||||
bool HandleListCreatureCommand(const char* args);
|
|
||||||
bool HandleListItemCommand(const char* args);
|
|
||||||
bool HandleListObjectCommand(const char* args);
|
|
||||||
bool HandleGameObjectNearCommand(const char* args);
|
|
||||||
bool HandlePasswordCommand(const char* args);
|
bool HandlePasswordCommand(const char* args);
|
||||||
bool HandleLockAccountCommand(const char* args);
|
bool HandleLockAccountCommand(const char* args);
|
||||||
bool HandleRespawnCommand(const char* args);
|
bool HandleRespawnCommand(const char* args);
|
||||||
bool HandleWpAddCommand(const char* args);
|
|
||||||
bool HandleWpModifyCommand(const char* args);
|
|
||||||
bool HandleWpShowCommand(const char* args);
|
|
||||||
bool HandleWpExportCommand(const char* args);
|
|
||||||
bool HandleWpImportCommand(const char* args);
|
|
||||||
bool HandleRenameCommand(const char * args);
|
bool HandleRenameCommand(const char * args);
|
||||||
bool HandleCustomizeCommand(const char * args);
|
bool HandleCustomizeCommand(const char * args);
|
||||||
bool HandlePDumpLoadCommand(const char *args);
|
bool HandlePDumpLoadCommand(const char *args);
|
||||||
bool HandlePDumpWriteCommand(const char *args);
|
bool HandlePDumpWriteCommand(const char *args);
|
||||||
bool HandleCastCommand(const char *args);
|
|
||||||
bool HandleCastBackCommand(const char *args);
|
|
||||||
bool HandleCastDistCommand(const char *args);
|
|
||||||
bool HandleCastSelfCommand(const char *args);
|
|
||||||
bool HandleCastTargetCommand(const char *args);
|
|
||||||
bool HandleComeToMeCommand(const char *args);
|
bool HandleComeToMeCommand(const char *args);
|
||||||
bool HandleCombatStopCommand(const char *args);
|
bool HandleCombatStopCommand(const char *args);
|
||||||
bool HandleSendMessageCommand(const char * args);
|
|
||||||
bool HandleFlushArenaPointsCommand(const char *args);
|
bool HandleFlushArenaPointsCommand(const char *args);
|
||||||
bool HandleRepairitemsCommand(const char* args);
|
bool HandleRepairitemsCommand(const char* args);
|
||||||
bool HandleWaterwalkCommand(const char* args);
|
bool HandleWaterwalkCommand(const char* args);
|
||||||
|
|
||||||
//! Development Commands
|
//! Development Commands
|
||||||
bool HandleSet32Bit(const char* args);
|
bool HandleSet32Bit(const char* args);
|
||||||
bool HandleQuestAdd(const char * args);
|
|
||||||
bool HandleQuestRemove(const char * args);
|
|
||||||
bool HandleQuestComplete(const char * args);
|
|
||||||
bool HandleSaveAllCommand(const char* args);
|
bool HandleSaveAllCommand(const char* args);
|
||||||
|
|
||||||
Player* getSelectedPlayer();
|
Player* getSelectedPlayer();
|
||||||
|
|
|
||||||
|
|
@ -304,6 +304,29 @@ enum InhabitTypeValues
|
||||||
INHABIT_ANYWHERE = INHABIT_GROUND | INHABIT_WATER | INHABIT_AIR
|
INHABIT_ANYWHERE = INHABIT_GROUND | INHABIT_WATER | INHABIT_AIR
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Enums used by StringTextData::Type (CreatureEventAI)
|
||||||
|
enum ChatType
|
||||||
|
{
|
||||||
|
CHAT_TYPE_SAY = 0,
|
||||||
|
CHAT_TYPE_YELL = 1,
|
||||||
|
CHAT_TYPE_TEXT_EMOTE = 2,
|
||||||
|
CHAT_TYPE_BOSS_EMOTE = 3,
|
||||||
|
CHAT_TYPE_WHISPER = 4,
|
||||||
|
CHAT_TYPE_BOSS_WHISPER = 5,
|
||||||
|
CHAT_TYPE_ZONE_YELL = 6
|
||||||
|
};
|
||||||
|
|
||||||
|
//Selection method used by SelectTarget (CreatureEventAI)
|
||||||
|
enum AttackingTarget
|
||||||
|
{
|
||||||
|
ATTACKING_TARGET_RANDOM = 0, //Just selects a random target
|
||||||
|
ATTACKING_TARGET_TOPAGGRO, //Selects targes from top aggro to bottom
|
||||||
|
ATTACKING_TARGET_BOTTOMAGGRO, //Selects targets from bottom aggro to top
|
||||||
|
ATTACKING_TARGET_RANDOM_PLAYER, //Just selects a random target (player only)
|
||||||
|
ATTACKING_TARGET_TOPAGGRO_PLAYER, //Selects targes from top aggro to bottom (player only)
|
||||||
|
ATTACKING_TARGET_BOTTOMAGGRO_PLAYER, //Selects targets from bottom aggro to top (player only)
|
||||||
|
};
|
||||||
|
|
||||||
// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform
|
// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform
|
||||||
#if defined( __GNUC__ )
|
#if defined( __GNUC__ )
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
#include "GuardAI.h"
|
#include "GuardAI.h"
|
||||||
#include "PetAI.h"
|
#include "PetAI.h"
|
||||||
#include "TotemAI.h"
|
#include "TotemAI.h"
|
||||||
|
#include "CreatureEventAI.h"
|
||||||
#include "RandomMovementGenerator.h"
|
#include "RandomMovementGenerator.h"
|
||||||
#include "CreatureAIImpl.h"
|
#include "CreatureAIImpl.h"
|
||||||
#include "MovementGeneratorImpl.h"
|
#include "MovementGeneratorImpl.h"
|
||||||
|
|
@ -38,6 +39,7 @@ namespace AIRegistry
|
||||||
(new CreatureAIFactory<GuardAI>("GuardAI"))->RegisterSelf();
|
(new CreatureAIFactory<GuardAI>("GuardAI"))->RegisterSelf();
|
||||||
(new CreatureAIFactory<PetAI>("PetAI"))->RegisterSelf();
|
(new CreatureAIFactory<PetAI>("PetAI"))->RegisterSelf();
|
||||||
(new CreatureAIFactory<TotemAI>("TotemAI"))->RegisterSelf();
|
(new CreatureAIFactory<TotemAI>("TotemAI"))->RegisterSelf();
|
||||||
|
(new CreatureAIFactory<CreatureEventAI>("EventAI"))->RegisterSelf();
|
||||||
|
|
||||||
(new MovementGeneratorFactory<RandomMovementGenerator<Creature> >(RANDOM_MOTION_TYPE))->RegisterSelf();
|
(new MovementGeneratorFactory<RandomMovementGenerator<Creature> >(RANDOM_MOTION_TYPE))->RegisterSelf();
|
||||||
(new MovementGeneratorFactory<WaypointMovementGenerator<Creature> >(WAYPOINT_MOTION_TYPE))->RegisterSelf();
|
(new MovementGeneratorFactory<WaypointMovementGenerator<Creature> >(WAYPOINT_MOTION_TYPE))->RegisterSelf();
|
||||||
|
|
|
||||||
1705
src/game/CreatureEventAI.cpp
Normal file
1705
src/game/CreatureEventAI.cpp
Normal file
File diff suppressed because it is too large
Load diff
305
src/game/CreatureEventAI.h
Normal file
305
src/game/CreatureEventAI.h
Normal file
|
|
@ -0,0 +1,305 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MANGOS_CREATURE_EAI_H
|
||||||
|
#define MANGOS_CREATURE_EAI_H
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Creature.h"
|
||||||
|
#include "CreatureAI.h"
|
||||||
|
#include "Unit.h"
|
||||||
|
|
||||||
|
class Player;
|
||||||
|
class WorldObject;
|
||||||
|
|
||||||
|
#define EVENT_UPDATE_TIME 500
|
||||||
|
#define SPELL_RUN_AWAY 8225
|
||||||
|
#define MAX_ACTIONS 3
|
||||||
|
#define TEXT_SOURCE_RANGE -1000000 //the amount of entries each text source has available
|
||||||
|
|
||||||
|
enum Event_Types
|
||||||
|
{
|
||||||
|
EVENT_T_TIMER = 0, //InitialMin, InitialMax, RepeatMin, RepeatMax
|
||||||
|
EVENT_T_TIMER_OOC = 1, //InitialMin, InitialMax, RepeatMin, RepeatMax
|
||||||
|
EVENT_T_HP = 2, //HPMax%, HPMin%, RepeatMin, RepeatMax
|
||||||
|
EVENT_T_MANA = 3, //ManaMax%,ManaMin% RepeatMin, RepeatMax
|
||||||
|
EVENT_T_AGGRO = 4, //NONE
|
||||||
|
EVENT_T_KILL = 5, //RepeatMin, RepeatMax
|
||||||
|
EVENT_T_DEATH = 6, //NONE
|
||||||
|
EVENT_T_EVADE = 7, //NONE
|
||||||
|
EVENT_T_SPELLHIT = 8, //SpellID, School, RepeatMin, RepeatMax
|
||||||
|
EVENT_T_RANGE = 9, //MinDist, MaxDist, RepeatMin, RepeatMax
|
||||||
|
EVENT_T_OOC_LOS = 10, //NoHostile, NoFriendly, RepeatMin, RepeatMax
|
||||||
|
EVENT_T_SPAWNED = 11, //NONE
|
||||||
|
EVENT_T_TARGET_HP = 12, //HPMax%, HPMin%, RepeatMin, RepeatMax
|
||||||
|
EVENT_T_TARGET_CASTING = 13, //RepeatMin, RepeatMax
|
||||||
|
EVENT_T_FRIENDLY_HP = 14, //HPDeficit, Radius, RepeatMin, RepeatMax
|
||||||
|
EVENT_T_FRIENDLY_IS_CC = 15, //DispelType, Radius, RepeatMin, RepeatMax
|
||||||
|
EVENT_T_FRIENDLY_MISSING_BUFF = 16, //SpellId, Radius, RepeatMin, RepeatMax
|
||||||
|
EVENT_T_SUMMONED_UNIT = 17, //CreatureId, RepeatMin, RepeatMax
|
||||||
|
EVENT_T_TARGET_MANA = 18, //ManaMax%, ManaMin%, RepeatMin, RepeatMax
|
||||||
|
EVENT_T_QUEST_ACCEPT = 19, //QuestID
|
||||||
|
EVENT_T_QUEST_COMPLETE = 20, //
|
||||||
|
EVENT_T_REACHED_HOME = 21, //NONE
|
||||||
|
EVENT_T_RECEIVE_EMOTE = 22, //EmoteId, Condition, CondValue1, CondValue2
|
||||||
|
|
||||||
|
EVENT_T_END,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Action_Types
|
||||||
|
{
|
||||||
|
ACTION_T_NONE = 0, //No action
|
||||||
|
ACTION_T_TEXT = 1, //-TextId1, optionally -TextId2, optionally -TextId3(if -TextId2 exist). If more than just -TextId1 is defined, randomize. Negative values.
|
||||||
|
ACTION_T_SET_FACTION = 2, //FactionId (or 0 for default)
|
||||||
|
ACTION_T_MORPH_TO_ENTRY_OR_MODEL = 3, //Creature_template entry(param1) OR ModelId (param2) (or 0 for both to demorph)
|
||||||
|
ACTION_T_SOUND = 4, //SoundId
|
||||||
|
ACTION_T_EMOTE = 5, //EmoteId
|
||||||
|
ACTION_T_RANDOM_SAY = 6, //UNUSED
|
||||||
|
ACTION_T_RANDOM_YELL = 7, //UNUSED
|
||||||
|
ACTION_T_RANDOM_TEXTEMOTE = 8, //UNUSED
|
||||||
|
ACTION_T_RANDOM_SOUND = 9, //SoundId1, SoundId2, SoundId3 (-1 in any field means no output if randomed that field)
|
||||||
|
ACTION_T_RANDOM_EMOTE = 10, //EmoteId1, EmoteId2, EmoteId3 (-1 in any field means no output if randomed that field)
|
||||||
|
ACTION_T_CAST = 11, //SpellId, Target, CastFlags
|
||||||
|
ACTION_T_SUMMON = 12, //CreatureID, Target, Duration in ms
|
||||||
|
ACTION_T_THREAT_SINGLE_PCT = 13, //Threat%, Target
|
||||||
|
ACTION_T_THREAT_ALL_PCT = 14, //Threat%
|
||||||
|
ACTION_T_QUEST_EVENT = 15, //QuestID, Target
|
||||||
|
ACTION_T_CASTCREATUREGO = 16, //QuestID, SpellId, Target
|
||||||
|
ACTION_T_SET_UNIT_FIELD = 17, //Field_Number, Value, Target
|
||||||
|
ACTION_T_SET_UNIT_FLAG = 18, //Flags (may be more than one field OR'd together), Target
|
||||||
|
ACTION_T_REMOVE_UNIT_FLAG = 19, //Flags (may be more than one field OR'd together), Target
|
||||||
|
ACTION_T_AUTO_ATTACK = 20, //AllowAttackState (0 = stop attack, anything else means continue attacking)
|
||||||
|
ACTION_T_COMBAT_MOVEMENT = 21, //AllowCombatMovement (0 = stop combat based movement, anything else continue attacking)
|
||||||
|
ACTION_T_SET_PHASE = 22, //Phase
|
||||||
|
ACTION_T_INC_PHASE = 23, //Value (may be negative to decrement phase, should not be 0)
|
||||||
|
ACTION_T_EVADE = 24, //No Params
|
||||||
|
ACTION_T_FLEE = 25, //No Params
|
||||||
|
ACTION_T_QUEST_EVENT_ALL = 26, //QuestID
|
||||||
|
ACTION_T_CASTCREATUREGO_ALL = 27, //QuestId, SpellId
|
||||||
|
ACTION_T_REMOVEAURASFROMSPELL = 28, //Target, Spellid
|
||||||
|
ACTION_T_RANGED_MOVEMENT = 29, //Distance, Angle
|
||||||
|
ACTION_T_RANDOM_PHASE = 30, //PhaseId1, PhaseId2, PhaseId3
|
||||||
|
ACTION_T_RANDOM_PHASE_RANGE = 31, //PhaseMin, PhaseMax
|
||||||
|
ACTION_T_SUMMON_ID = 32, //CreatureId, Target, SpawnId
|
||||||
|
ACTION_T_KILLED_MONSTER = 33, //CreatureId, Target
|
||||||
|
ACTION_T_SET_INST_DATA = 34, //Field, Data
|
||||||
|
ACTION_T_SET_INST_DATA64 = 35, //Field, Target
|
||||||
|
ACTION_T_UPDATE_TEMPLATE = 36, //Entry, Team
|
||||||
|
ACTION_T_DIE = 37, //No Params
|
||||||
|
ACTION_T_ZONE_COMBAT_PULSE = 38, //No Params
|
||||||
|
|
||||||
|
ACTION_T_END,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Target
|
||||||
|
{
|
||||||
|
//Self (m_creature)
|
||||||
|
TARGET_T_SELF = 0, //Self cast
|
||||||
|
|
||||||
|
//Hostile targets (if pet then returns pet owner)
|
||||||
|
TARGET_T_HOSTILE, //Our current target (ie: highest aggro)
|
||||||
|
TARGET_T_HOSTILE_SECOND_AGGRO, //Second highest aggro (generaly used for cleaves and some special attacks)
|
||||||
|
TARGET_T_HOSTILE_LAST_AGGRO, //Dead last on aggro (no idea what this could be used for)
|
||||||
|
TARGET_T_HOSTILE_RANDOM, //Just any random target on our threat list
|
||||||
|
TARGET_T_HOSTILE_RANDOM_NOT_TOP, //Any random target except top threat
|
||||||
|
|
||||||
|
//Invoker targets (if pet then returns pet owner)
|
||||||
|
TARGET_T_ACTION_INVOKER, //Unit who caused this Event to occur (only works for EVENT_T_AGGRO, EVENT_T_KILL, EVENT_T_DEATH, EVENT_T_SPELLHIT, EVENT_T_OOC_LOS, EVENT_T_FRIENDLY_HP, EVENT_T_FRIENDLY_IS_CC, EVENT_T_FRIENDLY_MISSING_BUFF)
|
||||||
|
|
||||||
|
//Hostile targets (including pets)
|
||||||
|
TARGET_T_HOSTILE_WPET, //Current target (can be a pet)
|
||||||
|
TARGET_T_HOSTILE_WPET_SECOND_AGGRO, //Second highest aggro (generaly used for cleaves and some special attacks)
|
||||||
|
TARGET_T_HOSTILE_WPET_LAST_AGGRO, //Dead last on aggro (no idea what this could be used for)
|
||||||
|
TARGET_T_HOSTILE_WPET_RANDOM, //Just any random target on our threat list
|
||||||
|
TARGET_T_HOSTILE_WPET_RANDOM_NOT_TOP, //Any random target except top threat
|
||||||
|
|
||||||
|
TARGET_T_ACTION_INVOKER_WPET,
|
||||||
|
|
||||||
|
TARGET_T_END
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CastFlags
|
||||||
|
{
|
||||||
|
CAST_INTURRUPT_PREVIOUS = 0x01, //Interrupt any spell casting
|
||||||
|
CAST_TRIGGERED = 0x02, //Triggered (this makes spell cost zero mana and have no cast time)
|
||||||
|
CAST_FORCE_CAST = 0x04, //Forces cast even if creature is out of mana or out of range
|
||||||
|
CAST_NO_MELEE_IF_OOM = 0x08, //Prevents creature from entering melee if out of mana or out of range
|
||||||
|
CAST_FORCE_TARGET_SELF = 0x10, //Forces the target to cast this spell on itself
|
||||||
|
CAST_AURA_NOT_PRESENT = 0x20, //Only casts the spell if the target does not have an aura from the spell
|
||||||
|
};
|
||||||
|
|
||||||
|
enum EventFlags
|
||||||
|
{
|
||||||
|
EFLAG_REPEATABLE = 0x01, //Event repeats
|
||||||
|
EFLAG_NORMAL = 0x02, //Event only occurs in Normal instance difficulty
|
||||||
|
EFLAG_HEROIC = 0x04, //Event only occurs in Heroic instance difficulty
|
||||||
|
EFLAG_RESERVED_3 = 0x08,
|
||||||
|
EFLAG_RESERVED_4 = 0x10,
|
||||||
|
EFLAG_RESERVED_5 = 0x20,
|
||||||
|
EFLAG_RESERVED_6 = 0x40,
|
||||||
|
EFLAG_DEBUG_ONLY = 0x80, //Event only occurs in debug build of SD2 only
|
||||||
|
};
|
||||||
|
|
||||||
|
// String text additional data, used in (CreatureEventAI)
|
||||||
|
struct StringTextData
|
||||||
|
{
|
||||||
|
uint32 SoundId;
|
||||||
|
uint8 Type;
|
||||||
|
uint32 Language;
|
||||||
|
uint32 Emote;
|
||||||
|
};
|
||||||
|
// Text Maps
|
||||||
|
typedef UNORDERED_MAP<int32, StringTextData> CreatureEventAI_TextMap;
|
||||||
|
|
||||||
|
struct CreatureEventAI_Event
|
||||||
|
{
|
||||||
|
uint32 event_id;
|
||||||
|
|
||||||
|
uint32 creature_id;
|
||||||
|
|
||||||
|
uint16 event_type;
|
||||||
|
uint32 event_inverse_phase_mask;
|
||||||
|
uint8 event_chance;
|
||||||
|
uint8 event_flags;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint32 event_param1;
|
||||||
|
int32 event_param1_s;
|
||||||
|
};
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint32 event_param2;
|
||||||
|
int32 event_param2_s;
|
||||||
|
};
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint32 event_param3;
|
||||||
|
int32 event_param3_s;
|
||||||
|
};
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint32 event_param4;
|
||||||
|
int32 event_param4_s;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _action
|
||||||
|
{
|
||||||
|
uint16 type;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint32 param1;
|
||||||
|
int32 param1_s;
|
||||||
|
};
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint32 param2;
|
||||||
|
int32 param2_s;
|
||||||
|
};
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint32 param3;
|
||||||
|
int32 param3_s;
|
||||||
|
};
|
||||||
|
}action[MAX_ACTIONS];
|
||||||
|
};
|
||||||
|
//Event_Map
|
||||||
|
typedef UNORDERED_MAP<uint32, std::vector<CreatureEventAI_Event> > CreatureEventAI_Event_Map;
|
||||||
|
|
||||||
|
struct CreatureEventAI_Summon
|
||||||
|
{
|
||||||
|
uint32 id;
|
||||||
|
|
||||||
|
float position_x;
|
||||||
|
float position_y;
|
||||||
|
float position_z;
|
||||||
|
float orientation;
|
||||||
|
uint32 SpawnTimeSecs;
|
||||||
|
};
|
||||||
|
|
||||||
|
//EventSummon_Map
|
||||||
|
typedef UNORDERED_MAP<uint32, CreatureEventAI_Summon> CreatureEventAI_Summon_Map;
|
||||||
|
|
||||||
|
struct CreatureEventAIHolder
|
||||||
|
{
|
||||||
|
CreatureEventAIHolder(CreatureEventAI_Event p) : Event(p), Time(0), Enabled(true){}
|
||||||
|
|
||||||
|
CreatureEventAI_Event Event;
|
||||||
|
uint32 Time;
|
||||||
|
bool Enabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MANGOS_DLL_SPEC CreatureEventAI : public CreatureAI
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
CreatureEventAI(Creature &c);
|
||||||
|
~CreatureEventAI()
|
||||||
|
{
|
||||||
|
CreatureEventAIList.clear();
|
||||||
|
}
|
||||||
|
void JustRespawned();
|
||||||
|
void Reset();
|
||||||
|
void JustReachedHome();
|
||||||
|
void EnterEvadeMode();
|
||||||
|
void JustDied(Unit* killer);
|
||||||
|
void KilledUnit(Unit* victim);
|
||||||
|
void JustSummoned(Creature* pUnit);
|
||||||
|
void Aggro(Unit *who);
|
||||||
|
void AttackStart(Unit *who);
|
||||||
|
void MoveInLineOfSight(Unit *who);
|
||||||
|
void SpellHit(Unit* pUnit, const SpellEntry* pSpell);
|
||||||
|
void UpdateAI(const uint32 diff);
|
||||||
|
bool IsVisible(Unit *) const;
|
||||||
|
static int Permissible(const Creature *);
|
||||||
|
|
||||||
|
bool ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pActionInvoker = NULL);
|
||||||
|
void ProcessAction(uint16 type, uint32 param1, uint32 param2, uint32 param3, uint32 rnd, uint32 EventId, Unit* pActionInvoker);
|
||||||
|
inline uint32 GetRandActionParam(uint32 rnd, uint32 param1, uint32 param2, uint32 param3);
|
||||||
|
inline Unit* GetTargetByType(uint32 Target, Unit* pActionInvoker);
|
||||||
|
inline Unit* SelectUnit(AttackingTarget target, uint32 position);
|
||||||
|
|
||||||
|
void DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target);
|
||||||
|
void DoZoneInCombat(Unit* pUnit);
|
||||||
|
void DoMeleeAttackIfReady();
|
||||||
|
bool CanCast(Unit* Target, SpellEntry const *Spell, bool Triggered);
|
||||||
|
bool ReceiveEmote(Player* pPlayer, Creature* pCreature, uint32 uiEmote);
|
||||||
|
|
||||||
|
Unit* DoSelectLowestHpFriendly(float range, uint32 MinHPDiff);
|
||||||
|
void DoFindFriendlyMissingBuff(std::list<Creature*>& _list, float range, uint32 spellid);
|
||||||
|
void DoFindFriendlyCC(std::list<Creature*>& _list, float range);
|
||||||
|
|
||||||
|
//Pointer to creature we are manipulating
|
||||||
|
Creature& m_creature;
|
||||||
|
|
||||||
|
//Bool for if we are in combat or not
|
||||||
|
bool InCombat;
|
||||||
|
|
||||||
|
//Holder for events (stores enabled, time, and eventid)
|
||||||
|
std::list<CreatureEventAIHolder> CreatureEventAIList;
|
||||||
|
uint32 EventUpdateTime; //Time between event updates
|
||||||
|
uint32 EventDiff; //Time between the last event call
|
||||||
|
bool bEmptyList;
|
||||||
|
|
||||||
|
//Variables used by Events themselves
|
||||||
|
uint8 Phase; //Current phase, max 32 phases
|
||||||
|
bool CombatMovementEnabled; //If we allow targeted movment gen (movement twoards top threat)
|
||||||
|
bool MeleeEnabled; //If we allow melee auto attack
|
||||||
|
uint32 AttackDistance; //Distance to attack from
|
||||||
|
float AttackAngle; //Angle of attack
|
||||||
|
};
|
||||||
|
#endif
|
||||||
560
src/game/CreatureEventAIMgr.cpp
Normal file
560
src/game/CreatureEventAIMgr.cpp
Normal file
|
|
@ -0,0 +1,560 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Database/DatabaseEnv.h"
|
||||||
|
#include "Database/SQLStorage.h"
|
||||||
|
#include "CreatureEventAI.h"
|
||||||
|
#include "CreatureEventAIMgr.h"
|
||||||
|
#include "ObjectMgr.h"
|
||||||
|
#include "ProgressBar.h"
|
||||||
|
#include "Policies/SingletonImp.h"
|
||||||
|
#include "ObjectDefines.h"
|
||||||
|
|
||||||
|
INSTANTIATE_SINGLETON_1(CreatureEventAIMgr);
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
void CreatureEventAIMgr::LoadCreatureEventAI_Texts()
|
||||||
|
{
|
||||||
|
// Drop Existing Text Map, only done once and we are ready to add data from multiple sources.
|
||||||
|
m_CreatureEventAI_TextMap.clear();
|
||||||
|
|
||||||
|
// Load EventAI Text
|
||||||
|
LoadMangosStrings(WorldDatabase,"creature_ai_texts",-1,1+(TEXT_SOURCE_RANGE));
|
||||||
|
|
||||||
|
// Gather Additional data from EventAI Texts
|
||||||
|
QueryResult *result = WorldDatabase.PQuery("SELECT entry, sound, type, language, emote FROM creature_ai_texts");
|
||||||
|
|
||||||
|
sLog.outString("Loading EventAI Texts additional data...");
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
barGoLink bar(result->GetRowCount());
|
||||||
|
uint32 count = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
bar.step();
|
||||||
|
Field* fields = result->Fetch();
|
||||||
|
StringTextData temp;
|
||||||
|
|
||||||
|
int32 i = fields[0].GetInt32();
|
||||||
|
temp.SoundId = fields[1].GetInt32();
|
||||||
|
temp.Type = fields[2].GetInt32();
|
||||||
|
temp.Language = fields[3].GetInt32();
|
||||||
|
temp.Emote = fields[4].GetInt32();
|
||||||
|
|
||||||
|
if (i >= 0)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` is not a negative value.",i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i <= TEXT_SOURCE_RANGE)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` is out of accepted entry range for table.",i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (temp.SoundId)
|
||||||
|
{
|
||||||
|
if (!GetSoundEntriesStore()->LookupEntry(temp.SoundId))
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` has soundId %u but sound does not exist.",i,temp.SoundId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetLanguageDescByID(temp.Language))
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` using Language %u but Language does not exist.",i,temp.Language);
|
||||||
|
|
||||||
|
if (temp.Type > CHAT_TYPE_BOSS_WHISPER)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` has Type %u but this Chat Type does not exist.",i,temp.Type);
|
||||||
|
|
||||||
|
m_CreatureEventAI_TextMap[i] = temp;
|
||||||
|
++count;
|
||||||
|
} while (result->NextRow());
|
||||||
|
|
||||||
|
delete result;
|
||||||
|
|
||||||
|
sLog.outString();
|
||||||
|
sLog.outString(">> Loaded %u additional CreatureEventAI Texts data.", count);
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
barGoLink bar(1);
|
||||||
|
bar.step();
|
||||||
|
sLog.outString();
|
||||||
|
sLog.outString(">> Loaded 0 additional CreatureEventAI Texts data. DB table `creature_ai_texts` is empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
void CreatureEventAIMgr::LoadCreatureEventAI_Summons()
|
||||||
|
{
|
||||||
|
|
||||||
|
//Drop Existing EventSummon Map
|
||||||
|
m_CreatureEventAI_Summon_Map.clear();
|
||||||
|
|
||||||
|
//Gather additional data for EventAI
|
||||||
|
QueryResult *result = WorldDatabase.PQuery("SELECT id, position_x, position_y, position_z, orientation, spawntimesecs FROM creature_ai_summons");
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
barGoLink bar(result->GetRowCount());
|
||||||
|
uint32 Count = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
bar.step();
|
||||||
|
Field *fields = result->Fetch();
|
||||||
|
|
||||||
|
CreatureEventAI_Summon temp;
|
||||||
|
|
||||||
|
uint32 i = fields[0].GetUInt32();
|
||||||
|
temp.position_x = fields[1].GetFloat();
|
||||||
|
temp.position_y = fields[2].GetFloat();
|
||||||
|
temp.position_z = fields[3].GetFloat();
|
||||||
|
temp.orientation = fields[4].GetFloat();
|
||||||
|
temp.SpawnTimeSecs = fields[5].GetUInt32();
|
||||||
|
|
||||||
|
//Add to map
|
||||||
|
m_CreatureEventAI_Summon_Map[i] = temp;
|
||||||
|
++Count;
|
||||||
|
}while (result->NextRow());
|
||||||
|
|
||||||
|
delete result;
|
||||||
|
|
||||||
|
sLog.outString();
|
||||||
|
sLog.outString(">> Loaded %u CreatureEventAI summon definitions", Count);
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
barGoLink bar(1);
|
||||||
|
bar.step();
|
||||||
|
sLog.outString();
|
||||||
|
sLog.outString(">> Loaded 0 CreatureEventAI Summon definitions. DB table `creature_ai_summons` is empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
|
||||||
|
{
|
||||||
|
//Drop Existing EventAI List
|
||||||
|
m_CreatureEventAI_Event_Map.clear();
|
||||||
|
|
||||||
|
//Gather event data
|
||||||
|
QueryResult *result = WorldDatabase.PQuery("SELECT id, creature_id, event_type, event_inverse_phase_mask, event_chance, event_flags, "
|
||||||
|
"event_param1, event_param2, event_param3, event_param4, "
|
||||||
|
"action1_type, action1_param1, action1_param2, action1_param3, "
|
||||||
|
"action2_type, action2_param1, action2_param2, action2_param3, "
|
||||||
|
"action3_type, action3_param1, action3_param2, action3_param3 "
|
||||||
|
"FROM creature_ai_scripts");
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
barGoLink bar(result->GetRowCount());
|
||||||
|
uint32 Count = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
bar.step();
|
||||||
|
Field *fields = result->Fetch();
|
||||||
|
|
||||||
|
CreatureEventAI_Event temp;
|
||||||
|
|
||||||
|
temp.event_id = fields[0].GetUInt32();
|
||||||
|
uint32 i = temp.event_id;
|
||||||
|
temp.creature_id = fields[1].GetUInt32();
|
||||||
|
uint32 creature_id = temp.creature_id;
|
||||||
|
temp.event_type = fields[2].GetUInt16();
|
||||||
|
temp.event_inverse_phase_mask = fields[3].GetUInt32();
|
||||||
|
temp.event_chance = fields[4].GetUInt8();
|
||||||
|
temp.event_flags = fields[5].GetUInt8();
|
||||||
|
temp.event_param1 = fields[6].GetUInt32();
|
||||||
|
temp.event_param2 = fields[7].GetUInt32();
|
||||||
|
temp.event_param3 = fields[8].GetUInt32();
|
||||||
|
temp.event_param4 = fields[9].GetUInt32();
|
||||||
|
|
||||||
|
CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(temp.creature_id);
|
||||||
|
//Creature does not exist in database
|
||||||
|
if (!cInfo)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u has script for non-existing creature.", i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Report any errors in event
|
||||||
|
if (temp.event_type >= EVENT_T_END)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u has incorrect event type. Maybe DB requires updated version of SD2.", i);
|
||||||
|
|
||||||
|
//No chance of this event occuring
|
||||||
|
if (temp.event_chance == 0)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u has 0 percent chance. Event will never trigger!", i);
|
||||||
|
|
||||||
|
//Chance above 100, force it to be 100
|
||||||
|
if (temp.event_chance > 100)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Creature %u are using event %u with more than 100 percent chance. Adjusting to 100 percent.", temp.creature_id, i);
|
||||||
|
temp.event_chance = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Individual event checks
|
||||||
|
switch (temp.event_type)
|
||||||
|
{
|
||||||
|
case EVENT_T_HP:
|
||||||
|
case EVENT_T_MANA:
|
||||||
|
case EVENT_T_TARGET_HP:
|
||||||
|
{
|
||||||
|
if (temp.event_param2 > 100)
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EVENT_T_SPELLHIT:
|
||||||
|
{
|
||||||
|
if (temp.event_param1)
|
||||||
|
{
|
||||||
|
SpellEntry const* pSpell = GetSpellStore()->LookupEntry(temp.event_param1);
|
||||||
|
if (!pSpell)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Creature %u has non-existant SpellID(%u) defined in event %u.", temp.creature_id, temp.event_param1, i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (temp.event_param2_s != -1 && temp.event_param2 != 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: fix this system with SPELL_SCHOOL_MASK. Current complicate things, using int32(-1) instead of just 0
|
||||||
|
//SPELL_SCHOOL_MASK_NONE = 0 and does not exist, thus it can not ever trigger or be used in SpellHit()
|
||||||
|
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)
|
||||||
|
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_RANGE:
|
||||||
|
case EVENT_T_OOC_LOS:
|
||||||
|
case EVENT_T_FRIENDLY_HP:
|
||||||
|
case EVENT_T_FRIENDLY_IS_CC:
|
||||||
|
case EVENT_T_FRIENDLY_MISSING_BUFF:
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EVENT_T_TIMER:
|
||||||
|
case EVENT_T_TIMER_OOC:
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EVENT_T_KILL:
|
||||||
|
case EVENT_T_TARGET_CASTING:
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EVENT_T_AGGRO:
|
||||||
|
case EVENT_T_DEATH:
|
||||||
|
case EVENT_T_EVADE:
|
||||||
|
case EVENT_T_SPAWNED:
|
||||||
|
case EVENT_T_REACHED_HOME:
|
||||||
|
{
|
||||||
|
if (temp.event_flags & EFLAG_REPEATABLE)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Creature %u has EFLAG_REPEATABLE set. Event can never be repeatable. Removing flag for event %u.", temp.creature_id, i);
|
||||||
|
temp.event_flags &= ~EFLAG_REPEATABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32 j = 0; j < MAX_ACTIONS; j++)
|
||||||
|
{
|
||||||
|
temp.action[j].type = fields[10+(j*4)].GetUInt16();
|
||||||
|
temp.action[j].param1 = fields[11+(j*4)].GetUInt32();
|
||||||
|
temp.action[j].param2 = fields[12+(j*4)].GetUInt32();
|
||||||
|
temp.action[j].param3 = fields[13+(j*4)].GetUInt32();
|
||||||
|
|
||||||
|
//Report any errors in actions
|
||||||
|
switch (temp.action[j].type)
|
||||||
|
{
|
||||||
|
case ACTION_T_TEXT:
|
||||||
|
{
|
||||||
|
if (temp.action[j].param1_s < 0)
|
||||||
|
{
|
||||||
|
if (m_CreatureEventAI_TextMap.find(temp.action[j].param1_s) == m_CreatureEventAI_TextMap.end())
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 refrences non-existing entry in texts table.", i, j+1);
|
||||||
|
}
|
||||||
|
if (temp.action[j].param2_s < 0)
|
||||||
|
{
|
||||||
|
if (m_CreatureEventAI_TextMap.find(temp.action[j].param2_s) == m_CreatureEventAI_TextMap.end())
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param2 refrences non-existing entry in texts table.", i, j+1);
|
||||||
|
|
||||||
|
if (!temp.action[j].param1_s)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u has param2, but param1 is not set. Required for randomized text.", i, j+1);
|
||||||
|
}
|
||||||
|
if (temp.action[j].param3_s < 0)
|
||||||
|
{
|
||||||
|
if (m_CreatureEventAI_TextMap.find(temp.action[j].param3_s) == m_CreatureEventAI_TextMap.end())
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param3 refrences non-existing entry in texts table.", i, j+1);
|
||||||
|
|
||||||
|
if (!temp.action[j].param1_s || !temp.action[j].param2_s)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u has param3, but param1 and/or param2 is not set. Required for randomized text.", i, j+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ACTION_T_SET_FACTION:
|
||||||
|
if (temp.action[j].param1 !=0 && !GetFactionStore()->LookupEntry(temp.action[j].param1))
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant FactionId %u.", i, j+1, temp.action[j].param1);
|
||||||
|
temp.action[j].param1 = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ACTION_T_MORPH_TO_ENTRY_OR_MODEL:
|
||||||
|
if (temp.action[j].param1 !=0 || temp.action[j].param2 !=0)
|
||||||
|
{
|
||||||
|
if (temp.action[j].param1 && !GetCreatureTemplateStore(temp.action[j].param1))
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Creature entry %u.", i, j+1, temp.action[j].param1);
|
||||||
|
temp.action[j].param1 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (temp.action[j].param2 && !GetCreatureDisplayStore()->LookupEntry(temp.action[j].param2))
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant ModelId %u.", i, j+1, temp.action[j].param2);
|
||||||
|
temp.action[j].param2 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ACTION_T_SOUND:
|
||||||
|
if (!GetSoundEntriesStore()->LookupEntry(temp.action[j].param1))
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SoundID %u.", i, j+1, temp.action[j].param1);
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
case ACTION_T_RANDOM_SOUND:
|
||||||
|
{
|
||||||
|
if(!GetSoundEntriesStore()->LookupEntry(temp.action[j].param1))
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 uses non-existant SoundID %u.", i, j+1, temp.action[j].param1);
|
||||||
|
if(!GetSoundEntriesStore()->LookupEntry(temp.action[j].param2))
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param2 uses non-existant SoundID %u.", i, j+1, temp.action[j].param2);
|
||||||
|
if(!GetSoundEntriesStore()->LookupEntry(temp.action[j].param3))
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param3 uses non-existant SoundID %u.", i, j+1, temp.action[j].param3);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
case ACTION_T_CAST:
|
||||||
|
{
|
||||||
|
const SpellEntry *spell = GetSpellStore()->LookupEntry(temp.action[j].param1);
|
||||||
|
if (!spell)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param1);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (spell->RecoveryTime > 0 && temp.event_flags & EFLAG_REPEATABLE)
|
||||||
|
{
|
||||||
|
//output as debug for now, also because there's no general rule all spells have RecoveryTime
|
||||||
|
if (temp.event_param3 < spell->RecoveryTime)
|
||||||
|
debug_log("CreatureEventAI: Event %u Action %u uses SpellID %u but cooldown is longer(%u) than minumum defined in event param3(%u).", i, j+1,temp.action[j].param1, spell->RecoveryTime, temp.event_param3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (temp.action[j].param2 >= TARGET_T_END)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ACTION_T_REMOVEAURASFROMSPELL:
|
||||||
|
{
|
||||||
|
if (!GetSpellStore()->LookupEntry(temp.action[j].param2))
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2);
|
||||||
|
|
||||||
|
if (temp.action[j].param1 >= TARGET_T_END)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ACTION_T_QUEST_EVENT:
|
||||||
|
{
|
||||||
|
if (Quest const* qid = GetQuestTemplateStore(temp.action[j].param1))
|
||||||
|
{
|
||||||
|
if (!qid->HasFlag(QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT))
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u. SpecialFlags for quest entry %u does not include |2, Action will not have any effect.", i, j+1, temp.action[j].param1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Quest entry %u.", i, j+1, temp.action[j].param1);
|
||||||
|
|
||||||
|
if (temp.action[j].param2 >= TARGET_T_END)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ACTION_T_QUEST_EVENT_ALL:
|
||||||
|
{
|
||||||
|
if (Quest const* qid = GetQuestTemplateStore(temp.action[j].param1))
|
||||||
|
{
|
||||||
|
if (!qid->HasFlag(QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT))
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u. SpecialFlags for quest entry %u does not include |2, Action will not have any effect.", i, j+1, temp.action[j].param1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Quest entry %u.", i, j+1, temp.action[j].param1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ACTION_T_CASTCREATUREGO:
|
||||||
|
{
|
||||||
|
if (!GetCreatureTemplateStore(temp.action[j].param1))
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1);
|
||||||
|
|
||||||
|
if (!GetSpellStore()->LookupEntry(temp.action[j].param2))
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2);
|
||||||
|
|
||||||
|
if (temp.action[j].param3 >= TARGET_T_END)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ACTION_T_CASTCREATUREGO_ALL:
|
||||||
|
{
|
||||||
|
if (!GetQuestTemplateStore(temp.action[j].param1))
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Quest entry %u.", i, j+1, temp.action[j].param1);
|
||||||
|
|
||||||
|
if (!GetSpellStore()->LookupEntry(temp.action[j].param2))
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
//2nd param target
|
||||||
|
case ACTION_T_SUMMON_ID:
|
||||||
|
{
|
||||||
|
if (!GetCreatureTemplateStore(temp.action[j].param1))
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1);
|
||||||
|
|
||||||
|
if (m_CreatureEventAI_Summon_Map.find(temp.action[j].param3) == m_CreatureEventAI_Summon_Map.end())
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u summons missing CreatureEventAI_Summon %u", i, j+1, temp.action[j].param3);
|
||||||
|
|
||||||
|
if (temp.action[j].param2 >= TARGET_T_END)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ACTION_T_KILLED_MONSTER:
|
||||||
|
{
|
||||||
|
if (!GetCreatureTemplateStore(temp.action[j].param1))
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1);
|
||||||
|
|
||||||
|
if (temp.action[j].param2 >= TARGET_T_END)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ACTION_T_SUMMON:
|
||||||
|
{
|
||||||
|
if (!GetCreatureTemplateStore(temp.action[j].param1))
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1);
|
||||||
|
|
||||||
|
if (temp.action[j].param2 >= TARGET_T_END)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ACTION_T_THREAT_SINGLE_PCT:
|
||||||
|
case ACTION_T_SET_UNIT_FLAG:
|
||||||
|
case ACTION_T_REMOVE_UNIT_FLAG:
|
||||||
|
if (temp.action[j].param2 >= TARGET_T_END)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
//3rd param target
|
||||||
|
case ACTION_T_SET_UNIT_FIELD:
|
||||||
|
if (temp.action[j].param1 < OBJECT_END || temp.action[j].param1 >= UNIT_END)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 (UNIT_FIELD*). Index out of range for intended use.", i, j+1);
|
||||||
|
if (temp.action[j].param3 >= TARGET_T_END)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACTION_T_SET_PHASE:
|
||||||
|
if (temp.action[j].param1 > 31)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phase > 31. Phase mask cannot be used past phase 31.", i, j+1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACTION_T_INC_PHASE:
|
||||||
|
if (!temp.action[j].param1)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u is incrementing phase by 0. Was this intended?", i, j+1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACTION_T_SET_INST_DATA:
|
||||||
|
{
|
||||||
|
if (!(temp.event_flags & EFLAG_NORMAL) && !(temp.event_flags & EFLAG_HEROIC))
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u. Cannot set instance data without event flags (normal/heroic).", i, j+1);
|
||||||
|
|
||||||
|
if (temp.action[j].param2 > 4/*SPECIAL*/)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set instance data above encounter state 4. Custom case?", i, j+1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ACTION_T_SET_INST_DATA64:
|
||||||
|
{
|
||||||
|
if (!(temp.event_flags & EFLAG_NORMAL) && !(temp.event_flags & EFLAG_HEROIC))
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u. Cannot set instance data without event flags (normal/heroic).", i, j+1);
|
||||||
|
|
||||||
|
if (temp.action[j].param2 >= TARGET_T_END)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ACTION_T_UPDATE_TEMPLATE:
|
||||||
|
{
|
||||||
|
if (!GetCreatureTemplateStore(temp.action[j].param1))
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ACTION_T_RANDOM_SAY:
|
||||||
|
case ACTION_T_RANDOM_YELL:
|
||||||
|
case ACTION_T_RANDOM_TEXTEMOTE:
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u currently unused ACTION type. Did you forget to update database?", i, j+1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (temp.action[j].type >= ACTION_T_END)
|
||||||
|
sLog.outErrorDb("CreatureEventAI: Event %u Action %u has incorrect action type. Maybe DB requires updated version of SD2.", i, j+1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add to list
|
||||||
|
m_CreatureEventAI_Event_Map[creature_id].push_back(temp);
|
||||||
|
++Count;
|
||||||
|
} while (result->NextRow());
|
||||||
|
|
||||||
|
delete result;
|
||||||
|
|
||||||
|
sLog.outString();
|
||||||
|
sLog.outString(">> Loaded %u CreatureEventAI scripts", Count);
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
barGoLink bar(1);
|
||||||
|
bar.step();
|
||||||
|
sLog.outString();
|
||||||
|
sLog.outString(">> Loaded 0 CreatureEventAI scripts. DB table `creature_ai_scripts` is empty.");
|
||||||
|
}
|
||||||
|
}
|
||||||
46
src/game/CreatureEventAIMgr.h
Normal file
46
src/game/CreatureEventAIMgr.h
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MANGOS_CREATURE_EAI_MGR_H
|
||||||
|
#define MANGOS_CREATURE_EAI_MGR_H
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "CreatureEventAI.h"
|
||||||
|
|
||||||
|
class CreatureEventAIMgr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CreatureEventAIMgr(){};
|
||||||
|
~CreatureEventAIMgr(){};
|
||||||
|
|
||||||
|
void LoadCreatureEventAI_Texts();
|
||||||
|
void LoadCreatureEventAI_Summons();
|
||||||
|
void LoadCreatureEventAI_Scripts();
|
||||||
|
|
||||||
|
CreatureEventAI_Event_Map& GetCreatureEventAIMap() { return m_CreatureEventAI_Event_Map; }
|
||||||
|
CreatureEventAI_Summon_Map& GetCreatureEventAISummonMap() { return m_CreatureEventAI_Summon_Map; }
|
||||||
|
CreatureEventAI_TextMap& GetCreatureEventAITextMap() { return m_CreatureEventAI_TextMap; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
CreatureEventAI_Event_Map m_CreatureEventAI_Event_Map;
|
||||||
|
CreatureEventAI_Summon_Map m_CreatureEventAI_Summon_Map;
|
||||||
|
CreatureEventAI_TextMap m_CreatureEventAI_TextMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CreatureEAI_Mgr MaNGOS::Singleton<CreatureEventAIMgr>::Instance()
|
||||||
|
#endif
|
||||||
|
|
@ -42,12 +42,16 @@ enum AchievementFactionFlags
|
||||||
|
|
||||||
enum AchievementFlags
|
enum AchievementFlags
|
||||||
{
|
{
|
||||||
ACHIEVEMENT_FLAG_COUNTER = 0x00000001,
|
ACHIEVEMENT_FLAG_COUNTER = 0x00000001, // Just count statistic (never stop and complete)
|
||||||
ACHIEVEMENT_FLAG_REACH_LEVEL = 0x00000004,
|
ACHIEVEMENT_FLAG_UNK2 = 0x00000002, // not used
|
||||||
ACHIEVEMENT_FLAG_RERERED_MAX = 0x00000010, // displays the maximum criteria of a refered achievement
|
ACHIEVEMENT_FLAG_STORE_MAX_VALUE = 0x00000004, // Store only max value? used only in "Reach level xx"
|
||||||
ACHIEVEMENT_FLAG_AVERAGE = 0x00000040,
|
ACHIEVEMENT_FLAG_SUMM = 0x00000008, // Use summ criteria value from all reqirements (and calculate max value)
|
||||||
ACHIEVEMENT_FLAG_REALM_FIRST_REACH= 0x00000100,
|
ACHIEVEMENT_FLAG_MAX_USED = 0x00000010, // Show max criteria (and calculate max value ??)
|
||||||
ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200,
|
ACHIEVEMENT_FLAG_REQ_COUNT = 0x00000020, // Use not zero req count (and calculate max value)
|
||||||
|
ACHIEVEMENT_FLAG_AVERANGE = 0x00000040, // Show as averange value (value / time_in_days) depend from other flag (by def use last criteria value)
|
||||||
|
ACHIEVEMENT_FLAG_BAR = 0x00000080, // Show as progress bar (value / max vale) depend from other flag (by def use last criteria value)
|
||||||
|
ACHIEVEMENT_FLAG_REALM_FIRST_REACH = 0x00000100, //
|
||||||
|
ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200, //
|
||||||
};
|
};
|
||||||
|
|
||||||
enum AchievementCriteriaCondition
|
enum AchievementCriteriaCondition
|
||||||
|
|
@ -63,8 +67,12 @@ enum AchievementCriteriaCondition
|
||||||
|
|
||||||
enum AchievementCriteriaCompletionFlags
|
enum AchievementCriteriaCompletionFlags
|
||||||
{
|
{
|
||||||
// some Achievements (like 698) have several criteria but only one has to be fulfilled. These are identified by this flag.
|
ACHIEVEMENT_CRITERIA_FLAG_SHOW_PROGRESS_BAR = 0x00000001, // Show progress as bar
|
||||||
ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL = 2,
|
ACHIEVEMENT_CRITERIA_FLAG_HIDE_CRITERIA = 0x00000002, // Not show criteria in client
|
||||||
|
ACHIEVEMENT_CRITERIA_FLAG_UNK3 = 0x00000004, // BG related??
|
||||||
|
ACHIEVEMENT_CRITERIA_FLAG_UNK4 = 0x00000008, //
|
||||||
|
ACHIEVEMENT_CRITERIA_FLAG_UNK5 = 0x00000010, // not used
|
||||||
|
ACHIEVEMENT_CRITERIA_FLAG_MONEY_COUNTER = 0x00000020, // Displays counter as money
|
||||||
};
|
};
|
||||||
|
|
||||||
enum AchievementCriteriaGroupFlags
|
enum AchievementCriteriaGroupFlags
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ DBCStorage <CharTitlesEntry> sCharTitlesStore(CharTitlesEntryfmt);
|
||||||
DBCStorage <ChatChannelsEntry> sChatChannelsStore(ChatChannelsEntryfmt);
|
DBCStorage <ChatChannelsEntry> sChatChannelsStore(ChatChannelsEntryfmt);
|
||||||
DBCStorage <ChrClassesEntry> sChrClassesStore(ChrClassesEntryfmt);
|
DBCStorage <ChrClassesEntry> sChrClassesStore(ChrClassesEntryfmt);
|
||||||
DBCStorage <ChrRacesEntry> sChrRacesStore(ChrRacesEntryfmt);
|
DBCStorage <ChrRacesEntry> sChrRacesStore(ChrRacesEntryfmt);
|
||||||
|
DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore(CinematicSequencesEntryfmt);
|
||||||
DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore(CreatureDisplayInfofmt);
|
DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore(CreatureDisplayInfofmt);
|
||||||
DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore(CreatureFamilyfmt);
|
DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore(CreatureFamilyfmt);
|
||||||
DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore(CreatureSpellDatafmt);
|
DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore(CreatureSpellDatafmt);
|
||||||
|
|
@ -76,7 +77,9 @@ DBCStorage <GtOCTRegenHPEntry> sGtOCTRegenHPStore(GtOCTRegenHPfmt);
|
||||||
//DBCStorage <GtOCTRegenMPEntry> sGtOCTRegenMPStore(GtOCTRegenMPfmt); -- not used currently
|
//DBCStorage <GtOCTRegenMPEntry> sGtOCTRegenMPStore(GtOCTRegenMPfmt); -- not used currently
|
||||||
DBCStorage <GtRegenHPPerSptEntry> sGtRegenHPPerSptStore(GtRegenHPPerSptfmt);
|
DBCStorage <GtRegenHPPerSptEntry> sGtRegenHPPerSptStore(GtRegenHPPerSptfmt);
|
||||||
DBCStorage <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore(GtRegenMPPerSptfmt);
|
DBCStorage <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore(GtRegenMPPerSptfmt);
|
||||||
|
|
||||||
DBCStorage <HolidaysEntry> sHolidaysStore(Holidaysfmt);
|
DBCStorage <HolidaysEntry> sHolidaysStore(Holidaysfmt);
|
||||||
|
|
||||||
DBCStorage <ItemEntry> sItemStore(Itemfmt);
|
DBCStorage <ItemEntry> sItemStore(Itemfmt);
|
||||||
DBCStorage <ItemBagFamilyEntry> sItemBagFamilyStore(ItemBagFamilyfmt);
|
DBCStorage <ItemBagFamilyEntry> sItemBagFamilyStore(ItemBagFamilyfmt);
|
||||||
//DBCStorage <ItemCondExtCostsEntry> sItemCondExtCostsStore(ItemCondExtCostsEntryfmt);
|
//DBCStorage <ItemCondExtCostsEntry> sItemCondExtCostsStore(ItemCondExtCostsEntryfmt);
|
||||||
|
|
@ -91,6 +94,7 @@ DBCStorage <LockEntry> sLockStore(LockEntryfmt);
|
||||||
|
|
||||||
DBCStorage <MailTemplateEntry> sMailTemplateStore(MailTemplateEntryfmt);
|
DBCStorage <MailTemplateEntry> sMailTemplateStore(MailTemplateEntryfmt);
|
||||||
DBCStorage <MapEntry> sMapStore(MapEntryfmt);
|
DBCStorage <MapEntry> sMapStore(MapEntryfmt);
|
||||||
|
DBCStorage <MovieEntry> sMovieStore(MovieEntryfmt);
|
||||||
|
|
||||||
DBCStorage <QuestSortEntry> sQuestSortStore(QuestSortEntryfmt);
|
DBCStorage <QuestSortEntry> sQuestSortStore(QuestSortEntryfmt);
|
||||||
|
|
||||||
|
|
@ -194,7 +198,7 @@ void LoadDBCStores(const std::string& dataPath)
|
||||||
{
|
{
|
||||||
std::string dbcPath = dataPath+"dbc/";
|
std::string dbcPath = dataPath+"dbc/";
|
||||||
|
|
||||||
const uint32 DBCFilesCount = 75;
|
const uint32 DBCFilesCount = 77;
|
||||||
|
|
||||||
barGoLink bar( DBCFilesCount );
|
barGoLink bar( DBCFilesCount );
|
||||||
|
|
||||||
|
|
@ -231,6 +235,7 @@ void LoadDBCStores(const std::string& dataPath)
|
||||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChatChannelsStore, dbcPath,"ChatChannels.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChatChannelsStore, dbcPath,"ChatChannels.dbc");
|
||||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrClassesStore, dbcPath,"ChrClasses.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrClassesStore, dbcPath,"ChrClasses.dbc");
|
||||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrRacesStore, dbcPath,"ChrRaces.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrRacesStore, dbcPath,"ChrRaces.dbc");
|
||||||
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCinematicSequencesStore, dbcPath,"CinematicSequences.dbc");
|
||||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureDisplayInfoStore, dbcPath,"CreatureDisplayInfo.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureDisplayInfoStore, dbcPath,"CreatureDisplayInfo.dbc");
|
||||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureFamilyStore, dbcPath,"CreatureFamily.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureFamilyStore, dbcPath,"CreatureFamily.dbc");
|
||||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureSpellDataStore, dbcPath,"CreatureSpellData.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureSpellDataStore, dbcPath,"CreatureSpellData.dbc");
|
||||||
|
|
@ -281,6 +286,7 @@ void LoadDBCStores(const std::string& dataPath)
|
||||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sLockStore, dbcPath,"Lock.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sLockStore, dbcPath,"Lock.dbc");
|
||||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMailTemplateStore, dbcPath,"MailTemplate.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMailTemplateStore, dbcPath,"MailTemplate.dbc");
|
||||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapStore, dbcPath,"Map.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapStore, dbcPath,"Map.dbc");
|
||||||
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMovieStore, dbcPath,"Movie.dbc");
|
||||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestSortStore, dbcPath,"QuestSort.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestSortStore, dbcPath,"QuestSort.dbc");
|
||||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sRandomPropertiesPointsStore, dbcPath,"RandPropPoints.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sRandomPropertiesPointsStore, dbcPath,"RandPropPoints.dbc");
|
||||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatDistributionStore, dbcPath,"ScalingStatDistribution.dbc");
|
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatDistributionStore, dbcPath,"ScalingStatDistribution.dbc");
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ extern DBCStorage <CharStartOutfitEntry> sCharStartOutfitStore;
|
||||||
extern DBCStorage <CharTitlesEntry> sCharTitlesStore;
|
extern DBCStorage <CharTitlesEntry> sCharTitlesStore;
|
||||||
extern DBCStorage <ChrClassesEntry> sChrClassesStore;
|
extern DBCStorage <ChrClassesEntry> sChrClassesStore;
|
||||||
extern DBCStorage <ChrRacesEntry> sChrRacesStore;
|
extern DBCStorage <ChrRacesEntry> sChrRacesStore;
|
||||||
|
extern DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore;
|
||||||
extern DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore;
|
extern DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore;
|
||||||
extern DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore;
|
extern DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore;
|
||||||
extern DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore;
|
extern DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore;
|
||||||
|
|
@ -106,6 +107,7 @@ extern DBCStorage <ItemSetEntry> sItemSetStore;
|
||||||
extern DBCStorage <LockEntry> sLockStore;
|
extern DBCStorage <LockEntry> sLockStore;
|
||||||
extern DBCStorage <MailTemplateEntry> sMailTemplateStore;
|
extern DBCStorage <MailTemplateEntry> sMailTemplateStore;
|
||||||
extern DBCStorage <MapEntry> sMapStore;
|
extern DBCStorage <MapEntry> sMapStore;
|
||||||
|
extern DBCStorage <MovieEntry> sMovieStore;
|
||||||
extern DBCStorage <QuestSortEntry> sQuestSortStore;
|
extern DBCStorage <QuestSortEntry> sQuestSortStore;
|
||||||
extern DBCStorage <RandomPropertiesPointsEntry> sRandomPropertiesPointsStore;
|
extern DBCStorage <RandomPropertiesPointsEntry> sRandomPropertiesPointsStore;
|
||||||
extern DBCStorage <ScalingStatDistributionEntry> sScalingStatDistributionStore;
|
extern DBCStorage <ScalingStatDistributionEntry> sScalingStatDistributionStore;
|
||||||
|
|
|
||||||
|
|
@ -649,6 +649,27 @@ struct ChrRacesEntry
|
||||||
uint32 addon; // 68 (0 - original race, 1 - tbc addon, ...)
|
uint32 addon; // 68 (0 - original race, 1 - tbc addon, ...)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* not used
|
||||||
|
struct CinematicCameraEntry
|
||||||
|
{
|
||||||
|
uint32 id; // 0 index
|
||||||
|
char* filename; // 1
|
||||||
|
uint32 soundid; // 2 in SoundEntries.dbc or 0
|
||||||
|
float start_x; // 3
|
||||||
|
float start_y; // 4
|
||||||
|
float start_z; // 5
|
||||||
|
float unk6; // 6 speed?
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct CinematicSequencesEntry
|
||||||
|
{
|
||||||
|
uint32 Id; // 0 index
|
||||||
|
//uint32 unk1; // 1 always 0
|
||||||
|
//uint32 cinematicCamera; // 2 id in CinematicCamera.dbc
|
||||||
|
// 3-9 always 0
|
||||||
|
};
|
||||||
|
|
||||||
struct CreatureDisplayInfoEntry
|
struct CreatureDisplayInfoEntry
|
||||||
{
|
{
|
||||||
uint32 Displayid; // 0 m_ID
|
uint32 Displayid; // 0 m_ID
|
||||||
|
|
@ -1079,6 +1100,13 @@ struct MapEntry
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MovieEntry
|
||||||
|
{
|
||||||
|
uint32 Id; // 0 index
|
||||||
|
//char* filename; // 1
|
||||||
|
//uint32 unk2; // 2 always 100
|
||||||
|
};
|
||||||
|
|
||||||
struct QuestSortEntry
|
struct QuestSortEntry
|
||||||
{
|
{
|
||||||
uint32 id; // 0 m_ID
|
uint32 id; // 0 m_ID
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ const char ChatChannelsEntryfmt[]="iixssssssssssssssssxxxxxxxxxxxxxxxxxx";
|
||||||
// ChatChannelsEntryfmt, index not used (more compact store)
|
// ChatChannelsEntryfmt, index not used (more compact store)
|
||||||
const char ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii";
|
const char ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii";
|
||||||
const char ChrRacesEntryfmt[]="nxixiixxixxxxissssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi";
|
const char ChrRacesEntryfmt[]="nxixiixxixxxxissssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi";
|
||||||
|
const char CinematicSequencesEntryfmt[]="nxxxxxxxxx";
|
||||||
const char CreatureDisplayInfofmt[]="nxxxfxxxxxxxxxxx";
|
const char CreatureDisplayInfofmt[]="nxxxfxxxxxxxxxxx";
|
||||||
const char CreatureFamilyfmt[]="nfifiiiiixssssssssssssssssxx";
|
const char CreatureFamilyfmt[]="nfifiiiiixssssssssssssssssxx";
|
||||||
const char CreatureSpellDatafmt[]="nxxxxxxxx";
|
const char CreatureSpellDatafmt[]="nxxxxxxxx";
|
||||||
|
|
@ -70,6 +71,7 @@ const char ItemSetEntryfmt[]="dssssssssssssssssxxxxxxxxxxxxxxxxxxiiiiiiiiiiiiiii
|
||||||
const char LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx";
|
const char LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx";
|
||||||
const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||||
const char MapEntryfmt[]="nxixssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiffiixxix";
|
const char MapEntryfmt[]="nxixssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiffiixxix";
|
||||||
|
const char MovieEntryfmt[]="nxx";
|
||||||
const char QuestSortEntryfmt[]="nxxxxxxxxxxxxxxxxx";
|
const char QuestSortEntryfmt[]="nxxxxxxxxxxxxxxxxx";
|
||||||
const char RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii";
|
const char RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii";
|
||||||
const char ScalingStatDistributionfmt[]="niiiiiiiiiiiiiiiiiiiii";
|
const char ScalingStatDistributionfmt[]="niiiiiiiiiiiiiiiiiiiii";
|
||||||
|
|
|
||||||
|
|
@ -633,6 +633,62 @@ namespace MaNGOS
|
||||||
|
|
||||||
// Unit checks
|
// Unit checks
|
||||||
|
|
||||||
|
class MostHPMissingInRange
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MostHPMissingInRange(Unit const* obj, float range, uint32 hp) : i_obj(obj), i_range(range), i_hp(hp) {}
|
||||||
|
bool operator()(Unit* u)
|
||||||
|
{
|
||||||
|
if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) && u->GetMaxHealth() - u->GetHealth() > i_hp)
|
||||||
|
{
|
||||||
|
i_hp = u->GetMaxHealth() - u->GetHealth();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Unit const* i_obj;
|
||||||
|
float i_range;
|
||||||
|
uint32 i_hp;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FriendlyCCedInRange
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FriendlyCCedInRange(Unit const* obj, float range) : i_obj(obj), i_range(range) {}
|
||||||
|
bool operator()(Unit* u)
|
||||||
|
{
|
||||||
|
if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) &&
|
||||||
|
(u->isFeared() || u->isCharmed() || u->isFrozen() || u->hasUnitState(UNIT_STAT_STUNNED) || u->hasUnitState(UNIT_STAT_CONFUSED)))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Unit const* i_obj;
|
||||||
|
float i_range;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FriendlyMissingBuffInRange
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FriendlyMissingBuffInRange(Unit const* obj, float range, uint32 spellid) : i_obj(obj), i_range(range), i_spell(spellid) {}
|
||||||
|
bool operator()(Unit* u)
|
||||||
|
{
|
||||||
|
if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) &&
|
||||||
|
!(u->HasAura(i_spell, 0) || u->HasAura(i_spell, 1) || u->HasAura(i_spell, 2)))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Unit const* i_obj;
|
||||||
|
float i_range;
|
||||||
|
uint32 i_spell;
|
||||||
|
};
|
||||||
|
|
||||||
class AnyUnfriendlyUnitInObjectRangeCheck
|
class AnyUnfriendlyUnitInObjectRangeCheck
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -62,5 +62,13 @@ class MANGOS_DLL_SPEC InstanceData
|
||||||
|
|
||||||
//called on creature creation
|
//called on creature creation
|
||||||
virtual void OnCreatureCreate(Creature * /*creature*/, uint32 /*creature_entry*/) {}
|
virtual void OnCreatureCreate(Creature * /*creature*/, uint32 /*creature_entry*/) {}
|
||||||
|
|
||||||
|
//All-purpose data storage 64 bit
|
||||||
|
virtual uint64 GetData64(uint32 /*Data*/) { return 0; }
|
||||||
|
virtual void SetData64(uint32 /*Data*/, uint64 /*Value*/) { }
|
||||||
|
|
||||||
|
//All-purpose data storage 32 bit
|
||||||
|
virtual uint32 GetData(uint32 /*Type*/) { return 0; }
|
||||||
|
virtual void SetData(uint32 /*Type*/, uint32 /*Data*/) {}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -765,7 +765,12 @@ enum MangosStrings
|
||||||
LANG_RESET_PET_TALENTS_ONLINE = 1127,
|
LANG_RESET_PET_TALENTS_ONLINE = 1127,
|
||||||
// Room for more level 3 1128-1199 not used
|
// Room for more level 3 1128-1199 not used
|
||||||
|
|
||||||
// FREE IDS 1200-9999
|
// Debug commands
|
||||||
|
LANG_CINEMATIC_NOT_EXIST = 1200,
|
||||||
|
LANG_MOVIE_NOT_EXIST = 1201,
|
||||||
|
// Room for more debug 1202-1299 not used
|
||||||
|
|
||||||
|
// FREE IDS 1300-9999
|
||||||
|
|
||||||
// Use for not-in-offcial-sources patches
|
// Use for not-in-offcial-sources patches
|
||||||
// 10000-10999
|
// 10000-10999
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ bool ChatHandler::HandleReloadAllCommand(const char*)
|
||||||
{
|
{
|
||||||
HandleReloadSkillFishingBaseLevelCommand("");
|
HandleReloadSkillFishingBaseLevelCommand("");
|
||||||
|
|
||||||
|
HandleReloadAllAchievementCommand("");
|
||||||
HandleReloadAllAreaCommand("");
|
HandleReloadAllAreaCommand("");
|
||||||
HandleReloadAllLootCommand("");
|
HandleReloadAllLootCommand("");
|
||||||
HandleReloadAllNpcCommand("");
|
HandleReloadAllNpcCommand("");
|
||||||
|
|
@ -70,6 +71,13 @@ bool ChatHandler::HandleReloadAllCommand(const char*)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ChatHandler::HandleReloadAllAchievementCommand(const char*)
|
||||||
|
{
|
||||||
|
HandleReloadAchievementCriteriaDataCommand("");
|
||||||
|
HandleReloadAchievementRewardCommand("");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ChatHandler::HandleReloadAllAreaCommand(const char*)
|
bool ChatHandler::HandleReloadAllAreaCommand(const char*)
|
||||||
{
|
{
|
||||||
//HandleReloadQuestAreaTriggersCommand(""); -- reloaded in HandleReloadAllQuestCommand
|
//HandleReloadQuestAreaTriggersCommand(""); -- reloaded in HandleReloadAllQuestCommand
|
||||||
|
|
@ -155,6 +163,7 @@ bool ChatHandler::HandleReloadAllItemCommand(const char*)
|
||||||
|
|
||||||
bool ChatHandler::HandleReloadAllLocalesCommand(const char* /*args*/)
|
bool ChatHandler::HandleReloadAllLocalesCommand(const char* /*args*/)
|
||||||
{
|
{
|
||||||
|
HandleReloadLocalesAchievementRewardCommand("a");
|
||||||
HandleReloadLocalesCreatureCommand("a");
|
HandleReloadLocalesCreatureCommand("a");
|
||||||
HandleReloadLocalesGameobjectCommand("a");
|
HandleReloadLocalesGameobjectCommand("a");
|
||||||
HandleReloadLocalesItemCommand("a");
|
HandleReloadLocalesItemCommand("a");
|
||||||
|
|
@ -173,6 +182,22 @@ bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ChatHandler::HandleReloadAchievementCriteriaDataCommand(const char*)
|
||||||
|
{
|
||||||
|
sLog.outString( "Re-Loading Additional Achievement Criteria Data..." );
|
||||||
|
achievementmgr.LoadAchievementCriteriaData();
|
||||||
|
SendGlobalSysMessage("DB table `achievement_criteria_data` reloaded.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChatHandler::HandleReloadAchievementRewardCommand(const char*)
|
||||||
|
{
|
||||||
|
sLog.outString( "Re-Loading Achievement Reward Data..." );
|
||||||
|
achievementmgr.LoadRewards();
|
||||||
|
SendGlobalSysMessage("DB table `achievement_reward` reloaded.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*)
|
bool ChatHandler::HandleReloadAreaTriggerTavernCommand(const char*)
|
||||||
{
|
{
|
||||||
sLog.outString( "Re-Loading Tavern Area Triggers..." );
|
sLog.outString( "Re-Loading Tavern Area Triggers..." );
|
||||||
|
|
@ -670,6 +695,14 @@ bool ChatHandler::HandleReloadGameTeleCommand(const char* /*arg*/)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ChatHandler::HandleReloadLocalesAchievementRewardCommand(const char*)
|
||||||
|
{
|
||||||
|
sLog.outString( "Re-Loading Locales Achievement Reward Data..." );
|
||||||
|
achievementmgr.LoadRewardLocales();
|
||||||
|
SendGlobalSysMessage("DB table `locales_achievement_reward` reloaded.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ChatHandler::HandleReloadLocalesCreatureCommand(const char* /*arg*/)
|
bool ChatHandler::HandleReloadLocalesCreatureCommand(const char* /*arg*/)
|
||||||
{
|
{
|
||||||
sLog.outString( "Re-Loading Locales Creature ...");
|
sLog.outString( "Re-Loading Locales Creature ...");
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,10 @@ libmangosgame_a_SOURCES = \
|
||||||
CreatureAIRegistry.h \
|
CreatureAIRegistry.h \
|
||||||
CreatureAISelector.cpp \
|
CreatureAISelector.cpp \
|
||||||
CreatureAISelector.h \
|
CreatureAISelector.h \
|
||||||
|
CreatureEventAI.cpp \
|
||||||
|
CreatureEventAI.h \
|
||||||
|
CreatureEventAIMgr.cpp \
|
||||||
|
CreatureEventAIMgr.h \
|
||||||
Creature.cpp \
|
Creature.cpp \
|
||||||
Creature.h \
|
Creature.h \
|
||||||
DBCEnums.h \
|
DBCEnums.h \
|
||||||
|
|
|
||||||
|
|
@ -1616,8 +1616,6 @@ float Map::GetHeight(float x, float y, float z, bool pUseVmaps) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "World.h"
|
|
||||||
|
|
||||||
uint16 Map::GetAreaFlag(float x, float y, float z) const
|
uint16 Map::GetAreaFlag(float x, float y, float z) const
|
||||||
{
|
{
|
||||||
uint16 areaflag;
|
uint16 areaflag;
|
||||||
|
|
@ -1642,9 +1640,9 @@ uint16 Map::GetAreaFlag(float x, float y, float z) const
|
||||||
case 2456: // Death's Breach (Eastern Plaguelands)
|
case 2456: // Death's Breach (Eastern Plaguelands)
|
||||||
if(z > 350.0f) areaflag = 1950; break;
|
if(z > 350.0f) areaflag = 1950; break;
|
||||||
// Dalaran
|
// Dalaran
|
||||||
case 1593:
|
case 1593: // Crystalsong Forest
|
||||||
case 2484:
|
case 2484: // The Twilight Rivulet (Crystalsong Forest)
|
||||||
case 2492:
|
case 2492: // Forlorn Woods (Crystalsong Forest)
|
||||||
if (x > 5568.0f && x < 6116.0f && y > 282.0f && y < 982.0f && z > 563.0f) areaflag = 2153; break;
|
if (x > 5568.0f && x < 6116.0f && y > 282.0f && y < 982.0f && z > 563.0f) areaflag = 2153; break;
|
||||||
// Maw of Neltharion (cave)
|
// Maw of Neltharion (cave)
|
||||||
case 164: // Dragonblight
|
case 164: // Dragonblight
|
||||||
|
|
@ -1652,6 +1650,27 @@ uint16 Map::GetAreaFlag(float x, float y, float z) const
|
||||||
case 1827: // Wintergrasp
|
case 1827: // Wintergrasp
|
||||||
case 2591: // The Cauldron of Flames (Wintergrasp)
|
case 2591: // The Cauldron of Flames (Wintergrasp)
|
||||||
if (x > 4364.0f && x < 4632.0f && y > 1545.0f && y < 1886.0f && z < 200.0f) areaflag = 1853; break;
|
if (x > 4364.0f && x < 4632.0f && y > 1545.0f && y < 1886.0f && z < 200.0f) areaflag = 1853; break;
|
||||||
|
// Undercity (sewers enter and path)
|
||||||
|
case 179: // Tirisfal Glades
|
||||||
|
if (x > 1595.0f && x < 1699.0f && y > 535.0f && y < 643.5f && z < 30.5f) areaflag = 685; break;
|
||||||
|
// Undercity (Royal Quarter)
|
||||||
|
case 210: // Silverpine Forest
|
||||||
|
case 316: // The Shining Strand (Silverpine Forest)
|
||||||
|
case 438: // Lordamere Lake (Silverpine Forest)
|
||||||
|
if (x > 1237.0f && x < 1401.0f && y > 284.0f && y < 440.0f && z < -40.0f) areaflag = 685; break;
|
||||||
|
// Undercity (cave and ground zone, part of royal quarter)
|
||||||
|
case 607: // Ruins of Lordaeron (Tirisfal Glades)
|
||||||
|
// ground and near to ground (by city walls)
|
||||||
|
if(z > 0.0f)
|
||||||
|
{
|
||||||
|
if (x > 1510.0f && x < 1839.0f && y > 29.77f && y < 433.0f) areaflag = 685;
|
||||||
|
}
|
||||||
|
// more wide underground, part of royal quarter
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (x > 1299.0f && x < 1839.0f && y > 10.0f && y < 440.0f) areaflag = 685;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return areaflag;
|
return areaflag;
|
||||||
|
|
|
||||||
|
|
@ -2404,7 +2404,7 @@ void Player::InitStatsForLevel(bool reapplyMods)
|
||||||
SetUInt32Value(PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE,0);
|
SetUInt32Value(PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE,0);
|
||||||
for(int i = 0; i < MAX_SPELL_SCHOOL; ++i)
|
for(int i = 0; i < MAX_SPELL_SCHOOL; ++i)
|
||||||
{
|
{
|
||||||
SetFloatValue(UNIT_FIELD_POWER_COST_MODIFIER+i,0.0f);
|
SetUInt32Value(UNIT_FIELD_POWER_COST_MODIFIER+i,0);
|
||||||
SetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+i,0.0f);
|
SetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+i,0.0f);
|
||||||
}
|
}
|
||||||
// Reset no reagent cost field
|
// Reset no reagent cost field
|
||||||
|
|
@ -18969,14 +18969,17 @@ bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const
|
||||||
|
|
||||||
bool Player::CanUseBattleGroundObject()
|
bool Player::CanUseBattleGroundObject()
|
||||||
{
|
{
|
||||||
|
// TODO : some spells gives player ForceReaction to one faction (ReputationMgr::ApplyForceReaction)
|
||||||
|
// maybe gameobject code should handle that ForceReaction usage
|
||||||
|
// BUG: sometimes when player clicks on flag in AB - client won't send gameobject_use, only gameobject_report_use packet
|
||||||
return ( //InBattleGround() && // in battleground - not need, check in other cases
|
return ( //InBattleGround() && // in battleground - not need, check in other cases
|
||||||
//!IsMounted() && - not correct, player is dismounted when he clicks on flag
|
//!IsMounted() && - not correct, player is dismounted when he clicks on flag
|
||||||
//i'm not sure if these two are correct, because invisible players should get visible when they click on flag
|
//player cannot use object when he is invulnerable (immune)
|
||||||
!isTotalImmune() && // not totally immune
|
!isTotalImmune() && // not totally immune
|
||||||
|
//i'm not sure if these two are correct, because invisible players should get visible when they click on flag
|
||||||
!HasStealthAura() && // not stealthed
|
!HasStealthAura() && // not stealthed
|
||||||
!HasInvisibilityAura() && // not invisible
|
!HasInvisibilityAura() && // not invisible
|
||||||
!HasAura(SPELL_RECENTLY_DROPPED_FLAG, 0) && // can't pickup
|
!HasAura(SPELL_RECENTLY_DROPPED_FLAG, 0) && // can't pickup
|
||||||
//TODO player cannot use object when he is invulnerable (immune) - (ice block, divine shield, divine protection, divine intervention ...)
|
|
||||||
isAlive() // live player
|
isAlive() // live player
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -373,7 +373,7 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
|
||||||
damage = uint32(damage * (m_caster->GetTotalAttackPowerValue(BASE_ATTACK)) / 100);
|
damage = uint32(damage * (m_caster->GetTotalAttackPowerValue(BASE_ATTACK)) / 100);
|
||||||
}
|
}
|
||||||
// Shield Slam
|
// Shield Slam
|
||||||
else if(m_spellInfo->SpellFamilyFlags & 0x0000020000000000LL)
|
else if(m_spellInfo->SpellFamilyFlags & 0x0000020000000000LL && m_spellInfo->Category==1209)
|
||||||
damage += int32(m_caster->GetShieldBlockValue());
|
damage += int32(m_caster->GetShieldBlockValue());
|
||||||
// Victory Rush
|
// Victory Rush
|
||||||
else if(m_spellInfo->SpellFamilyFlags & 0x10000000000LL)
|
else if(m_spellInfo->SpellFamilyFlags & 0x10000000000LL)
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ void HostilReference::sourceObjectDestroyLink()
|
||||||
//============================================================
|
//============================================================
|
||||||
// Inform the source, that the status of the reference changed
|
// Inform the source, that the status of the reference changed
|
||||||
|
|
||||||
void HostilReference::fireStatusChanged(const ThreatRefStatusChangeEvent& pThreatRefStatusChangeEvent)
|
void HostilReference::fireStatusChanged(ThreatRefStatusChangeEvent& pThreatRefStatusChangeEvent)
|
||||||
{
|
{
|
||||||
if(getSource())
|
if(getSource())
|
||||||
getSource()->processThreatEvent(&pThreatRefStatusChangeEvent);
|
getSource()->processThreatEvent(&pThreatRefStatusChangeEvent);
|
||||||
|
|
@ -97,7 +97,11 @@ void HostilReference::addThreat(float pMod)
|
||||||
if(!isOnline())
|
if(!isOnline())
|
||||||
updateOnlineStatus();
|
updateOnlineStatus();
|
||||||
if(pMod != 0.0f)
|
if(pMod != 0.0f)
|
||||||
fireStatusChanged(ThreatRefStatusChangeEvent(UEV_THREAT_REF_THREAT_CHANGE, this, pMod));
|
{
|
||||||
|
ThreatRefStatusChangeEvent event(UEV_THREAT_REF_THREAT_CHANGE, this, pMod);
|
||||||
|
fireStatusChanged(event);
|
||||||
|
}
|
||||||
|
|
||||||
if(isValid() && pMod >= 0)
|
if(isValid() && pMod >= 0)
|
||||||
{
|
{
|
||||||
Unit* victim_owner = getTarget()->GetOwner();
|
Unit* victim_owner = getTarget()->GetOwner();
|
||||||
|
|
@ -153,7 +157,9 @@ void HostilReference::setOnlineOfflineState(bool pIsOnline)
|
||||||
iOnline = pIsOnline;
|
iOnline = pIsOnline;
|
||||||
if(!iOnline)
|
if(!iOnline)
|
||||||
setAccessibleState(false); // if not online that not accessable as well
|
setAccessibleState(false); // if not online that not accessable as well
|
||||||
fireStatusChanged(ThreatRefStatusChangeEvent(UEV_THREAT_REF_ONLINE_STATUS, this));
|
|
||||||
|
ThreatRefStatusChangeEvent event(UEV_THREAT_REF_ONLINE_STATUS, this);
|
||||||
|
fireStatusChanged(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -164,7 +170,9 @@ void HostilReference::setAccessibleState(bool pIsAccessible)
|
||||||
if(iAccessible != pIsAccessible)
|
if(iAccessible != pIsAccessible)
|
||||||
{
|
{
|
||||||
iAccessible = pIsAccessible;
|
iAccessible = pIsAccessible;
|
||||||
fireStatusChanged(ThreatRefStatusChangeEvent(UEV_THREAT_REF_ASSECCIBLE_STATUS, this));
|
|
||||||
|
ThreatRefStatusChangeEvent event(UEV_THREAT_REF_ASSECCIBLE_STATUS, this);
|
||||||
|
fireStatusChanged(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -175,7 +183,9 @@ void HostilReference::setAccessibleState(bool pIsAccessible)
|
||||||
void HostilReference::removeReference()
|
void HostilReference::removeReference()
|
||||||
{
|
{
|
||||||
invalidate();
|
invalidate();
|
||||||
fireStatusChanged(ThreatRefStatusChangeEvent(UEV_THREAT_REF_REMOVE_FROM_LIST, this));
|
|
||||||
|
ThreatRefStatusChangeEvent event(UEV_THREAT_REF_REMOVE_FROM_LIST, this);
|
||||||
|
fireStatusChanged(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================
|
//============================================================
|
||||||
|
|
@ -355,12 +365,18 @@ void ThreatManager::addThreat(Unit* pVictim, float pThreat, SpellSchoolMask scho
|
||||||
//players and pets have only InHateListOf
|
//players and pets have only InHateListOf
|
||||||
//HateOfflineList is used co contain unattackable victims (in-flight, in-water, GM etc.)
|
//HateOfflineList is used co contain unattackable victims (in-flight, in-water, GM etc.)
|
||||||
|
|
||||||
if (pVictim == getOwner()) // only for same creatures :)
|
// not to self
|
||||||
|
if (pVictim == getOwner())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// not to GM
|
||||||
if(!pVictim || (pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)pVictim)->isGameMaster()) )
|
if(!pVictim || (pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)pVictim)->isGameMaster()) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// not to dead and not for dead
|
||||||
|
if(!pVictim->isAlive() || !getOwner()->isAlive() )
|
||||||
|
return;
|
||||||
|
|
||||||
assert(getOwner()->GetTypeId()== TYPEID_UNIT);
|
assert(getOwner()->GetTypeId()== TYPEID_UNIT);
|
||||||
|
|
||||||
float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, schoolMask, pThreatSpell);
|
float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, schoolMask, pThreatSpell);
|
||||||
|
|
@ -444,18 +460,13 @@ void ThreatManager::setCurrentVictim(HostilReference* pHostilReference)
|
||||||
// The hated unit is gone, dead or deleted
|
// The hated unit is gone, dead or deleted
|
||||||
// return true, if the event is consumed
|
// return true, if the event is consumed
|
||||||
|
|
||||||
bool ThreatManager::processThreatEvent(const UnitBaseEvent* pUnitBaseEvent)
|
void ThreatManager::processThreatEvent(ThreatRefStatusChangeEvent* threatRefStatusChangeEvent)
|
||||||
{
|
{
|
||||||
bool consumed = false;
|
|
||||||
|
|
||||||
ThreatRefStatusChangeEvent* threatRefStatusChangeEvent;
|
|
||||||
HostilReference* hostilReference;
|
|
||||||
|
|
||||||
threatRefStatusChangeEvent = (ThreatRefStatusChangeEvent*) pUnitBaseEvent;
|
|
||||||
threatRefStatusChangeEvent->setThreatManager(this); // now we can set the threat manager
|
threatRefStatusChangeEvent->setThreatManager(this); // now we can set the threat manager
|
||||||
hostilReference = threatRefStatusChangeEvent->getReference();
|
|
||||||
|
|
||||||
switch(pUnitBaseEvent->getType())
|
HostilReference* hostilReference = threatRefStatusChangeEvent->getReference();
|
||||||
|
|
||||||
|
switch(threatRefStatusChangeEvent->getType())
|
||||||
{
|
{
|
||||||
case UEV_THREAT_REF_THREAT_CHANGE:
|
case UEV_THREAT_REF_THREAT_CHANGE:
|
||||||
if((getCurrentVictim() == hostilReference && threatRefStatusChangeEvent->getFValue()<0.0f) ||
|
if((getCurrentVictim() == hostilReference && threatRefStatusChangeEvent->getFValue()<0.0f) ||
|
||||||
|
|
@ -493,5 +504,4 @@ bool ThreatManager::processThreatEvent(const UnitBaseEvent* pUnitBaseEvent)
|
||||||
iThreatOfflineContainer.remove(hostilReference);
|
iThreatOfflineContainer.remove(hostilReference);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return consumed;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,20 +43,8 @@ class ThreatCalcHelper
|
||||||
};
|
};
|
||||||
|
|
||||||
//==============================================================
|
//==============================================================
|
||||||
|
|
||||||
class MANGOS_DLL_SPEC HostilReference : public Reference<Unit, ThreatManager>
|
class MANGOS_DLL_SPEC HostilReference : public Reference<Unit, ThreatManager>
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
float iThreat;
|
|
||||||
float iTempThreatModifyer; // used for taunt
|
|
||||||
uint64 iUnitGuid;
|
|
||||||
bool iOnline;
|
|
||||||
bool iAccessible;
|
|
||||||
private:
|
|
||||||
// Inform the source, that the status of that reference was changed
|
|
||||||
void fireStatusChanged(const ThreatRefStatusChangeEvent& pThreatRefStatusChangeEvent);
|
|
||||||
|
|
||||||
Unit* getSourceUnit();
|
|
||||||
public:
|
public:
|
||||||
HostilReference(Unit* pUnit, ThreatManager *pThreatManager, float pThreat);
|
HostilReference(Unit* pUnit, ThreatManager *pThreatManager, float pThreat);
|
||||||
|
|
||||||
|
|
@ -123,6 +111,17 @@ class MANGOS_DLL_SPEC HostilReference : public Reference<Unit, ThreatManager>
|
||||||
|
|
||||||
// Tell our refFrom (source) object, that the link is cut (Target destroyed)
|
// Tell our refFrom (source) object, that the link is cut (Target destroyed)
|
||||||
void sourceObjectDestroyLink();
|
void sourceObjectDestroyLink();
|
||||||
|
private:
|
||||||
|
// Inform the source, that the status of that reference was changed
|
||||||
|
void fireStatusChanged(ThreatRefStatusChangeEvent& pThreatRefStatusChangeEvent);
|
||||||
|
|
||||||
|
Unit* getSourceUnit();
|
||||||
|
private:
|
||||||
|
float iThreat;
|
||||||
|
float iTempThreatModifyer; // used for taunt
|
||||||
|
uint64 iUnitGuid;
|
||||||
|
bool iOnline;
|
||||||
|
bool iAccessible;
|
||||||
};
|
};
|
||||||
|
|
||||||
//==============================================================
|
//==============================================================
|
||||||
|
|
@ -168,12 +167,9 @@ class MANGOS_DLL_SPEC ThreatContainer
|
||||||
|
|
||||||
class MANGOS_DLL_SPEC ThreatManager
|
class MANGOS_DLL_SPEC ThreatManager
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
HostilReference* iCurrentVictim;
|
|
||||||
Unit* iOwner;
|
|
||||||
ThreatContainer iThreatContainer;
|
|
||||||
ThreatContainer iThreatOfflineContainer;
|
|
||||||
public:
|
public:
|
||||||
|
friend class HostilReference;
|
||||||
|
|
||||||
explicit ThreatManager(Unit *pOwner);
|
explicit ThreatManager(Unit *pOwner);
|
||||||
|
|
||||||
~ThreatManager() { clearReferences(); }
|
~ThreatManager() { clearReferences(); }
|
||||||
|
|
@ -187,7 +183,7 @@ class MANGOS_DLL_SPEC ThreatManager
|
||||||
|
|
||||||
bool isThreatListEmpty() { return iThreatContainer.empty();}
|
bool isThreatListEmpty() { return iThreatContainer.empty();}
|
||||||
|
|
||||||
bool processThreatEvent(const UnitBaseEvent* pUnitBaseEvent);
|
void processThreatEvent(ThreatRefStatusChangeEvent* threatRefStatusChangeEvent);
|
||||||
|
|
||||||
HostilReference* getCurrentVictim() { return iCurrentVictim; }
|
HostilReference* getCurrentVictim() { return iCurrentVictim; }
|
||||||
|
|
||||||
|
|
@ -208,6 +204,11 @@ class MANGOS_DLL_SPEC ThreatManager
|
||||||
std::list<HostilReference*>& getOfflieThreatList() { return iThreatOfflineContainer.getThreatList(); }
|
std::list<HostilReference*>& getOfflieThreatList() { return iThreatOfflineContainer.getThreatList(); }
|
||||||
ThreatContainer& getOnlineContainer() { return iThreatContainer; }
|
ThreatContainer& getOnlineContainer() { return iThreatContainer; }
|
||||||
ThreatContainer& getOfflineContainer() { return iThreatOfflineContainer; }
|
ThreatContainer& getOfflineContainer() { return iThreatOfflineContainer; }
|
||||||
|
private:
|
||||||
|
HostilReference* iCurrentVictim;
|
||||||
|
Unit* iOwner;
|
||||||
|
ThreatContainer iThreatContainer;
|
||||||
|
ThreatContainer iThreatOfflineContainer;
|
||||||
};
|
};
|
||||||
|
|
||||||
//=================================================
|
//=================================================
|
||||||
|
|
|
||||||
|
|
@ -4424,10 +4424,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
||||||
case 9799:
|
case 9799:
|
||||||
case 25988:
|
case 25988:
|
||||||
{
|
{
|
||||||
// prevent damage back from weapon special attacks
|
|
||||||
if (!procSpell || procSpell->DmgClass != SPELL_DAMAGE_CLASS_MAGIC )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// return damage % to attacker but < 50% own total health
|
// return damage % to attacker but < 50% own total health
|
||||||
basepoints0 = triggerAmount*int32(damage)/100;
|
basepoints0 = triggerAmount*int32(damage)/100;
|
||||||
if(basepoints0 > GetMaxHealth()/2)
|
if(basepoints0 > GetMaxHealth()/2)
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@
|
||||||
#include "AchievementMgr.h"
|
#include "AchievementMgr.h"
|
||||||
#include "AuctionHouseMgr.h"
|
#include "AuctionHouseMgr.h"
|
||||||
#include "ObjectMgr.h"
|
#include "ObjectMgr.h"
|
||||||
|
#include "CreatureEventAIMgr.h"
|
||||||
#include "SpellMgr.h"
|
#include "SpellMgr.h"
|
||||||
#include "Chat.h"
|
#include "Chat.h"
|
||||||
#include "DBCStores.h"
|
#include "DBCStores.h"
|
||||||
|
|
@ -1269,6 +1270,7 @@ void World::SetInitialWorldSettings()
|
||||||
sLog.outString();
|
sLog.outString();
|
||||||
achievementmgr.LoadAchievementReferenceList();
|
achievementmgr.LoadAchievementReferenceList();
|
||||||
achievementmgr.LoadAchievementCriteriaList();
|
achievementmgr.LoadAchievementCriteriaList();
|
||||||
|
achievementmgr.LoadAchievementCriteriaData();
|
||||||
achievementmgr.LoadRewards();
|
achievementmgr.LoadRewards();
|
||||||
achievementmgr.LoadRewardLocales();
|
achievementmgr.LoadRewardLocales();
|
||||||
achievementmgr.LoadCompletedAchievements();
|
achievementmgr.LoadCompletedAchievements();
|
||||||
|
|
@ -1341,6 +1343,15 @@ void World::SetInitialWorldSettings()
|
||||||
sLog.outString( "Loading Scripts text locales..." ); // must be after Load*Scripts calls
|
sLog.outString( "Loading Scripts text locales..." ); // must be after Load*Scripts calls
|
||||||
objmgr.LoadDbScriptStrings();
|
objmgr.LoadDbScriptStrings();
|
||||||
|
|
||||||
|
sLog.outString( "Loading CreatureEventAI Texts...");
|
||||||
|
CreatureEAI_Mgr.LoadCreatureEventAI_Texts();
|
||||||
|
|
||||||
|
sLog.outString( "Loading CreatureEventAI Summons...");
|
||||||
|
CreatureEAI_Mgr.LoadCreatureEventAI_Summons();
|
||||||
|
|
||||||
|
sLog.outString( "Loading CreatureEventAI Scripts...");
|
||||||
|
CreatureEAI_Mgr.LoadCreatureEventAI_Scripts();
|
||||||
|
|
||||||
sLog.outString( "Initializing Scripts..." );
|
sLog.outString( "Initializing Scripts..." );
|
||||||
if(!LoadScriptingModule())
|
if(!LoadScriptingModule())
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
|
||||||
|
|
@ -212,6 +212,54 @@ bool ChatHandler::HandleDebugUpdateWorldStateCommand(const char* args)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ChatHandler::HandleDebugPlayCinematicCommand(const char* args)
|
||||||
|
{
|
||||||
|
// USAGE: .debug play cinematic #cinematicid
|
||||||
|
// #cinematicid - ID decimal number from CinemaicSequences.dbc (1st column)
|
||||||
|
if( !*args )
|
||||||
|
{
|
||||||
|
SendSysMessage(LANG_BAD_VALUE);
|
||||||
|
SetSentErrorMessage(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 dwId = atoi((char*)args);
|
||||||
|
|
||||||
|
if(!sCinematicSequencesStore.LookupEntry(dwId))
|
||||||
|
{
|
||||||
|
PSendSysMessage(LANG_CINEMATIC_NOT_EXIST, dwId);
|
||||||
|
SetSentErrorMessage(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_session->GetPlayer()->SendCinematicStart(dwId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChatHandler::HandleDebugPlayMovieCommand(const char* args)
|
||||||
|
{
|
||||||
|
// USAGE: .debug play movie #movieid
|
||||||
|
// #movieid - ID decimal number from Movie.dbc (1st column)
|
||||||
|
if( !*args )
|
||||||
|
{
|
||||||
|
SendSysMessage(LANG_BAD_VALUE);
|
||||||
|
SetSentErrorMessage(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 dwId = atoi((char*)args);
|
||||||
|
|
||||||
|
if(!sMovieStore.LookupEntry(dwId))
|
||||||
|
{
|
||||||
|
PSendSysMessage(LANG_MOVIE_NOT_EXIST, dwId);
|
||||||
|
SetSentErrorMessage(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_session->GetPlayer()->SendMovieStart(dwId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//Play sound
|
//Play sound
|
||||||
bool ChatHandler::HandleDebugPlaySoundCommand(const char* args)
|
bool ChatHandler::HandleDebugPlaySoundCommand(const char* args)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "7614"
|
#define REVISION_NR "7630"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
|
|
@ -573,6 +573,18 @@
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\src\game\DynamicObject.h">
|
RelativePath="..\..\src\game\DynamicObject.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\CreatureEventAI.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\CreatureEventAI.h">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\CreatureEventAIMgr.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\CreatureEventAIMgr.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\src\game\FleeingMovementGenerator.cpp">
|
RelativePath="..\..\src\game\FleeingMovementGenerator.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
|
|
||||||
|
|
@ -938,6 +938,22 @@
|
||||||
RelativePath="..\..\src\game\DynamicObject.h"
|
RelativePath="..\..\src\game\DynamicObject.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\CreatureEventAI.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\CreatureEventAI.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\CreatureEventAIMgr.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\CreatureEventAIMgr.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\src\game\FleeingMovementGenerator.cpp"
|
RelativePath="..\..\src\game\FleeingMovementGenerator.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -940,6 +940,22 @@
|
||||||
RelativePath="..\..\src\game\DynamicObject.h"
|
RelativePath="..\..\src\game\DynamicObject.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\CreatureEventAI.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\CreatureEventAI.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\CreatureEventAIMgr.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\CreatureEventAIMgr.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\src\game\FleeingMovementGenerator.cpp"
|
RelativePath="..\..\src\game\FleeingMovementGenerator.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue