Merge branch 'master' into 330

This commit is contained in:
VladimirMangos 2010-01-09 00:53:31 +03:00
commit 75c81894b2
18 changed files with 340 additions and 310 deletions

View file

@ -1,47 +1,48 @@
============================================= ======================================================
EventAI documentation: (updated May 19, 2009) EventAI Documentation: (Last Updated: January 8, 2010)
============================================= ======================================================
EventAI allows users to create new creature scripts entierly within the database. EventAI allows users to create new creature scripts entirely 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. 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 (...); UPDATE creature_template SET AIName = 'EventAI' WHERE entry IN (...);
========================================= =========================================
Basic structure of EventAI Basic Structure of EventAI
========================================= =========================================
EventAI follows a basic if (Event) then do (Action) format. EventAI follows a basic IF (Event) then DO (Action) format.
Below is the list of current fields of the creature_ai_scripts table. Below is the list of current fields of the creature_ai_scripts table.
(Field_Name) (Description) Field_Name Description
id This value is merely an incrementing counter of the current Event number. Required for sql queries. -------------------------------------------
creature_id Creature id which should trigger this event. id This value is merely an incrementing counter of the current Event number. Required for sql queries.
creature_id Creature ID which should trigger this event (This is from Creature_Template Table).
event_type The type of event (see "Event types" below) event_type The type of event (see "Event types" below)
event_inverse_phase_mask Mask with phases this event should NOT trigger in* event_inverse_phase_mask Mask with phases this event should NOT trigger in*
event_chance Percentage chance of triggering the event (1 - 100) event_chance Percentage chance of triggering the event (1 - 100)
event_flags Event flags (repeatable, ... (see below)) event_flags Event flags (repeatable, ... (see below))
event_param1 Variables for the event (depends on event_type) event_param1 Variables for the event (depends on event_type)
event_param2 event_param2 Variables for the event (depends on event_type)
event_param3 event_param3 Variables for the event (depends on event_type)
event_param4 event_param4 Variables for the event (depends on event_type)
action1_type An action to take when the event occurs (see "Action types" below) action1_type Action #1 to take when the Event occurs (see "Action types" below)
action1_param1 Variables used by Action1 (depends on action_type) action1_param1 Variables used by Action1 (depends on action_type)
action1_param2 action1_param2 Variables used by Action1 (depends on action_type)
action1_param3 action1_param3 Variables used by Action1 (depends on action_type)
action2_type action2_type Action #2 to take when the Event occurs (see "Action types" below)
action2_param1 action2_param1 Variables used by Action1 (depends on action_type)
action2_param2 action2_param2 Variables used by Action1 (depends on action_type)
action2_param3 action2_param3 Variables used by Action1 (depends on action_type)
action3_type action3_type Action #3 to take when the Event occurs (see "Action types" below)
action3_param1 action3_param1 Variables used by Action1 (depends on action_type)
action3_param2 action3_param2 Variables used by Action1 (depends on action_type)
action3_param3 action3_param3 Variables used by Action1 (depends on action_type)
All params are signed 32-bit values (+/- 2147483647). Time values are always in milliseconds. All params are signed 32-bit values (+/- 2147483647). Time values are always in milliseconds.
In case of a percentage value, use value/100 (ie. param = 500 then that means 500%, -50 = -50%) In case of a percentage value, use value/100 (ie. param = 500 then that means 500%, -50 = -50%)
@ -50,7 +51,7 @@ In case of a percentage value, use value/100 (ie. param = 500 then that means 50
========================================= =========================================
Event types Event Types
========================================= =========================================
A list of event types EventAI is able to handle. A list of event types EventAI is able to handle.
@ -60,17 +61,17 @@ Events will not repeat until the creature exits combat or unless EFLAG_REPEATABL
Some events such as EVENT_T_AGGRO, EVENT_T_DEATH, EVENT_T_SPAWNED, and EVENT_T_EVADE cannot repeat. Some events such as EVENT_T_AGGRO, EVENT_T_DEATH, EVENT_T_SPAWNED, and EVENT_T_EVADE cannot repeat.
# Internal name Param usage Description # Internal name Param usage Description
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0 EVENT_T_TIMER InitialMin, InitialMax, RepeatMin, RepeatMax Expires at first between (Param1) and (Param2) and then between every (Param3) and (Param4), but only in combat. 0 EVENT_T_TIMER InitialMin, InitialMax, RepeatMin, RepeatMax Expires at first between (Param1) and (Param2) and then will repeat between every (Param3) and (Param4), EXPIRES ONLY IN COMBAT.
1 EVENT_T_TIMER_OOC InitialMin, InitialMax, RepeatMin, RepeatMax Expires at first between (Param1) and (Param2) and then between every (Param3) and (Param4), but only out of combat. 1 EVENT_T_TIMER_OOC InitialMin, InitialMax, RepeatMin, RepeatMax Expires at first between (Param1) and (Param2) and then will repeat between every (Param3) and (Param4), EXPIRES 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). 2 EVENT_T_HP HPMax%, HPMin%, RepeatMin, RepeatMax Expires when the Creature's HP is between (Param1) and (Param2). Will repeat between 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). 3 EVENT_T_MANA ManaMax%,ManaMin% RepeatMin, RepeatMax Expires once the Creature's Mana% is between (Param1) and (Param2). Will repeat between every (Param3) and (Param4).
4 EVENT_T_AGGRO NONE Expires upon initial aggro (does not repeat). 4 EVENT_T_AGGRO NONE Expires ONLY upon the Creature's INITIAL Aggro at the Start of Combat (Does NOT Repeat).
5 EVENT_T_KILL RepeatMin, RepeatMax Expires upon killing a player. Will repeat between (Param1) and (Param2). 5 EVENT_T_KILL RepeatMin, RepeatMax Expires upon Killing a Player. Will repeat between (Param1) and (Param2).
6 EVENT_T_DEATH NONE Expires upon creature death. 6 EVENT_T_DEATH NONE Expires upon the Creature's Death. (This Triggers At The Moment The Creature Dies)
7 EVENT_T_EVADE NONE Expires upon creature EnterEvadeMode(). 7 EVENT_T_EVADE NONE Expires at the moment the Creature EnterEvadeMode().
8 EVENT_T_SPELLHIT SpellID, Schoolmask, RepeatMin, RepeatMax Expires upon a spell hit. When (param1) is set, it will be used as a trigger. With (param2) specified, the expiration is limited to specific spell schools (-1 for all). Will repeat every (Param3) and (Param4). 8 EVENT_T_SPELLHIT SpellID, Schoolmask, RepeatMin, RepeatMax Expires upon a Spell Hit on the Creature. When (param1) is set, it is the specific Spell ID used as the trigger. With (param2) specified, the expiration is limited to specific spell schools (-1 for all). Will repeat every (Param3) and (Param4). Only A Spell ID or Spell School may be Specified but NOT both.
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). 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 between every (Param3) and (Param4).
10 EVENT_T_OOC_LOS Hostile-or-Not, MaxAllowedRange, RepeatMin, RepeatMax Expires when a unit moves within distance (MaxAllowedRange) of a creature. If (Param1) is zero it will expire only when unit is hostile, friendly otherwise (Param1 = 1), depends generally on faction. Will repeat every (Param3) and (Param4). Does not expire when the creature is in combat. 10 EVENT_T_OOC_LOS Hostile-or-Not, MaxAllowedRange, RepeatMin, RepeatMax Expires when a unit moves within distance (MaxAllowedRange) of a creature. If (Param1) is zero it will expire only when unit is hostile, friendly otherwise (Param1 = 1), depends generally on faction. Will repeat every (Param3) and (Param4). Does not expire when the creature is in combat.
11 EVENT_T_SPAWNED NONE Expires on initial spawn and on creature respawn (useful for setting ranged movement type). 11 EVENT_T_SPAWNED NONE Expires on initial spawn and on 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). 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).
@ -79,8 +80,8 @@ Some events such as EVENT_T_AGGRO, EVENT_T_DEATH, EVENT_T_SPAWNED, and EVENT_T_E
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). 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 a spell (Param1) within 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 a 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 (Param1 = 0 means all spawns). Will repeat every (Param2) and (Param3). 17 EVENT_T_SUMMONED_UNIT CreatureId, RepeatMin, RepeatMax Expires after creature with entry = (Param1) is spawned (Param1 = 0 means all spawns). Will repeat every (Param2) and (Param3).
18 EVENT_T_TARGET_MANA ManaMax%, ManaMin%, RepeatMin, RepeatMax 18 EVENT_T_TARGET_MANA ManaMax%, ManaMin%, RepeatMin, RepeatMax Expires when current target's Mana is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
21 EVENT_T_REACHED_HOME NONE Expires when a creature reach it's home(spawn) location after evade. 21 EVENT_T_REACHED_HOME NONE Expires when a creature reaches it's home (spawn) location after evade.
22 EVENT_T_RECEIVE_EMOTE EmoteId, Condition, CondValue1, CondValue2 Expires when a creature receives an emote with emote text id (enum TextEmotes) in (Param1). Conditions can be defined (Param2) with optional values (Param3,Param4), see enum ConditionType. 22 EVENT_T_RECEIVE_EMOTE EmoteId, Condition, CondValue1, CondValue2 Expires when a creature receives an emote with emote text id (enum TextEmotes) in (Param1). Conditions can be defined (Param2) with optional values (Param3,Param4), see enum ConditionType.
23 EVENT_T_BUFFED SpellID, AmmountInStack, RepeatMin, RepeatMax Expires when a creature has spell (Param1) auras applied in a stack greater or equal to value provided in (Param2). Will repeat every (Param3) and (Param4). 23 EVENT_T_BUFFED SpellID, AmmountInStack, RepeatMin, RepeatMax Expires when a creature has spell (Param1) auras applied in a stack greater or equal to value provided in (Param2). Will repeat every (Param3) and (Param4).
24 EVENT_T_TARGET_BUFFED SpellID, AmmountInStack, RepeatMin, RepeatMax Expires when a target unit has spell (Param1) auras applied in a stack greater or equal to value provided in (Param2). Will repeat every (Param3) and (Param4). 24 EVENT_T_TARGET_BUFFED SpellID, AmmountInStack, RepeatMin, RepeatMax Expires when a target unit has spell (Param1) auras applied in a stack greater or equal to value provided in (Param2). Will repeat every (Param3) and (Param4).
@ -92,52 +93,53 @@ Action Types
A list of action types that EventAI can handle. A list of action types that EventAI can handle.
Each event type has its own specific interpretation of it's params, like every event type. Each event type has its own specific interpretation of it's params, like every event type.
For all ACTION_T_RANDOM, When a Particular Param is selected for the Event... The SAME Param # is selected for all 3 actions.
# Internal name Param usage Description # Internal name Param usage Description
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0 ACTION_T_NONE No Action Does nothing. 0 ACTION_T_NONE No Action Does nothing.
1 ACTION_T_TEXT -TextId1, -TextId2, -TextId3 Simply displays the specified -TextId. When -TextId2 and -TextId3 are specified, the selection will be randomized. Text types are defined, along with other options for the text, in a table below. All values needs to be negative. 1 ACTION_T_TEXT -TextId1, -TextId2, -TextId3 Simply displays the specified -TextId. When -TextId2 and -TextId3 are specified, the selection will be randomized. Text types are defined, along with other options for the text, in a table below. All values needs to be negative.
2 ACTION_T_SET_FACTION FactionId Changes faction for a creature. When param1 is zero, creature will revert to it's default faction. 2 ACTION_T_SET_FACTION FactionId Changes faction for a creature. When param1 is zero, creature will revert to it's default faction.
3 ACTION_T_MORPH_TO_ENTRY_OR_MODEL CreatureEntry, ModelId Set either model from creature_template.entry (Param1) OR explicit modelId (Param2). If (Param1) AND (Param2) are both 0, demorph and revert to the default model. 3 ACTION_T_MORPH_TO_ENTRY_OR_MODEL CreatureEntry, ModelId Set either model from creature_template.entry (Param1) OR explicit modelId (Param2). If (Param1) AND (Param2) are both 0, demorph and revert to the default model.
4 ACTION_T_SOUND SoundId Plays a sound 4 ACTION_T_SOUND SoundId Plays a sound
5 ACTION_T_EMOTE EmoteId Does an emote 5 ACTION_T_EMOTE EmoteId Does an emote
6 ACTION_T_RANDOM_SAY UNUSED 6 ACTION_T_RANDOM_SAY UNUSED UNUSED
7 ACTION_T_RANDOM_YELL UNUSED 7 ACTION_T_RANDOM_YELL UNUSED UNUSED
8 ACTION_T_RANDOM_TEXTEMOTE UNUSED 8 ACTION_T_RANDOM_TEXTEMOTE UNUSED UNUSED
9 ACTION_T_RANDOM_SOUND SoundId1, SoundId2, SoundId3 Plays a random sound * 9 ACTION_T_RANDOM_SOUND SoundId1, SoundId2, SoundId3 Plays a random sound *
10 ACTION_T_RANDOM_EMOTE EmoteId1, EmoteId2, EmoteId3 Emotes a random emote 10 ACTION_T_RANDOM_EMOTE EmoteId1, EmoteId2, EmoteId3 Emotes a random emote *
11 ACTION_T_CAST SpellId, Target, CastFlags Casts spell (Param1) on a target (Param2) using cast flags (specified below). 11 ACTION_T_CAST SpellId, Target, CastFlags Casts spell (Param1) on a target (Param2) using cast flags (specified below).
12 ACTION_T_SUMMON CreatureID, Target, Duration Summons a creature (Param1) for (Param3) duration and orders it to attach (Param2) target. Spawns on top of current creature. 12 ACTION_T_SUMMON CreatureID, Target, Duration Summons a creature (Param1) for (Param3) duration and orders it to attach (Param2) target. Spawns on top of current creature.
13 ACTION_T_THREAT_SINGLE_PCT Threat%, Target Modifies a threat by (Param1) percent on a target (Param2). 13 ACTION_T_THREAT_SINGLE_PCT Threat%, Target Modifies a threat by (Param1) percent on a target (Param2).
14 ACTION_T_THREAT_ALL_PCT Threat% Modifies a threat by (Param1) on all targets in the threat list (using -100% here will result in full aggro dump). 14 ACTION_T_THREAT_ALL_PCT Threat% Modifies a threat by (Param1) on all targets in the threat list (using -100% here will result in full aggro dump).
15 ACTION_T_QUEST_EVENT QuestID, Target Calls AreaExploredOrEventHappens with (Param1) for a target in (Param2). 15 ACTION_T_QUEST_EVENT QuestID, Target Calls AreaExploredOrEventHappens with (Param1) for a target in (Param2).
16 ACTION_T_QUEST_CASTCREATUREGO CreatureID, SpellId, Target Sends CastCreatureOrGo for a creature specified by CreatureId (Param1) with provided spell id (Param2) for a target in (Param3). 16 ACTION_T_QUEST_CASTCREATUREGO CreatureID, SpellId, Target Sends CastCreatureOrGo for a creature specified by CreatureId (Param1) with provided spell id (Param2) for a target in (Param3).
17 ACTION_T_SET_UNIT_FIELD Field_Number, Value, Target Sets a unit field (Param1) to provided value (Param2) on a target in (Param3). 17 ACTION_T_SET_UNIT_FIELD Field_Number, Value, Target Sets a unit field (Param1) to provided value (Param2) on a target in (Param3).
18 ACTION_T_SET_UNIT_FLAG Flags, Target Sets flag (flags can be used together to modify multiple flags at once) on a target (Param2). 18 ACTION_T_SET_UNIT_FLAG Flags, Target Sets flag (flags can be used together to modify multiple flags at once) on a target (Param2).
19 ACTION_T_REMOVE_UNIT_FLAG Flags, Target Removes flag on a target (Param2). 19 ACTION_T_REMOVE_UNIT_FLAG Flags, Target Removes flag on a target (Param2).
20 ACTION_T_AUTO_ATTACK AllowAutoAttack Stop melee attack when (Param1) is zero, otherwise continue attacking / allow melee attack. 20 ACTION_T_AUTO_ATTACK AllowAutoAttack Stop melee attack when (Param1) is zero, otherwise continue attacking / allow melee attack.
21 ACTION_T_COMBAT_MOVEMENT AllowCombatMovement Stop combat based movement when (Param1) is zero, otherwise continue/allow combat based movement (targeted movement generator). 21 ACTION_T_COMBAT_MOVEMENT AllowCombatMovement Stop combat based movement when (Param1) is zero, otherwise continue/allow combat based movement (targeted movement generator).
22 ACTION_T_SET_PHASE Phase Sets the current phase to (Param1). 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, but should not be zero. 23 ACTION_T_INC_PHASE Value Increments the phase by (Param1). May be negative to decrement, but should not be zero.
24 ACTION_T_EVADE No Params Forces the creature to evade, wiping all threat and dropping combat. 24 ACTION_T_EVADE No Params Forces the creature to evade, wiping all threat and dropping combat.
25 ACTION_T_FLEE_FOR_ASSIST No Params Causes the creature to flee for assistence (often at low health). 25 ACTION_T_FLEE_FOR_ASSIST No Params Causes the creature to flee for assistence (often at low health).
26 ACTION_T_QUEST_EVENT_ALL QuestId Calls GroupEventHappens with (Param1). Only used if it's _expected_ event should call quest completion for all players in a current party. 26 ACTION_T_QUEST_EVENT_ALL QuestId Calls GroupEventHappens with (Param1). Only used if it's _expected_ event should call quest completion for all players in a current party.
27 ACTION_T_CASTCREATUREGO_ALL QuestId, SpellId Calls CastedCreatureOrGo for all players on the threat list with quest id specified in (Param1) and spell id in (Param2). 27 ACTION_T_CASTCREATUREGO_ALL QuestId, SpellId Calls CastedCreatureOrGo for all players on the threat list with quest id specified in (Param1) and spell id in (Param2).
28 ACTION_T_REMOVEAURASFROMSPELL Target, Spellid Removes all auras on a target (Param1) caused by a spell (Param2). 28 ACTION_T_REMOVEAURASFROMSPELL Target, Spellid Removes all auras on a target (Param1) caused by a spell (Param2).
29 ACTION_T_RANGED_MOVEMENT Distance, Angle Changes the movement generator to a ranged type. (note: default melee type can still be set by using 0 as angle and 0 as distance). 29 ACTION_T_RANGED_MOVEMENT Distance, Angle Changes the movement generator to a ranged type. (note: default melee type can still be set by using 0 as angle and 0 as distance).
30 ACTION_T_RANDOM_PHASE PhaseId1, PhaseId2, PhaseId3 Sets a phase to a specified id(s)* 30 ACTION_T_RANDOM_PHASE PhaseId1, PhaseId2, PhaseId3 Sets a phase to a specified id(s)*
31 ACTION_T_RANDOM_PHASE_RANGE PhaseMin, PhaseMax Sets a phase to a random id (Phase = PhaseMin + rnd % PhaseMin-PhaseMax). PhaseMax must be greater than PhaseMin. 31 ACTION_T_RANDOM_PHASE_RANGE PhaseMin, PhaseMax Sets a phase to a random id (Phase = PhaseMin + rnd % PhaseMin-PhaseMax). PhaseMax must be greater than PhaseMin.
32 ACTION_T_SUMMON CreatureID, Target, SummonID Summons a creature (Param1) to attack target (Param2) at location specified by EventAI_Summons (Param3). 32 ACTION_T_SUMMON CreatureID, Target, SummonID Summons a creature (Param1) to attack target (Param2) at location specified by EventAI_Summons (Param3).
33 ACTION_T_KILLED_MONSTER CreatureID, Target Calls KilledMonster (Param1) for a target (Param2). 33 ACTION_T_KILLED_MONSTER CreatureID, Target Calls KilledMonster (Param1) for a target (Param2).
34 ACTION_T_SET_INST_DATA Field, Data Calls ScriptedInstance::SetData with field (Param1) and data (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 target's GUID (Param2). 35 ACTION_T_SET_INST_DATA64 Field, Target Calls ScriptedInstance::SetData64 with field (Param1) and target's GUID (Param2).
36 ACTION_T_UPDATE_TEMPLATE TemplateId, Team Changes a creature's template to (Param1) with team = Alliance or Horde when (Param2) is either false or true respectively. 36 ACTION_T_UPDATE_TEMPLATE TemplateId, Team Changes a creature's template to (Param1) with team = Alliance or Horde when (Param2) is either false or true respectively.
37 ACTION_T_DIE No Params Kills the creature 37 ACTION_T_DIE No Params Kills the creature
38 ACTION_T_ZONE_COMBAT_PULSE No Params Puts all players within an instance into combat with the creature. Only works when a creature is already in combat. Doesn't work outside instances. 38 ACTION_T_ZONE_COMBAT_PULSE No Params Puts all players within an instance into combat with the creature. Only works when a creature is already in combat. Doesn't work outside instances.
39 ACTION_T_CALL_FOR_HELP Radius Call any friendly out-of-combat creatures in a radius (Param1) to attack current creature's target. 39 ACTION_T_CALL_FOR_HELP Radius Call any friendly out-of-combat creatures in a radius (Param1) to attack current creature's target.
40 ACTION_T_SET_SHEATH Sheath Sets sheath state for a creature (0 = no weapon, 1 = melee weapon, 2 = ranged weapon). 40 ACTION_T_SET_SHEATH Sheath Sets sheath state for a creature (0 = no weapon, 1 = melee weapon, 2 = ranged weapon).
41 ACTION_T_FORCE_DESPAWN No Params Despawns the creature 41 ACTION_T_FORCE_DESPAWN Delay Despawns the creature, if delay = 0 immediate otherwise will despawn after delay time set in Param1 (in ms).
42 ACTION_T_SET_INVINCIBILITY_HP_LEVEL hp_level, is_percent Set min. health level for creature that can be set at damage as flat value or percent from max health 42 ACTION_T_SET_INVINCIBILITY_HP_LEVEL HP_Level, HP_Percent Set min. health level for creature that can be set at damage as flat value or percent from max health
* = Use -1 where the param is expected to do nothing. Random constant is generated for each event, so if you have a random yell and a random sound, they will be linked up with each other (ie. param2 with param2). * = Use -1 where the param is expected to do nothing. Random constant is generated for each event, so if you have a random yell and a random sound, they will be linked up with each other (ie. param2 with param2).
@ -233,15 +235,16 @@ 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 OR If (param2) is set it will only expire on spells of that school. Will repeat every (Param3) and (Param4). BOTH - Expires upon Spell hit. If (param1) is set will only expire on that spell OR If (param2) is set it 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. This Event is commonly used for NPC's who can do special things when you cast a spell (Or specific spell) on them.
(name, school, schoolmask) (Name ==> School ==> School Bitmask Values)
SPELL_SCHOOL_NORMAL = 0, ==> 1 -------------------------------------------
SPELL_SCHOOL_HOLY = 1, ==> 2 SPELL_SCHOOL_NORMAL = 0 ==> 1
SPELL_SCHOOL_FIRE = 2, ==> 4 SPELL_SCHOOL_HOLY = 1 ==> 2
SPELL_SCHOOL_NATURE = 3, ==> 8 SPELL_SCHOOL_FIRE = 2 ==> 4
SPELL_SCHOOL_FROST = 4, ==> 16 SPELL_SCHOOL_NATURE = 3 ==> 8
SPELL_SCHOOL_SHADOW = 5, ==> 32 SPELL_SCHOOL_FROST = 4 ==> 16
SPELL_SCHOOL_ARCANE = 6, ==> 64 SPELL_SCHOOL_SHADOW = 5 ==> 32
Use These Values For Schoolmask (Param2) or Any Combinations Of These Schoolmasks for Multiple Schools. SPELL_SCHOOL_ARCANE = 6 ==> 64
Use These Bitmask Values For Schoolmask (Param2) or Any Combinations Of These Schoolmasks for Multiple Schools.
------------------ ------------------
9 = EVENT_T_RANGE: 9 = EVENT_T_RANGE:
@ -382,9 +385,9 @@ CONDITION_ACTIVE_EVENT (12) event_id 0, note this is id from dbc, also def
Action Types Action Types
========================================= =========================================
----------------- ------------------
1 = ACTION_T_TEXT: 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). 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) 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). 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).
@ -511,7 +514,7 @@ This is commonly used for Quests where only ONE player will gain credit for the
16 = ACTION_T_CASTCREATUREGO: 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 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 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. 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 action will call CastedCreatureOrGO() function for the player. It can be used to give quest credit for casting a spell on the creature.
@ -548,7 +551,7 @@ When activated, this action changes the target's flags by removing (turning off)
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. 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. 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). NOTE: Developers have recommended 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. This is commonly used in combination with EVENT_T_RANGE and ACTION_T_COMBAT_MOVEMENT for Ranged Combat for Mages and Spell Casters.
------------------------------ ------------------------------
@ -558,7 +561,7 @@ Parameter 1: If zero, then the creature will stop moving towards its victim (if
Parameter 2: If non-zero, then stop melee combat state (if param1=0) or start melee combat state (if param1!=0) and creature in combat with selected target. Parameter 2: If non-zero, then stop melee combat state (if param1=0) or start melee combat state (if param1!=0) and creature in combat with selected target.
This action controls whether or not the creature will always move towards its target. 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) NOTE: Developers have recommended 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) 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)
Parameter 2 specialy used for ranged combat proper client side visual show ranged weapon in proper state. Parameter 2 specialy used for ranged combat proper client side visual show ranged weapon in proper state.
@ -588,10 +591,9 @@ When activated, the creature will immediately exit out of combat, clear its thre
NOTE: All Param Values Are 0 for this Action. NOTE: All Param Values Are 0 for this Action.
------------------- -------------------
25 = ACTION_T_FLEE: 25 = ACTION_T_FLEE_FOR_ASSIST:
------------------- -------------------
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". When activated, the creature will flee from combat for assistance from nearby NPC's if possible.
A Better Flee system is in Development.
NOTE: All Param Values Are 0 for this Action. NOTE: All Param Values Are 0 for this Action.
------------------------------ ------------------------------
@ -683,6 +685,16 @@ 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. 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. 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.
Field Values:
These are located in there SD2 Instance File (Example: blackrock_depths.h) And Are Clearly Defined For Specific Events Scripted In The Instance.
Data Values:
NOT_STARTED = 0
IN_PROGRESS = 1
FAIL = 2
DONE = 3
SPECIAL = 4
------------------------------ ------------------------------
35 = ACTION_T_SET_INST_DATA64: 35 = ACTION_T_SET_INST_DATA64:
------------------------------ ------------------------------
@ -723,28 +735,28 @@ Mostly used when call to help more wide that normal aggro radius or auto-used ca
------------------------- -------------------------
40 ACTION_T_SET_SHEATH: 40 ACTION_T_SET_SHEATH:
------------------------- -------------------------
Parameter 1: Sheath state Parameter 1: Set Sheath State
0 SHEATH_STATE_UNARMED not prepared weapon show (not used mostly by creatures) 0 = SHEATH_STATE_UNARMED Set No Weapon Displayed (Not Usually Used By Creatures)
1 SHEATH_STATE_MELEE melee weapon prepared show 1 = SHEATH_STATE_MELEE Set Melee Weapon Displayed
2 SHEATH_STATE_RANGED ranged weapon prepared show 2 = SHEATH_STATE_RANGED Set Ranged Weapon Displayed
Let set sheath state for creature. Set Sheath State For NPC.
Note: SHEATH_STATE_RANGED case work in combat state only if combat not start as melee commands. Note: SHEATH_STATE_RANGED case work in combat state only if combat not start as melee commands.
This possible setup by set ar event AI start (single used EVENT_T_TIMER_OOC set ACTION_T_COMBAT_MOVEMENT 0 for creature that prefered ranged attack) This possible setup by set at event AI start (single used EVENT_T_TIMER_OOC or set ACTION_T_COMBAT_MOVEMENT 0 for creature that prefered ranged attack)
------------------------- ----------------------------
41 ACTION_T_FORCE_DESPAWN 41 ACTION_T_FORCE_DESPAWN:
------------------------- ----------------------------
Despawns the creature (in or out of combat) Despawns The NPC with optional delay time (Works In or Out of Combat)
No parameters Parameter 1: Delay - Sets delay time until Despawn occurs after triggering the action. Time is in (ms).
------------------------- -----------------------------------------
42 ACTION_T_SET_INVINCIBILITY_HP_LEVEL 42 ACTION_T_SET_INVINCIBILITY_HP_LEVEL:
------------------------- -----------------------------------------
Parameter 1: min. health level for creature that can be set at damage, 0 used as absent min. health value for apply damage. Parameter 1: Minimum Health Level That NPC Can Reach (NPC Will Not Go Below This Value).
Parameter 2: format of paramater 1 value Parameter 2: Sets Format of Paramater 1 Value
0 paramater 1 used as flat value 0 = Sets Paramater 1 as an exact HP value
1 paramater 1 used as percent (0..100) from creature max health 1 = Sets Paramater 1 as a HP Percent (0..100) of the creature's max health
========================================= =========================================
Target Types Target Types
@ -752,14 +764,15 @@ Target Types
Below is the list of current Target types that EventAI can handle. Below is the list of current Target types that EventAI can handle.
Target types are used by certain actions and may effect actions differently Target types are used by certain actions and may effect actions differently
(# Internal Name Discription) # Internal Name Description
0 TARGET_T_SELF Self cast ---------------------------------------------------
1 TARGET_T_HOSTILE Our current target (ie: highest aggro) 0 TARGET_T_SELF Self Cast
2 TARGET_T_HOSTILE_SECOND_AGGRO Second highest aggro (generaly used for cleaves and some special attacks) 1 TARGET_T_HOSTILE Current Target (ie: Highest Aggro)
3 TARGET_T_HOSTILE_LAST_AGGRO Dead last on aggro (no idea what this could be used for) 2 TARGET_T_HOSTILE_SECOND_AGGRO Second Highest Aggro (Generaly used for Cleaves and some special attacks)
4 TARGET_T_HOSTILE_RANDOM Just any random target on our threat list 3 TARGET_T_HOSTILE_LAST_AGGRO Dead Last on Aggro (no idea what this could be used for)
5 TARGET_T_HOSTILE_RANDOM_NOT_TOP Any random target except top threat 4 TARGET_T_HOSTILE_RANDOM Random Target on The Threat List
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) 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 Cast Flags
@ -769,7 +782,8 @@ Cast flags are handled bitwise. Bit 0 is Interrupt Previous, bit 1 is triggered,
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. 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. 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) # Decimal Internal Name Description
--------------------------------------------------------------
0 1 CAST_INTURRUPT_PREVIOUS Interrupts any previous spell casting (basicaly makes sure that this spell goes off) 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. 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 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
@ -785,7 +799,8 @@ Event Flags
========================================= =========================================
Below is the list of current Event Flags that EventAI can handle. Event flags are handled bitwise. Below is the list of current Event Flags that EventAI can handle. Event flags are handled bitwise.
(bit# Decimal Internal Name Discription) # Decimal Internal Name Description
------------------------------------------------------------
0 1 EFLAG_REPEATABLE Event repeats (Does not repeat if this flag is not set) 0 1 EFLAG_REPEATABLE Event repeats (Does not repeat if this flag is not set)
1 2 EFLAG_DIFFICULTY_0 Event occurs in instance difficulty 0 (will not occur if not set) 1 2 EFLAG_DIFFICULTY_0 Event occurs in instance difficulty 0 (will not occur if not set)
2 4 EFLAG_DIFFICULTY_1 Event occurs in instance difficulty 1 (will not occur if not set) 2 4 EFLAG_DIFFICULTY_1 Event occurs in instance difficulty 1 (will not occur if not set)
@ -818,7 +833,7 @@ content_loc7 This is the actual text presented in the Localization #7 C
content_loc8 This is the actual text presented in the Localization #8 Clients (Russian) 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. 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). type Variables used to define type of text (Say/Yell/TextEmote/Whisper).
language This value is the Language that the text is native in. 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) 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 comment This is a comment regarding the text entry
@ -828,7 +843,7 @@ Note: Fields `content_loc1` to `content_loc8` are NULL values by default and are
========================================= =========================================
Text Types (type) Text Types (type)
========================================= =========================================
Below is the list of current Text types that texts tables can handle. These were previously seperate Actions in ACID. Below is the list of current Text types that texts tables can handle. These were previously seperate Actions before.
# Internal Name Description # Internal Name Description
----------------------------------------------------------- -----------------------------------------------------------

View file

@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
`version` varchar(120) default NULL, `version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL,
`cache_id` int(10) default '0', `cache_id` int(10) default '0',
`required_9121_01_mangos_npc_spellclick_spells` bit(1) default NULL `required_9125_01_mangos_npc_spellclick_spells` 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';
-- --

View file

@ -0,0 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_9121_01_mangos_npc_spellclick_spells required_9125_01_mangos_npc_spellclick_spells bit;
UPDATE npc_spellclick_spells SET cast_flags=1 WHERE spell_id=46167;
DELETE FROM npc_spellclick_spells WHERE spell_id=46773;

View file

@ -226,6 +226,7 @@ pkgdata_DATA = \
9074_01_mangos_command.sql \ 9074_01_mangos_command.sql \
9095_01_mangos_command.sql \ 9095_01_mangos_command.sql \
9121_01_mangos_npc_spellclick_spells.sql \ 9121_01_mangos_npc_spellclick_spells.sql \
9125_01_mangos_npc_spellclick_spells.sql \
README README
## Additional files to include when running 'make dist' ## Additional files to include when running 'make dist'
@ -432,4 +433,5 @@ EXTRA_DIST = \
9074_01_mangos_command.sql \ 9074_01_mangos_command.sql \
9095_01_mangos_command.sql \ 9095_01_mangos_command.sql \
9121_01_mangos_npc_spellclick_spells.sql \ 9121_01_mangos_npc_spellclick_spells.sql \
9125_01_mangos_npc_spellclick_spells.sql \
README README

View file

@ -212,7 +212,7 @@ BattleGround::BattleGround()
m_Status = STATUS_NONE; m_Status = STATUS_NONE;
m_ClientInstanceID = 0; m_ClientInstanceID = 0;
m_EndTime = 0; m_EndTime = 0;
m_QueueId = QUEUE_ID_MAX_LEVEL_19; m_BracketId = BG_BRACKET_ID_FIRST;
m_InvitedAlliance = 0; m_InvitedAlliance = 0;
m_InvitedHorde = 0; m_InvitedHorde = 0;
m_ArenaType = 0; m_ArenaType = 0;
@ -1101,7 +1101,7 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
{ {
// a player has left the battleground, so there are free slots -> add to queue // a player has left the battleground, so there are free slots -> add to queue
AddToBGFreeSlotQueue(); AddToBGFreeSlotQueue();
sBattleGroundMgr.ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, GetQueueId()); sBattleGroundMgr.ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, GetBracketId());
} }
// Let others know // Let others know
@ -1129,7 +1129,7 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
// this method is called when no players remains in battleground // this method is called when no players remains in battleground
void BattleGround::Reset() void BattleGround::Reset()
{ {
SetQueueId(QUEUE_ID_MAX_LEVEL_19); SetBracketId(BG_BRACKET_ID_FIRST);
SetWinner(WINNER_NONE); SetWinner(WINNER_NONE);
SetStatus(STATUS_WAIT_QUEUE); SetStatus(STATUS_WAIT_QUEUE);
SetStartTime(0); SetStartTime(0);

View file

@ -165,18 +165,22 @@ enum BattleGroundQueueTypeId
}; };
#define MAX_BATTLEGROUND_QUEUE_TYPES 10 #define MAX_BATTLEGROUND_QUEUE_TYPES 10
enum BGQueueIdBasedOnLevel // queue_id for level ranges enum BattleGroundBracketId // bracketId for level ranges
{ {
QUEUE_ID_MAX_LEVEL_19 = 0, BG_BRACKET_ID_FIRST = 0,
QUEUE_ID_MAX_LEVEL_29 = 1,
QUEUE_ID_MAX_LEVEL_39 = 2, BG_BRACKET_ID_MAX_LEVEL_19 = 0,
QUEUE_ID_MAX_LEVEL_49 = 3, BG_BRACKET_ID_MAX_LEVEL_29 = 1,
QUEUE_ID_MAX_LEVEL_59 = 4, BG_BRACKET_ID_MAX_LEVEL_39 = 2,
QUEUE_ID_MAX_LEVEL_69 = 5, BG_BRACKET_ID_MAX_LEVEL_49 = 3,
QUEUE_ID_MAX_LEVEL_79 = 6, BG_BRACKET_ID_MAX_LEVEL_59 = 4,
QUEUE_ID_MAX_LEVEL_80 = 7 BG_BRACKET_ID_MAX_LEVEL_69 = 5,
BG_BRACKET_ID_MAX_LEVEL_79 = 6,
BG_BRACKET_ID_MAX_LEVEL_80 = 7,
BG_BRACKET_ID_LAST = 7
}; };
#define MAX_BATTLEGROUND_QUEUES 8 #define MAX_BATTLEGROUND_BRACKETS 8
enum ScoreType enum ScoreType
{ {
@ -309,7 +313,7 @@ class BattleGround
// Get methods: // Get methods:
char const* GetName() const { return m_Name; } char const* GetName() const { return m_Name; }
BattleGroundTypeId GetTypeID() const { return m_TypeID; } BattleGroundTypeId GetTypeID() const { return m_TypeID; }
BGQueueIdBasedOnLevel GetQueueId() const { return m_QueueId; } BattleGroundBracketId GetBracketId() const { return m_BracketId; }
uint32 GetInstanceID() const { return m_InstanceID; } uint32 GetInstanceID() const { return m_InstanceID; }
BattleGroundStatus GetStatus() const { return m_Status; } BattleGroundStatus GetStatus() const { return m_Status; }
uint32 GetClientInstanceID() const { return m_ClientInstanceID; } uint32 GetClientInstanceID() const { return m_ClientInstanceID; }
@ -334,9 +338,9 @@ class BattleGround
void SetName(char const* Name) { m_Name = Name; } void SetName(char const* Name) { m_Name = Name; }
void SetTypeID(BattleGroundTypeId TypeID) { m_TypeID = TypeID; } void SetTypeID(BattleGroundTypeId TypeID) { m_TypeID = TypeID; }
//here we can count minlevel and maxlevel for players //here we can count minlevel and maxlevel for players
void SetQueueId(BGQueueIdBasedOnLevel ID) void SetBracketId(BattleGroundBracketId ID)
{ {
m_QueueId = ID; m_BracketId = ID;
uint8 diff = (m_TypeID == BATTLEGROUND_AV) ? 1 : 0; uint8 diff = (m_TypeID == BATTLEGROUND_AV) ? 1 : 0;
this->SetLevelRange((ID + 1) * 10 + diff, (ID + 2) * 10 - ((diff + 1) % 2)); this->SetLevelRange((ID + 1) * 10 + diff, (ID + 2) * 10 - ((diff + 1) % 2));
} }
@ -585,7 +589,7 @@ class BattleGround
uint32 m_StartTime; uint32 m_StartTime;
bool m_ArenaBuffSpawned; // to cache if arenabuff event is started (cause bool is faster than checking IsActiveEvent) bool m_ArenaBuffSpawned; // to cache if arenabuff event is started (cause bool is faster than checking IsActiveEvent)
int32 m_EndTime; // it is set to 120000 when bg is ending and it decreases itself int32 m_EndTime; // it is set to 120000 when bg is ending and it decreases itself
BGQueueIdBasedOnLevel m_QueueId; BattleGroundBracketId m_BracketId;
uint8 m_ArenaType; // 2=2v2, 3=3v3, 5=5v5 uint8 m_ArenaType; // 2=2v2, 3=3v3, 5=5v5
bool m_InBGFreeSlotQueue; // used to make sure that BG is only once inserted into the BattleGroundMgr.BGFreeSlotQueue[bgTypeId] deque bool m_InBGFreeSlotQueue; // used to make sure that BG is only once inserted into the BattleGroundMgr.BGFreeSlotQueue[bgTypeId] deque
bool m_SetDeleteThis; // used for safe deletion of the bg after end / all players leave bool m_SetDeleteThis; // used for safe deletion of the bg after end / all players leave

View file

@ -115,6 +115,8 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
return; return;
} }
BattleGroundBracketId bgBracketId = _player->GetBattleGroundBracketIdFromLevel();
// check queueing conditions // check queueing conditions
if (!joinAsGroup) if (!joinAsGroup)
{ {
@ -155,8 +157,8 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
if (joinAsGroup /* && _player->GetGroup()*/) if (joinAsGroup /* && _player->GetGroup()*/)
{ {
sLog.outDebug("Battleground: the following players are joining as group:"); sLog.outDebug("Battleground: the following players are joining as group:");
GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, 0, false, isPremade, 0); GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bgBracketId, 0, false, isPremade, 0);
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel()); uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundBracketIdFromLevel());
for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
{ {
Player *member = itr->getSource(); Player *member = itr->getSource();
@ -176,8 +178,8 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
} }
else else
{ {
GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, 0, false, isPremade, 0); GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bgBracketId, 0, false, isPremade, 0);
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel()); uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundBracketIdFromLevel());
// already checked if queueSlot is valid, now just get it // already checked if queueSlot is valid, now just get it
uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId); uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId);
@ -187,7 +189,7 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
SendPacket(&data); SendPacket(&data);
sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName()); sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName());
} }
sBattleGroundMgr.ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, _player->GetBattleGroundQueueIdFromLevel()); sBattleGroundMgr.ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, _player->GetBattleGroundBracketIdFromLevel());
} }
void WorldSession::HandleBattleGroundPlayerPositionsOpcode( WorldPacket & /*recv_data*/ ) void WorldSession::HandleBattleGroundPlayerPositionsOpcode( WorldPacket & /*recv_data*/ )
@ -431,7 +433,7 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data )
bgQueue.RemovePlayer(_player->GetGUID(), true); bgQueue.RemovePlayer(_player->GetGUID(), true);
// player left queue, we should update it - do not update Arena Queue // player left queue, we should update it - do not update Arena Queue
if (!ginfo.ArenaType) if (!ginfo.ArenaType)
sBattleGroundMgr.ScheduleQueueUpdate(ginfo.ArenaTeamRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, _player->GetBattleGroundQueueIdFromLevel()); sBattleGroundMgr.ScheduleQueueUpdate(ginfo.ArenaTeamRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, _player->GetBattleGroundBracketIdFromLevel());
SendPacket(&data); SendPacket(&data);
sLog.outDebug("Battleground: player %s (%u) left queue for bgtype %u, queue type %u.", _player->GetName(), _player->GetGUIDLow(), bg->GetTypeID(), bgQueueTypeId); sLog.outDebug("Battleground: player %s (%u) left queue for bgtype %u, queue type %u.", _player->GetName(), _player->GetGUIDLow(), bg->GetTypeID(), bgQueueTypeId);
break; break;
@ -513,7 +515,7 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ )
bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId); bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
if (!bg) if (!bg)
continue; continue;
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(&ginfo, _player->GetBattleGroundQueueIdFromLevel()); uint32 avgTime = bgQueue.GetAverageQueueWaitTime(&ginfo, _player->GetBattleGroundBracketIdFromLevel());
// send status in BattleGround Queue // send status in BattleGround Queue
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_WAIT_QUEUE, avgTime, getMSTimeDiff(ginfo.JoinTime, getMSTime()), arenaType); sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_WAIT_QUEUE, avgTime, getMSTimeDiff(ginfo.JoinTime, getMSTime()), arenaType);
SendPacket(&data); SendPacket(&data);
@ -607,8 +609,8 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
} }
//check existance //check existance
BattleGround* bg = NULL; BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(BATTLEGROUND_AA);
if (!(bg = sBattleGroundMgr.GetBattleGroundTemplate(BATTLEGROUND_AA))) if (!bg)
{ {
sLog.outError("Battleground: template bg (all arenas) not found"); sLog.outError("Battleground: template bg (all arenas) not found");
return; return;
@ -616,6 +618,7 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
BattleGroundTypeId bgTypeId = bg->GetTypeID(); BattleGroundTypeId bgTypeId = bg->GetTypeID();
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, arenatype); BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, arenatype);
BattleGroundBracketId bgBracketId = _player->GetBattleGroundBracketIdFromLevel();
// check queueing conditions // check queueing conditions
if (!asGroup) if (!asGroup)
@ -682,8 +685,8 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
if (isRated) if (isRated)
sLog.outDebug("Battleground: arena team id %u, leader %s queued with rating %u for type %u",_player->GetArenaTeamId(arenaslot),_player->GetName(),arenaRating,arenatype); sLog.outDebug("Battleground: arena team id %u, leader %s queued with rating %u for type %u",_player->GetArenaTeamId(arenaslot),_player->GetName(),arenaRating,arenatype);
GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, arenatype, isRated, false, arenaRating, ateamId); GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bgBracketId, arenatype, isRated, false, arenaRating, ateamId);
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel()); uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundBracketIdFromLevel());
for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
{ {
Player *member = itr->getSource(); Player *member = itr->getSource();
@ -704,8 +707,8 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
} }
else else
{ {
GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, arenatype, isRated, false, arenaRating, ateamId); GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bgBracketId, arenatype, isRated, false, arenaRating, ateamId);
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel()); uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundBracketIdFromLevel());
uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId); uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId);
WorldPacket data; WorldPacket data;
@ -714,7 +717,7 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
SendPacket(&data); SendPacket(&data);
sLog.outDebug("Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName()); sLog.outDebug("Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName());
} }
sBattleGroundMgr.ScheduleQueueUpdate(arenaRating, arenatype, bgQueueTypeId, bgTypeId, _player->GetBattleGroundQueueIdFromLevel()); sBattleGroundMgr.ScheduleQueueUpdate(arenaRating, arenatype, bgQueueTypeId, bgTypeId, _player->GetBattleGroundBracketIdFromLevel());
} }
void WorldSession::HandleReportPvPAFK( WorldPacket & recv_data ) void WorldSession::HandleReportPvPAFK( WorldPacket & recv_data )

View file

@ -54,13 +54,13 @@ INSTANTIATE_SINGLETON_1( BattleGroundMgr );
BattleGroundQueue::BattleGroundQueue() BattleGroundQueue::BattleGroundQueue()
{ {
for(uint32 i = 0; i < BG_TEAMS_COUNT; i++) for(uint32 i = 0; i < BG_TEAMS_COUNT; ++i)
{ {
for(uint32 j = 0; j < MAX_BATTLEGROUND_QUEUES; j++) for(uint32 j = 0; j < MAX_BATTLEGROUND_BRACKETS; ++j)
{ {
m_SumOfWaitTimes[i][j] = 0; m_SumOfWaitTimes[i][j] = 0;
m_WaitTimeLastPlayer[i][j] = 0; m_WaitTimeLastPlayer[i][j] = 0;
for(uint32 k = 0; k < COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME; k++) for(uint32 k = 0; k < COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME; ++k)
m_WaitTimes[i][j][k] = 0; m_WaitTimes[i][j][k] = 0;
} }
} }
@ -69,9 +69,9 @@ BattleGroundQueue::BattleGroundQueue()
BattleGroundQueue::~BattleGroundQueue() BattleGroundQueue::~BattleGroundQueue()
{ {
m_QueuedPlayers.clear(); m_QueuedPlayers.clear();
for (int i = 0; i < MAX_BATTLEGROUND_QUEUES; i++) for (int i = 0; i < MAX_BATTLEGROUND_BRACKETS; ++i)
{ {
for(uint32 j = 0; j < BG_QUEUE_GROUP_TYPES_COUNT; j++) for(uint32 j = 0; j < BG_QUEUE_GROUP_TYPES_COUNT; ++j)
{ {
for(GroupsQueueType::iterator itr = m_QueuedGroups[i][j].begin(); itr!= m_QueuedGroups[i][j].end(); ++itr) for(GroupsQueueType::iterator itr = m_QueuedGroups[i][j].begin(); itr!= m_QueuedGroups[i][j].end(); ++itr)
delete (*itr); delete (*itr);
@ -148,10 +148,8 @@ bool BattleGroundQueue::SelectionPool::AddGroup(GroupQueueInfo *ginfo, uint32 de
/*********************************************************/ /*********************************************************/
// add group or player (grp == NULL) to bg queue with the given leader and bg specifications // add group or player (grp == NULL) to bg queue with the given leader and bg specifications
GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, Group* grp, BattleGroundTypeId BgTypeId, uint8 ArenaType, bool isRated, bool isPremade, uint32 arenaRating, uint32 arenateamid) GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, Group* grp, BattleGroundTypeId BgTypeId, BattleGroundBracketId bracket_id, uint8 ArenaType, bool isRated, bool isPremade, uint32 arenaRating, uint32 arenateamid)
{ {
BGQueueIdBasedOnLevel queue_id = leader->GetBattleGroundQueueIdFromLevel();
// create new ginfo // create new ginfo
GroupQueueInfo* ginfo = new GroupQueueInfo; GroupQueueInfo* ginfo = new GroupQueueInfo;
ginfo->BgTypeId = BgTypeId; ginfo->BgTypeId = BgTypeId;
@ -173,7 +171,7 @@ GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, Group* grp, BattleG
index += BG_TEAMS_COUNT; index += BG_TEAMS_COUNT;
if (ginfo->Team == HORDE) if (ginfo->Team == HORDE)
index++; index++;
sLog.outDebug("Adding Group to BattleGroundQueue bgTypeId : %u, queue_id : %u, index : %u", BgTypeId, queue_id, index); sLog.outDebug("Adding Group to BattleGroundQueue bgTypeId : %u, bracket_id : %u, index : %u", BgTypeId, bracket_id, index);
uint32 lastOnlineTime = getMSTime(); uint32 lastOnlineTime = getMSTime();
@ -209,7 +207,7 @@ GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, Group* grp, BattleG
} }
//add GroupInfo to m_QueuedGroups //add GroupInfo to m_QueuedGroups
m_QueuedGroups[queue_id][index].push_back(ginfo); m_QueuedGroups[bracket_id][index].push_back(ginfo);
//announce to world, this code needs mutex //announce to world, this code needs mutex
if (!isRated && !isPremade && sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE)) if (!isRated && !isPremade && sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE))
@ -221,12 +219,12 @@ GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, Group* grp, BattleG
uint32 MinPlayers = bg->GetMinPlayersPerTeam(); uint32 MinPlayers = bg->GetMinPlayersPerTeam();
uint32 qHorde = 0; uint32 qHorde = 0;
uint32 qAlliance = 0; uint32 qAlliance = 0;
uint32 q_min_level = (queue_id + 1) * 10; uint32 q_min_level = (bracket_id + 1) * 10;
GroupsQueueType::const_iterator itr; GroupsQueueType::const_iterator itr;
for(itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].end(); ++itr) for(itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].end(); ++itr)
if (!(*itr)->IsInvitedToBGInstanceGUID) if (!(*itr)->IsInvitedToBGInstanceGUID)
qAlliance += (*itr)->Players.size(); qAlliance += (*itr)->Players.size();
for(itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].end(); ++itr) for(itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].end(); ++itr)
if (!(*itr)->IsInvitedToBGInstanceGUID) if (!(*itr)->IsInvitedToBGInstanceGUID)
qHorde += (*itr)->Players.size(); qHorde += (*itr)->Players.size();
@ -250,7 +248,7 @@ GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, Group* grp, BattleG
return ginfo; return ginfo;
} }
void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id) void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BattleGroundBracketId bracket_id)
{ {
uint32 timeInQueue = getMSTimeDiff(ginfo->JoinTime, getMSTime()); uint32 timeInQueue = getMSTimeDiff(ginfo->JoinTime, getMSTime());
uint8 team_index = BG_TEAM_ALLIANCE; //default set to BG_TEAM_ALLIANCE - or non rated arenas! uint8 team_index = BG_TEAM_ALLIANCE; //default set to BG_TEAM_ALLIANCE - or non rated arenas!
@ -266,19 +264,19 @@ void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* g
} }
//store pointer to arrayindex of player that was added first //store pointer to arrayindex of player that was added first
uint32* lastPlayerAddedPointer = &(m_WaitTimeLastPlayer[team_index][queue_id]); uint32* lastPlayerAddedPointer = &(m_WaitTimeLastPlayer[team_index][bracket_id]);
//remove his time from sum //remove his time from sum
m_SumOfWaitTimes[team_index][queue_id] -= m_WaitTimes[team_index][queue_id][(*lastPlayerAddedPointer)]; m_SumOfWaitTimes[team_index][bracket_id] -= m_WaitTimes[team_index][bracket_id][(*lastPlayerAddedPointer)];
//set average time to new //set average time to new
m_WaitTimes[team_index][queue_id][(*lastPlayerAddedPointer)] = timeInQueue; m_WaitTimes[team_index][bracket_id][(*lastPlayerAddedPointer)] = timeInQueue;
//add new time to sum //add new time to sum
m_SumOfWaitTimes[team_index][queue_id] += timeInQueue; m_SumOfWaitTimes[team_index][bracket_id] += timeInQueue;
//set index of last player added to next one //set index of last player added to next one
(*lastPlayerAddedPointer)++; (*lastPlayerAddedPointer)++;
(*lastPlayerAddedPointer) %= COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME; (*lastPlayerAddedPointer) %= COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME;
} }
uint32 BattleGroundQueue::GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id) uint32 BattleGroundQueue::GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BattleGroundBracketId bracket_id)
{ {
uint8 team_index = BG_TEAM_ALLIANCE; //default set to BG_TEAM_ALLIANCE - or non rated arenas! uint8 team_index = BG_TEAM_ALLIANCE; //default set to BG_TEAM_ALLIANCE - or non rated arenas!
if (!ginfo->ArenaType) if (!ginfo->ArenaType)
@ -292,8 +290,8 @@ uint32 BattleGroundQueue::GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueue
team_index = BG_TEAM_HORDE; //for rated arenas use BG_TEAM_HORDE team_index = BG_TEAM_HORDE; //for rated arenas use BG_TEAM_HORDE
} }
//check if there is enought values(we always add values > 0) //check if there is enought values(we always add values > 0)
if (m_WaitTimes[team_index][queue_id][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME - 1] ) if (m_WaitTimes[team_index][bracket_id][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME - 1] )
return (m_SumOfWaitTimes[team_index][queue_id] / COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME); return (m_SumOfWaitTimes[team_index][bracket_id] / COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME);
else else
//if there aren't enough values return 0 - not available //if there aren't enough values return 0 - not available
return 0; return 0;
@ -305,7 +303,7 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou
//Player *plr = sObjectMgr.GetPlayer(guid); //Player *plr = sObjectMgr.GetPlayer(guid);
//ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_Lock); //ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_Lock);
int32 queue_id = -1; // signed for proper for-loop finish int32 bracket_id = -1; // signed for proper for-loop finish
QueuedPlayersMap::iterator itr; QueuedPlayersMap::iterator itr;
//remove player from map, if he's there //remove player from map, if he's there
@ -323,17 +321,17 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou
// variable index removes useless searching in other team's queue // variable index removes useless searching in other team's queue
uint32 index = (group->Team == HORDE) ? BG_TEAM_HORDE : BG_TEAM_ALLIANCE; uint32 index = (group->Team == HORDE) ? BG_TEAM_HORDE : BG_TEAM_ALLIANCE;
for (int32 queue_id_tmp = MAX_BATTLEGROUND_QUEUES - 1; queue_id_tmp >= 0 && queue_id == -1; --queue_id_tmp) for (int32 bracket_id_tmp = MAX_BATTLEGROUND_BRACKETS - 1; bracket_id_tmp >= 0 && bracket_id == -1; --bracket_id_tmp)
{ {
//we must check premade and normal team's queue - because when players from premade are joining bg, //we must check premade and normal team's queue - because when players from premade are joining bg,
//they leave groupinfo so we can't use its players size to find out index //they leave groupinfo so we can't use its players size to find out index
for (uint32 j = index; j < BG_QUEUE_GROUP_TYPES_COUNT; j += BG_QUEUE_NORMAL_ALLIANCE) for (uint32 j = index; j < BG_QUEUE_GROUP_TYPES_COUNT; j += BG_QUEUE_NORMAL_ALLIANCE)
{ {
for(group_itr_tmp = m_QueuedGroups[queue_id_tmp][j].begin(); group_itr_tmp != m_QueuedGroups[queue_id_tmp][j].end(); ++group_itr_tmp) for(group_itr_tmp = m_QueuedGroups[bracket_id_tmp][j].begin(); group_itr_tmp != m_QueuedGroups[bracket_id_tmp][j].end(); ++group_itr_tmp)
{ {
if ((*group_itr_tmp) == group) if ((*group_itr_tmp) == group)
{ {
queue_id = queue_id_tmp; bracket_id = bracket_id_tmp;
group_itr = group_itr_tmp; group_itr = group_itr_tmp;
//we must store index to be able to erase iterator //we must store index to be able to erase iterator
index = j; index = j;
@ -343,12 +341,12 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou
} }
} }
//player can't be in queue without group, but just in case //player can't be in queue without group, but just in case
if (queue_id == -1) if (bracket_id == -1)
{ {
sLog.outError("BattleGroundQueue: ERROR Cannot find groupinfo for player GUID: %u", GUID_LOPART(guid)); sLog.outError("BattleGroundQueue: ERROR Cannot find groupinfo for player GUID: %u", GUID_LOPART(guid));
return; return;
} }
sLog.outDebug("BattleGroundQueue: Removing player GUID %u, from queue_id %u", GUID_LOPART(guid), (uint32)queue_id); sLog.outDebug("BattleGroundQueue: Removing player GUID %u, from bracket_id %u", GUID_LOPART(guid), (uint32)bracket_id);
// ALL variables are correctly set // ALL variables are correctly set
// We can ignore leveling up in queue - it should not cause crash // We can ignore leveling up in queue - it should not cause crash
@ -394,7 +392,7 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou
// remove group queue info if needed // remove group queue info if needed
if (group->Players.empty()) if (group->Players.empty())
{ {
m_QueuedGroups[queue_id][index].erase(group_itr); m_QueuedGroups[bracket_id][index].erase(group_itr);
delete group; delete group;
} }
// if group wasn't empty, so it wasn't deleted, and player have left a rated // if group wasn't empty, so it wasn't deleted, and player have left a rated
@ -453,7 +451,7 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b
ginfo->IsInvitedToBGInstanceGUID = bg->GetInstanceID(); ginfo->IsInvitedToBGInstanceGUID = bg->GetInstanceID();
BattleGroundTypeId bgTypeId = bg->GetTypeID(); BattleGroundTypeId bgTypeId = bg->GetTypeID();
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, bg->GetArenaType()); BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, bg->GetArenaType());
BGQueueIdBasedOnLevel queue_id = bg->GetQueueId(); BattleGroundBracketId bracket_id = bg->GetBracketId();
// set ArenaTeamId for rated matches // set ArenaTeamId for rated matches
if (bg->isArena() && bg->isRated()) if (bg->isArena() && bg->isRated())
@ -471,7 +469,7 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b
continue; continue;
// invite the player // invite the player
PlayerInvitedToBGUpdateAverageWaitTime(ginfo, queue_id); PlayerInvitedToBGUpdateAverageWaitTime(ginfo, bracket_id);
//sBattleGroundMgr.InvitePlayer(plr, bg, ginfo->Team); //sBattleGroundMgr.InvitePlayer(plr, bg, ginfo->Team);
// set invited player counters // set invited player counters
@ -507,22 +505,22 @@ This function is inviting players to already running battlegrounds
Invitation type is based on config file Invitation type is based on config file
large groups are disadvantageous, because they will be kicked first if invitation type = 1 large groups are disadvantageous, because they will be kicked first if invitation type = 1
*/ */
void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel queue_id) void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BattleGroundBracketId bracket_id)
{ {
int32 hordeFree = bg->GetFreeSlotsForTeam(HORDE); int32 hordeFree = bg->GetFreeSlotsForTeam(HORDE);
int32 aliFree = bg->GetFreeSlotsForTeam(ALLIANCE); int32 aliFree = bg->GetFreeSlotsForTeam(ALLIANCE);
//iterator for iterating through bg queue //iterator for iterating through bg queue
GroupsQueueType::const_iterator Ali_itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].begin(); GroupsQueueType::const_iterator Ali_itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].begin();
//count of groups in queue - used to stop cycles //count of groups in queue - used to stop cycles
uint32 aliCount = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].size(); uint32 aliCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].size();
//index to queue which group is current //index to queue which group is current
uint32 aliIndex = 0; uint32 aliIndex = 0;
for (; aliIndex < aliCount && m_SelectionPools[BG_TEAM_ALLIANCE].AddGroup((*Ali_itr), aliFree); aliIndex++) for (; aliIndex < aliCount && m_SelectionPools[BG_TEAM_ALLIANCE].AddGroup((*Ali_itr), aliFree); aliIndex++)
++Ali_itr; ++Ali_itr;
//the same thing for horde //the same thing for horde
GroupsQueueType::const_iterator Horde_itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].begin(); GroupsQueueType::const_iterator Horde_itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].begin();
uint32 hordeCount = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].size(); uint32 hordeCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].size();
uint32 hordeIndex = 0; uint32 hordeIndex = 0;
for (; hordeIndex < hordeCount && m_SelectionPools[BG_TEAM_HORDE].AddGroup((*Horde_itr), hordeFree); hordeIndex++) for (; hordeIndex < hordeCount && m_SelectionPools[BG_TEAM_HORDE].AddGroup((*Horde_itr), hordeFree); hordeIndex++)
++Horde_itr; ++Horde_itr;
@ -585,22 +583,22 @@ void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel
// this method checks if premade versus premade battleground is possible // this method checks if premade versus premade battleground is possible
// then after 30 mins (default) in queue it moves premade group to normal queue // then after 30 mins (default) in queue it moves premade group to normal queue
// it tries to invite as much players as it can - to MaxPlayersPerTeam, because premade groups have more than MinPlayersPerTeam players // it tries to invite as much players as it can - to MaxPlayersPerTeam, because premade groups have more than MinPlayersPerTeam players
bool BattleGroundQueue::CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam) bool BattleGroundQueue::CheckPremadeMatch(BattleGroundBracketId bracket_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam)
{ {
//check match //check match
if (!m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].empty() && !m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].empty()) if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].empty() && !m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].empty())
{ {
//start premade match //start premade match
//if groups aren't invited //if groups aren't invited
GroupsQueueType::const_iterator ali_group, horde_group; GroupsQueueType::const_iterator ali_group, horde_group;
for( ali_group = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].begin(); ali_group != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].end(); ++ali_group) for( ali_group = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].begin(); ali_group != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].end(); ++ali_group)
if (!(*ali_group)->IsInvitedToBGInstanceGUID) if (!(*ali_group)->IsInvitedToBGInstanceGUID)
break; break;
for( horde_group = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].begin(); horde_group != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].end(); ++horde_group) for( horde_group = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].begin(); horde_group != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].end(); ++horde_group)
if (!(*horde_group)->IsInvitedToBGInstanceGUID) if (!(*horde_group)->IsInvitedToBGInstanceGUID)
break; break;
if (ali_group != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].end() && horde_group != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].end()) if (ali_group != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].end() && horde_group != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].end())
{ {
m_SelectionPools[BG_TEAM_ALLIANCE].AddGroup((*ali_group), MaxPlayersPerTeam); m_SelectionPools[BG_TEAM_ALLIANCE].AddGroup((*ali_group), MaxPlayersPerTeam);
m_SelectionPools[BG_TEAM_HORDE].AddGroup((*horde_group), MaxPlayersPerTeam); m_SelectionPools[BG_TEAM_HORDE].AddGroup((*horde_group), MaxPlayersPerTeam);
@ -609,7 +607,7 @@ bool BattleGroundQueue::CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32
GroupsQueueType::const_iterator itr; GroupsQueueType::const_iterator itr;
for(uint32 i = 0; i < BG_TEAMS_COUNT; i++) for(uint32 i = 0; i < BG_TEAMS_COUNT; i++)
{ {
for(itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin(); itr != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++itr) for(itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin(); itr != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++itr)
{ {
//if itr can join BG and player count is less that maxPlayers, then add group to selectionpool //if itr can join BG and player count is less that maxPlayers, then add group to selectionpool
if (!(*itr)->IsInvitedToBGInstanceGUID && !m_SelectionPools[i].AddGroup((*itr), maxPlayers)) if (!(*itr)->IsInvitedToBGInstanceGUID && !m_SelectionPools[i].AddGroup((*itr), maxPlayers))
@ -627,14 +625,14 @@ bool BattleGroundQueue::CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32
uint32 time_before = getMSTime() - sWorld.getConfig(CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH); uint32 time_before = getMSTime() - sWorld.getConfig(CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH);
for(uint32 i = 0; i < BG_TEAMS_COUNT; i++) for(uint32 i = 0; i < BG_TEAMS_COUNT; i++)
{ {
if (!m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE + i].empty()) if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE + i].empty())
{ {
GroupsQueueType::iterator itr = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE + i].begin(); GroupsQueueType::iterator itr = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE + i].begin();
if (!(*itr)->IsInvitedToBGInstanceGUID && ((*itr)->JoinTime < time_before || (*itr)->Players.size() < MinPlayersPerTeam)) if (!(*itr)->IsInvitedToBGInstanceGUID && ((*itr)->JoinTime < time_before || (*itr)->Players.size() < MinPlayersPerTeam))
{ {
//we must insert group to normal queue and erase pointer from premade queue //we must insert group to normal queue and erase pointer from premade queue
m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + i].push_front((*itr)); m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].push_front((*itr));
m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE + i].erase(itr); m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE + i].erase(itr);
} }
} }
} }
@ -643,13 +641,13 @@ bool BattleGroundQueue::CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32
} }
// this method tries to create battleground or arena with MinPlayersPerTeam against MinPlayersPerTeam // this method tries to create battleground or arena with MinPlayersPerTeam against MinPlayersPerTeam
bool BattleGroundQueue::CheckNormalMatch(BattleGround* bg_template, BGQueueIdBasedOnLevel queue_id, uint32 minPlayers, uint32 maxPlayers) bool BattleGroundQueue::CheckNormalMatch(BattleGround* bg_template, BattleGroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers)
{ {
GroupsQueueType::const_iterator itr_team[BG_TEAMS_COUNT]; GroupsQueueType::const_iterator itr_team[BG_TEAMS_COUNT];
for(uint32 i = 0; i < BG_TEAMS_COUNT; i++) for(uint32 i = 0; i < BG_TEAMS_COUNT; i++)
{ {
itr_team[i] = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin(); itr_team[i] = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].begin();
for(; itr_team[i] != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++(itr_team[i])) for(; itr_team[i] != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + i].end(); ++(itr_team[i]))
{ {
if (!(*(itr_team[i]))->IsInvitedToBGInstanceGUID) if (!(*(itr_team[i]))->IsInvitedToBGInstanceGUID)
{ {
@ -668,7 +666,7 @@ bool BattleGroundQueue::CheckNormalMatch(BattleGround* bg_template, BGQueueIdBas
{ {
//we will try to invite more groups to team with less players indexed by j //we will try to invite more groups to team with less players indexed by j
++(itr_team[j]); //this will not cause a crash, because for cycle above reached break; ++(itr_team[j]); //this will not cause a crash, because for cycle above reached break;
for(; itr_team[j] != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + j].end(); ++(itr_team[j])) for(; itr_team[j] != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + j].end(); ++(itr_team[j]))
{ {
if (!(*(itr_team[j]))->IsInvitedToBGInstanceGUID) if (!(*(itr_team[j]))->IsInvitedToBGInstanceGUID)
if (!m_SelectionPools[j].AddGroup(*(itr_team[j]), m_SelectionPools[(j + 1) % BG_TEAMS_COUNT].GetPlayerCount())) if (!m_SelectionPools[j].AddGroup(*(itr_team[j]), m_SelectionPools[(j + 1) % BG_TEAMS_COUNT].GetPlayerCount()))
@ -686,7 +684,7 @@ bool BattleGroundQueue::CheckNormalMatch(BattleGround* bg_template, BGQueueIdBas
} }
// this method will check if we can invite players to same faction skirmish match // this method will check if we can invite players to same faction skirmish match
bool BattleGroundQueue::CheckSkirmishForSameFaction(BGQueueIdBasedOnLevel queue_id, uint32 minPlayersPerTeam) bool BattleGroundQueue::CheckSkirmishForSameFaction(BattleGroundBracketId bracket_id, uint32 minPlayersPerTeam)
{ {
if (m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() < minPlayersPerTeam && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() < minPlayersPerTeam) if (m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() < minPlayersPerTeam && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() < minPlayersPerTeam)
return false; return false;
@ -704,16 +702,16 @@ bool BattleGroundQueue::CheckSkirmishForSameFaction(BGQueueIdBasedOnLevel queue_
//store last ginfo pointer //store last ginfo pointer
GroupQueueInfo* ginfo = m_SelectionPools[teamIndex].SelectedGroups.back(); GroupQueueInfo* ginfo = m_SelectionPools[teamIndex].SelectedGroups.back();
//set itr_team to group that was added to selection pool latest //set itr_team to group that was added to selection pool latest
GroupsQueueType::iterator itr_team = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].begin(); GroupsQueueType::iterator itr_team = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].begin();
for(; itr_team != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end(); ++itr_team) for(; itr_team != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end(); ++itr_team)
if (ginfo == *itr_team) if (ginfo == *itr_team)
break; break;
if (itr_team == m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end()) if (itr_team == m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end())
return false; return false;
GroupsQueueType::iterator itr_team2 = itr_team; GroupsQueueType::iterator itr_team2 = itr_team;
++itr_team2; ++itr_team2;
//invite players to other selection pool //invite players to other selection pool
for(; itr_team2 != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end(); ++itr_team2) for(; itr_team2 != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end(); ++itr_team2)
{ {
//if selection pool is full then break; //if selection pool is full then break;
if (!(*itr_team2)->IsInvitedToBGInstanceGUID && !m_SelectionPools[otherTeam].AddGroup(*itr_team2, minPlayersPerTeam)) if (!(*itr_team2)->IsInvitedToBGInstanceGUID && !m_SelectionPools[otherTeam].AddGroup(*itr_team2, minPlayersPerTeam))
@ -728,15 +726,15 @@ bool BattleGroundQueue::CheckSkirmishForSameFaction(BGQueueIdBasedOnLevel queue_
//set correct team //set correct team
(*itr)->Team = otherTeamId; (*itr)->Team = otherTeamId;
//add team to other queue //add team to other queue
m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + otherTeam].push_front(*itr); m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + otherTeam].push_front(*itr);
//remove team from old queue //remove team from old queue
GroupsQueueType::iterator itr2 = itr_team; GroupsQueueType::iterator itr2 = itr_team;
++itr2; ++itr2;
for(; itr2 != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end(); ++itr2) for(; itr2 != m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].end(); ++itr2)
{ {
if (*itr2 == *itr) if (*itr2 == *itr)
{ {
m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].erase(itr2); m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE + teamIndex].erase(itr2);
break; break;
} }
} }
@ -749,25 +747,25 @@ this method is called when group is inserted, or player / group is removed from
it must be called after fully adding the members of a group to ensure group joining it must be called after fully adding the members of a group to ensure group joining
should be called from BattleGround::RemovePlayer function in some cases should be called from BattleGround::RemovePlayer function in some cases
*/ */
void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType, bool isRated, uint32 arenaRating) void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id, uint8 arenaType, bool isRated, uint32 arenaRating)
{ {
//ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_Lock); //ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_Lock);
//if no players in queue - do nothing //if no players in queue - do nothing
if( m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].empty() && if( m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].empty() &&
m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].empty() && m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].empty() &&
m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].empty() && m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].empty() &&
m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].empty() ) m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].empty() )
return; return;
//battleground with free slot for player should be always in the beggining of the queue //battleground with free slot for player should be always in the beggining of the queue
// maybe it would be better to create bgfreeslotqueue for each queue_id_based_on_level // maybe it would be better to create bgfreeslotqueue for each bracket_id
BGFreeSlotQueueType::iterator itr, next; BGFreeSlotQueueType::iterator itr, next;
for (itr = sBattleGroundMgr.BGFreeSlotQueue[bgTypeId].begin(); itr != sBattleGroundMgr.BGFreeSlotQueue[bgTypeId].end(); itr = next) for (itr = sBattleGroundMgr.BGFreeSlotQueue[bgTypeId].begin(); itr != sBattleGroundMgr.BGFreeSlotQueue[bgTypeId].end(); itr = next)
{ {
next = itr; next = itr;
++next; ++next;
// DO NOT allow queue manager to invite new player to arena // DO NOT allow queue manager to invite new player to arena
if( (*itr)->isBattleGround() && (*itr)->GetTypeID() == bgTypeId && (*itr)->GetQueueId() == queue_id && if( (*itr)->isBattleGround() && (*itr)->GetTypeID() == bgTypeId && (*itr)->GetBracketId() == bracket_id &&
(*itr)->GetStatus() > STATUS_WAIT_QUEUE && (*itr)->GetStatus() < STATUS_WAIT_LEAVE ) (*itr)->GetStatus() > STATUS_WAIT_QUEUE && (*itr)->GetStatus() < STATUS_WAIT_LEAVE )
{ {
BattleGround* bg = *itr; //we have to store battleground pointer here, because when battleground is full, it is removed from free queue (not yet implemented!!) BattleGround* bg = *itr; //we have to store battleground pointer here, because when battleground is full, it is removed from free queue (not yet implemented!!)
@ -778,7 +776,7 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
m_SelectionPools[BG_TEAM_HORDE].Init(); m_SelectionPools[BG_TEAM_HORDE].Init();
// call a function that does the job for us // call a function that does the job for us
FillPlayersToBG(bg, queue_id); FillPlayersToBG(bg, bracket_id);
// now everything is set, invite players // now everything is set, invite players
for(GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_ALLIANCE].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_ALLIANCE].SelectedGroups.end(); ++citr) for(GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_ALLIANCE].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_ALLIANCE].SelectedGroups.end(); ++citr)
@ -843,11 +841,11 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
if (bg_template->isBattleGround()) if (bg_template->isBattleGround())
{ {
//check if there is premade against premade match //check if there is premade against premade match
if (CheckPremadeMatch(queue_id, MinPlayersPerTeam, MaxPlayersPerTeam)) if (CheckPremadeMatch(bracket_id, MinPlayersPerTeam, MaxPlayersPerTeam))
{ {
//create new battleground //create new battleground
BattleGround * bg2 = NULL; BattleGround * bg2 = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, bracket_id, 0, false);
if (!(bg2 = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, queue_id, 0, false))) if (!bg2)
{ {
sLog.outError("BattleGroundQueue::Update - Cannot create battleground: %u", bgTypeId); sLog.outError("BattleGroundQueue::Update - Cannot create battleground: %u", bgTypeId);
return; return;
@ -868,12 +866,12 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
if (!isRated) if (!isRated)
{ {
// if there are enough players in pools, start new battleground or non rated arena // if there are enough players in pools, start new battleground or non rated arena
if (CheckNormalMatch(bg_template, queue_id, MinPlayersPerTeam, MaxPlayersPerTeam) if (CheckNormalMatch(bg_template, bracket_id, MinPlayersPerTeam, MaxPlayersPerTeam)
|| (bg_template->isArena() && CheckSkirmishForSameFaction(queue_id, MinPlayersPerTeam)) ) || (bg_template->isArena() && CheckSkirmishForSameFaction(bracket_id, MinPlayersPerTeam)) )
{ {
// we successfully created a pool // we successfully created a pool
BattleGround * bg2 = NULL; BattleGround * bg2 = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, bracket_id, arenaType, false);
if (!(bg2 = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, queue_id, arenaType, false))) if (!bg2)
{ {
sLog.outError("BattleGroundQueue::Update - Cannot create battleground: %u", bgTypeId); sLog.outError("BattleGroundQueue::Update - Cannot create battleground: %u", bgTypeId);
return; return;
@ -896,14 +894,14 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
{ {
GroupQueueInfo* front1 = NULL; GroupQueueInfo* front1 = NULL;
GroupQueueInfo* front2 = NULL; GroupQueueInfo* front2 = NULL;
if (!m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].empty()) if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].empty())
{ {
front1 = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].front(); front1 = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].front();
arenaRating = front1->ArenaTeamRating; arenaRating = front1->ArenaTeamRating;
} }
if (!m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].empty()) if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].empty())
{ {
front2 = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].front(); front2 = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].front();
arenaRating = front2->ArenaTeamRating; arenaRating = front2->ArenaTeamRating;
} }
if (front1 && front2) if (front1 && front2)
@ -933,8 +931,8 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
for(uint32 i = BG_QUEUE_PREMADE_ALLIANCE; i < BG_QUEUE_NORMAL_ALLIANCE; i++) for(uint32 i = BG_QUEUE_PREMADE_ALLIANCE; i < BG_QUEUE_NORMAL_ALLIANCE; i++)
{ {
// take the group that joined first // take the group that joined first
itr_team[i] = m_QueuedGroups[queue_id][i].begin(); itr_team[i] = m_QueuedGroups[bracket_id][i].begin();
for(; itr_team[i] != m_QueuedGroups[queue_id][i].end(); ++(itr_team[i])) for(; itr_team[i] != m_QueuedGroups[bracket_id][i].end(); ++(itr_team[i]))
{ {
// if group match conditions, then add it to pool // if group match conditions, then add it to pool
if( !(*itr_team[i])->IsInvitedToBGInstanceGUID if( !(*itr_team[i])->IsInvitedToBGInstanceGUID
@ -955,7 +953,7 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
{ {
itr_team[BG_TEAM_ALLIANCE] = itr_team[BG_TEAM_HORDE]; itr_team[BG_TEAM_ALLIANCE] = itr_team[BG_TEAM_HORDE];
++itr_team[BG_TEAM_ALLIANCE]; ++itr_team[BG_TEAM_ALLIANCE];
for(; itr_team[BG_TEAM_ALLIANCE] != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].end(); ++(itr_team[BG_TEAM_ALLIANCE])) for(; itr_team[BG_TEAM_ALLIANCE] != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].end(); ++(itr_team[BG_TEAM_ALLIANCE]))
{ {
if( !(*itr_team[BG_TEAM_ALLIANCE])->IsInvitedToBGInstanceGUID if( !(*itr_team[BG_TEAM_ALLIANCE])->IsInvitedToBGInstanceGUID
&& (((*itr_team[BG_TEAM_ALLIANCE])->ArenaTeamRating >= arenaMinRating && (*itr_team[BG_TEAM_ALLIANCE])->ArenaTeamRating <= arenaMaxRating) && (((*itr_team[BG_TEAM_ALLIANCE])->ArenaTeamRating >= arenaMinRating && (*itr_team[BG_TEAM_ALLIANCE])->ArenaTeamRating <= arenaMaxRating)
@ -971,7 +969,7 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
{ {
itr_team[BG_TEAM_HORDE] = itr_team[BG_TEAM_ALLIANCE]; itr_team[BG_TEAM_HORDE] = itr_team[BG_TEAM_ALLIANCE];
++itr_team[BG_TEAM_HORDE]; ++itr_team[BG_TEAM_HORDE];
for(; itr_team[BG_TEAM_HORDE] != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].end(); ++(itr_team[BG_TEAM_HORDE])) for(; itr_team[BG_TEAM_HORDE] != m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].end(); ++(itr_team[BG_TEAM_HORDE]))
{ {
if( !(*itr_team[BG_TEAM_HORDE])->IsInvitedToBGInstanceGUID if( !(*itr_team[BG_TEAM_HORDE])->IsInvitedToBGInstanceGUID
&& (((*itr_team[BG_TEAM_HORDE])->ArenaTeamRating >= arenaMinRating && (*itr_team[BG_TEAM_HORDE])->ArenaTeamRating <= arenaMaxRating) && (((*itr_team[BG_TEAM_HORDE])->ArenaTeamRating >= arenaMinRating && (*itr_team[BG_TEAM_HORDE])->ArenaTeamRating <= arenaMaxRating)
@ -987,7 +985,7 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
if (m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount()) if (m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount())
{ {
BattleGround* arena = NULL; BattleGround* arena = NULL;
if (!(arena = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, queue_id, arenaType, true))) if (!(arena = sBattleGroundMgr.CreateNewBattleGround(bgTypeId, bracket_id, arenaType, true)))
{ {
sLog.outError("BattlegroundQueue::Update couldn't create arena instance for rated arena match!"); sLog.outError("BattlegroundQueue::Update couldn't create arena instance for rated arena match!");
return; return;
@ -1001,16 +999,16 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
if ((*(itr_team[BG_TEAM_ALLIANCE]))->Team != ALLIANCE) if ((*(itr_team[BG_TEAM_ALLIANCE]))->Team != ALLIANCE)
{ {
// add to alliance queue // add to alliance queue
m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].push_front(*(itr_team[BG_TEAM_ALLIANCE])); m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].push_front(*(itr_team[BG_TEAM_ALLIANCE]));
// erase from horde queue // erase from horde queue
m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].erase(itr_team[BG_TEAM_ALLIANCE]); m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].erase(itr_team[BG_TEAM_ALLIANCE]);
itr_team[BG_TEAM_ALLIANCE] = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].begin(); itr_team[BG_TEAM_ALLIANCE] = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].begin();
} }
if ((*(itr_team[BG_TEAM_HORDE]))->Team != HORDE) if ((*(itr_team[BG_TEAM_HORDE]))->Team != HORDE)
{ {
m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].push_front(*(itr_team[BG_TEAM_HORDE])); m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].push_front(*(itr_team[BG_TEAM_HORDE]));
m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].erase(itr_team[BG_TEAM_HORDE]); m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].erase(itr_team[BG_TEAM_HORDE]);
itr_team[BG_TEAM_HORDE] = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].begin(); itr_team[BG_TEAM_HORDE] = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].begin();
} }
InviteGroupToBG(*(itr_team[BG_TEAM_ALLIANCE]), arena, ALLIANCE); InviteGroupToBG(*(itr_team[BG_TEAM_ALLIANCE]), arena, ALLIANCE);
@ -1094,7 +1092,7 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
bgQueue.RemovePlayer(m_PlayerGuid, true); bgQueue.RemovePlayer(m_PlayerGuid, true);
//update queues if battleground isn't ended //update queues if battleground isn't ended
if (bg && bg->isBattleGround() && bg->GetStatus() != STATUS_WAIT_LEAVE) if (bg && bg->isBattleGround() && bg->GetStatus() != STATUS_WAIT_LEAVE)
sBattleGroundMgr.ScheduleQueueUpdate(0, 0, m_BgQueueTypeId, m_BgTypeId, bg->GetQueueId()); sBattleGroundMgr.ScheduleQueueUpdate(0, 0, m_BgQueueTypeId, m_BgTypeId, bg->GetBracketId());
WorldPacket data; WorldPacket data;
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0); sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0);
@ -1136,8 +1134,8 @@ void BattleGroundMgr::DeleteAllBattleGrounds()
{ {
BattleGround * bg = itr->second; BattleGround * bg = itr->second;
m_BattleGrounds[i].erase(itr++); m_BattleGrounds[i].erase(itr++);
if (!m_ClientBattleGroundIds[i][bg->GetQueueId()].empty()) if (!m_ClientBattleGroundIds[i][bg->GetBracketId()].empty())
m_ClientBattleGroundIds[i][bg->GetQueueId()].erase(bg->GetClientInstanceID()); m_ClientBattleGroundIds[i][bg->GetBracketId()].erase(bg->GetClientInstanceID());
delete bg; delete bg;
} }
} }
@ -1172,8 +1170,8 @@ void BattleGroundMgr::Update(uint32 diff)
{ {
BattleGround * bg = itr->second; BattleGround * bg = itr->second;
m_BattleGrounds[i].erase(itr); m_BattleGrounds[i].erase(itr);
if (!m_ClientBattleGroundIds[i][bg->GetQueueId()].empty()) if (!m_ClientBattleGroundIds[i][bg->GetBracketId()].empty())
m_ClientBattleGroundIds[i][bg->GetQueueId()].erase(bg->GetClientInstanceID()); m_ClientBattleGroundIds[i][bg->GetBracketId()].erase(bg->GetClientInstanceID());
delete bg; delete bg;
} }
} }
@ -1198,8 +1196,8 @@ void BattleGroundMgr::Update(uint32 diff)
uint8 arenaType = scheduled[i] >> 24 & 255; uint8 arenaType = scheduled[i] >> 24 & 255;
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundQueueTypeId(scheduled[i] >> 16 & 255); BattleGroundQueueTypeId bgQueueTypeId = BattleGroundQueueTypeId(scheduled[i] >> 16 & 255);
BattleGroundTypeId bgTypeId = BattleGroundTypeId((scheduled[i] >> 8) & 255); BattleGroundTypeId bgTypeId = BattleGroundTypeId((scheduled[i] >> 8) & 255);
BGQueueIdBasedOnLevel queue_id = BGQueueIdBasedOnLevel(scheduled[i] & 255); BattleGroundBracketId bracket_id = BattleGroundBracketId(scheduled[i] & 255);
m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, queue_id, arenaType, arenaRating > 0, arenaRating); m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, bracket_id, arenaType, arenaRating > 0, arenaRating);
} }
} }
@ -1211,12 +1209,12 @@ void BattleGroundMgr::Update(uint32 diff)
{ {
// forced update for level 70 rated arenas // forced update for level 70 rated arenas
sLog.outDebug("BattleGroundMgr: UPDATING ARENA QUEUES"); sLog.outDebug("BattleGroundMgr: UPDATING ARENA QUEUES");
m_BattleGroundQueues[BATTLEGROUND_QUEUE_2v2].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_79, ARENA_TYPE_2v2, true, 0); m_BattleGroundQueues[BATTLEGROUND_QUEUE_2v2].Update(BATTLEGROUND_AA, BG_BRACKET_ID_MAX_LEVEL_79, ARENA_TYPE_2v2, true, 0);
m_BattleGroundQueues[BATTLEGROUND_QUEUE_2v2].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_80, ARENA_TYPE_2v2, true, 0); m_BattleGroundQueues[BATTLEGROUND_QUEUE_2v2].Update(BATTLEGROUND_AA, BG_BRACKET_ID_MAX_LEVEL_80, ARENA_TYPE_2v2, true, 0);
m_BattleGroundQueues[BATTLEGROUND_QUEUE_3v3].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_79, ARENA_TYPE_3v3, true, 0); m_BattleGroundQueues[BATTLEGROUND_QUEUE_3v3].Update(BATTLEGROUND_AA, BG_BRACKET_ID_MAX_LEVEL_79, ARENA_TYPE_3v3, true, 0);
m_BattleGroundQueues[BATTLEGROUND_QUEUE_3v3].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_80, ARENA_TYPE_3v3, true, 0); m_BattleGroundQueues[BATTLEGROUND_QUEUE_3v3].Update(BATTLEGROUND_AA, BG_BRACKET_ID_MAX_LEVEL_80, ARENA_TYPE_3v3, true, 0);
m_BattleGroundQueues[BATTLEGROUND_QUEUE_5v5].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_79, ARENA_TYPE_5v5, true, 0); m_BattleGroundQueues[BATTLEGROUND_QUEUE_5v5].Update(BATTLEGROUND_AA, BG_BRACKET_ID_MAX_LEVEL_79, ARENA_TYPE_5v5, true, 0);
m_BattleGroundQueues[BATTLEGROUND_QUEUE_5v5].Update(BATTLEGROUND_AA, QUEUE_ID_MAX_LEVEL_80, ARENA_TYPE_5v5, true, 0); m_BattleGroundQueues[BATTLEGROUND_QUEUE_5v5].Update(BATTLEGROUND_AA, BG_BRACKET_ID_MAX_LEVEL_80, ARENA_TYPE_5v5, true, 0);
m_NextRatingDiscardUpdate = sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER); m_NextRatingDiscardUpdate = sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER);
} }
else else
@ -1473,7 +1471,7 @@ BattleGround * BattleGroundMgr::GetBattleGroundTemplate(BattleGroundTypeId bgTyp
return m_BattleGrounds[bgTypeId].empty() ? NULL : m_BattleGrounds[bgTypeId].begin()->second; return m_BattleGrounds[bgTypeId].empty() ? NULL : m_BattleGrounds[bgTypeId].begin()->second;
} }
uint32 BattleGroundMgr::CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id) uint32 BattleGroundMgr::CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id)
{ {
if (IsArenaType(bgTypeId)) if (IsArenaType(bgTypeId))
return 0; //arenas don't have client-instanceids return 0; //arenas don't have client-instanceids
@ -1485,18 +1483,18 @@ uint32 BattleGroundMgr::CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeI
// the following works, because std::set is default ordered with "<" // the following works, because std::set is default ordered with "<"
// the optimalization would be to use as bitmask std::vector<uint32> - but that would only make code unreadable // the optimalization would be to use as bitmask std::vector<uint32> - but that would only make code unreadable
uint32 lastId = 0; uint32 lastId = 0;
for(std::set<uint32>::iterator itr = m_ClientBattleGroundIds[bgTypeId][queue_id].begin(); itr != m_ClientBattleGroundIds[bgTypeId][queue_id].end();) for(std::set<uint32>::iterator itr = m_ClientBattleGroundIds[bgTypeId][bracket_id].begin(); itr != m_ClientBattleGroundIds[bgTypeId][bracket_id].end();)
{ {
if( (++lastId) != *itr) //if there is a gap between the ids, we will break.. if( (++lastId) != *itr) //if there is a gap between the ids, we will break..
break; break;
lastId = *itr; lastId = *itr;
} }
m_ClientBattleGroundIds[bgTypeId][queue_id].insert(lastId + 1); m_ClientBattleGroundIds[bgTypeId][bracket_id].insert(lastId + 1);
return lastId + 1; return lastId + 1;
} }
// create a new battleground that will really be used to play // create a new battleground that will really be used to play
BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType, bool isRated) BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id, uint8 arenaType, bool isRated)
{ {
// get the template BG // get the template BG
BattleGround *bg_template = GetBattleGroundTemplate(bgTypeId); BattleGround *bg_template = GetBattleGroundTemplate(bgTypeId);
@ -1570,14 +1568,14 @@ BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeI
// generate a new instance id // generate a new instance id
bg->SetInstanceID(sMapMgr.GenerateInstanceId()); // set instance id bg->SetInstanceID(sMapMgr.GenerateInstanceId()); // set instance id
bg->SetClientInstanceID(CreateClientVisibleInstanceId(bgTypeId, queue_id)); bg->SetClientInstanceID(CreateClientVisibleInstanceId(bgTypeId, bracket_id));
// reset the new bg (set status to status_wait_queue from status_none) // reset the new bg (set status to status_wait_queue from status_none)
bg->Reset(); bg->Reset();
// start the joining of the bg // start the joining of the bg
bg->SetStatus(STATUS_WAIT_JOIN); bg->SetStatus(STATUS_WAIT_JOIN);
bg->SetQueueId(queue_id); bg->SetBracketId(bracket_id);
bg->SetArenaType(arenaType); bg->SetArenaType(arenaType);
bg->SetRated(isRated); bg->SetRated(isRated);
@ -1824,9 +1822,6 @@ void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, const uint6
if (!plr) if (!plr)
return; return;
uint32 PlayerLevel = 10;
PlayerLevel = plr->getLevel();
data->Initialize(SMSG_BATTLEFIELD_LIST); data->Initialize(SMSG_BATTLEFIELD_LIST);
*data << uint64(guid); // battlemaster guid *data << uint64(guid); // battlemaster guid
*data << uint8(fromWhere); // from where you joined *data << uint8(fromWhere); // from where you joined
@ -1846,8 +1841,8 @@ void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, const uint6
uint32 count = 0; uint32 count = 0;
*data << uint32(0); // number of bg instances *data << uint32(0); // number of bg instances
uint32 queue_id = plr->GetBattleGroundQueueIdFromLevel(); uint32 bracket_id = plr->GetBattleGroundBracketIdFromLevel();
for(std::set<uint32>::iterator itr = m_ClientBattleGroundIds[bgTypeId][queue_id].begin(); itr != m_ClientBattleGroundIds[bgTypeId][queue_id].end();++itr) for(std::set<uint32>::iterator itr = m_ClientBattleGroundIds[bgTypeId][bracket_id].begin(); itr != m_ClientBattleGroundIds[bgTypeId][bracket_id].end();++itr)
{ {
*data << uint32(*itr); *data << uint32(*itr);
++count; ++count;
@ -1983,11 +1978,11 @@ void BattleGroundMgr::ToggleArenaTesting()
sWorld.SendWorldText(LANG_DEBUG_ARENA_OFF); sWorld.SendWorldText(LANG_DEBUG_ARENA_OFF);
} }
void BattleGroundMgr::ScheduleQueueUpdate(uint32 arenaRating, uint8 arenaType, BattleGroundQueueTypeId bgQueueTypeId, BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id) void BattleGroundMgr::ScheduleQueueUpdate(uint32 arenaRating, uint8 arenaType, BattleGroundQueueTypeId bgQueueTypeId, BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id)
{ {
//ACE_Guard<ACE_Thread_Mutex> guard(SchedulerLock); //ACE_Guard<ACE_Thread_Mutex> guard(SchedulerLock);
//we will use only 1 number created of bgTypeId and queue_id //we will use only 1 number created of bgTypeId and bracket_id
uint64 schedule_id = ((uint64)arenaRating << 32) | (arenaType << 24) | (bgQueueTypeId << 16) | (bgTypeId << 8) | queue_id; uint64 schedule_id = ((uint64)arenaRating << 32) | (arenaType << 24) | (bgQueueTypeId << 16) | (bgTypeId << 8) | bracket_id;
bool found = false; bool found = false;
for (uint8 i = 0; i < m_QueueUpdateScheduler.size(); i++) for (uint8 i = 0; i < m_QueueUpdateScheduler.size(); i++)
{ {

View file

@ -75,18 +75,18 @@ class BattleGroundQueue
BattleGroundQueue(); BattleGroundQueue();
~BattleGroundQueue(); ~BattleGroundQueue();
void Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType = 0, bool isRated = false, uint32 minRating = 0); void Update(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id, uint8 arenaType = 0, bool isRated = false, uint32 minRating = 0);
void FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel queue_id); void FillPlayersToBG(BattleGround* bg, BattleGroundBracketId bracket_id);
bool CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam); bool CheckPremadeMatch(BattleGroundBracketId bracket_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam);
bool CheckNormalMatch(BattleGround* bg_template, BGQueueIdBasedOnLevel queue_id, uint32 minPlayers, uint32 maxPlayers); bool CheckNormalMatch(BattleGround* bg_template, BattleGroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers);
bool CheckSkirmishForSameFaction(BGQueueIdBasedOnLevel queue_id, uint32 minPlayersPerTeam); bool CheckSkirmishForSameFaction(BattleGroundBracketId bracket_id, uint32 minPlayersPerTeam);
GroupQueueInfo * AddGroup(Player* leader, Group* group, BattleGroundTypeId bgTypeId, uint8 ArenaType, bool isRated, bool isPremade, uint32 ArenaRating, uint32 ArenaTeamId = 0); GroupQueueInfo * AddGroup(Player* leader, Group* group, BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id, uint8 ArenaType, bool isRated, bool isPremade, uint32 ArenaRating, uint32 ArenaTeamId = 0);
void RemovePlayer(const uint64& guid, bool decreaseInvitedCount); void RemovePlayer(const uint64& guid, bool decreaseInvitedCount);
bool IsPlayerInvited(const uint64& pl_guid, const uint32 bgInstanceGuid, const uint32 removeTime); bool IsPlayerInvited(const uint64& pl_guid, const uint32 bgInstanceGuid, const uint32 removeTime);
bool GetPlayerGroupInfoData(const uint64& guid, GroupQueueInfo* ginfo); bool GetPlayerGroupInfoData(const uint64& guid, GroupQueueInfo* ginfo);
void PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id); void PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BattleGroundBracketId bracket_id);
uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id); uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BattleGroundBracketId bracket_id);
private: private:
//mutex that should not allow changing private data, nor allowing to update Queue during private data change. //mutex that should not allow changing private data, nor allowing to update Queue during private data change.
@ -108,7 +108,7 @@ class BattleGroundQueue
BG_QUEUE_NORMAL_ALLIANCE is used for normal (or small) alliance groups or non-rated arena matches BG_QUEUE_NORMAL_ALLIANCE is used for normal (or small) alliance groups or non-rated arena matches
BG_QUEUE_NORMAL_HORDE is used for normal (or small) horde groups or non-rated arena matches BG_QUEUE_NORMAL_HORDE is used for normal (or small) horde groups or non-rated arena matches
*/ */
GroupsQueueType m_QueuedGroups[MAX_BATTLEGROUND_QUEUES][BG_QUEUE_GROUP_TYPES_COUNT]; GroupsQueueType m_QueuedGroups[MAX_BATTLEGROUND_BRACKETS][BG_QUEUE_GROUP_TYPES_COUNT];
// class to select and invite groups to bg // class to select and invite groups to bg
class SelectionPool class SelectionPool
@ -128,9 +128,9 @@ class BattleGroundQueue
SelectionPool m_SelectionPools[BG_TEAMS_COUNT]; SelectionPool m_SelectionPools[BG_TEAMS_COUNT];
bool InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * bg, uint32 side); bool InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * bg, uint32 side);
uint32 m_WaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME]; uint32 m_WaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME];
uint32 m_WaitTimeLastPlayer[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES]; uint32 m_WaitTimeLastPlayer[BG_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS];
uint32 m_SumOfWaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES]; uint32 m_SumOfWaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS];
}; };
/* /*
@ -203,13 +203,13 @@ class BattleGroundMgr
BattleGround* GetBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId); //there must be uint32 because MAX_BATTLEGROUND_TYPE_ID means unknown BattleGround* GetBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId); //there must be uint32 because MAX_BATTLEGROUND_TYPE_ID means unknown
BattleGround* GetBattleGroundTemplate(BattleGroundTypeId bgTypeId); BattleGround* GetBattleGroundTemplate(BattleGroundTypeId bgTypeId);
BattleGround* CreateNewBattleGround(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType, bool isRated); BattleGround* CreateNewBattleGround(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id, uint8 arenaType, bool isRated);
uint32 CreateBattleGround(BattleGroundTypeId bgTypeId, bool IsArena, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO); uint32 CreateBattleGround(BattleGroundTypeId bgTypeId, bool IsArena, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO);
void AddBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId, BattleGround* BG) { m_BattleGrounds[bgTypeId][InstanceID] = BG; }; void AddBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId, BattleGround* BG) { m_BattleGrounds[bgTypeId][InstanceID] = BG; };
void RemoveBattleGround(uint32 instanceID, BattleGroundTypeId bgTypeId) { m_BattleGrounds[bgTypeId].erase(instanceID); } void RemoveBattleGround(uint32 instanceID, BattleGroundTypeId bgTypeId) { m_BattleGrounds[bgTypeId].erase(instanceID); }
uint32 CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id); uint32 CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id);
void CreateInitialBattleGrounds(); void CreateInitialBattleGrounds();
void DeleteAllBattleGrounds(); void DeleteAllBattleGrounds();
@ -222,7 +222,7 @@ class BattleGroundMgr
BGFreeSlotQueueType BGFreeSlotQueue[MAX_BATTLEGROUND_TYPE_ID]; BGFreeSlotQueueType BGFreeSlotQueue[MAX_BATTLEGROUND_TYPE_ID];
void ScheduleQueueUpdate(uint32 arenaRating, uint8 arenaType, BattleGroundQueueTypeId bgQueueTypeId, BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id); void ScheduleQueueUpdate(uint32 arenaRating, uint8 arenaType, BattleGroundQueueTypeId bgQueueTypeId, BattleGroundTypeId bgTypeId, BattleGroundBracketId bracket_id);
uint32 GetMaxRatingDifference() const; uint32 GetMaxRatingDifference() const;
uint32 GetRatingDiscardTimer() const; uint32 GetRatingDiscardTimer() const;
uint32 GetPrematureFinishTime() const; uint32 GetPrematureFinishTime() const;
@ -276,7 +276,7 @@ class BattleGroundMgr
/* Battlegrounds */ /* Battlegrounds */
BattleGroundSet m_BattleGrounds[MAX_BATTLEGROUND_TYPE_ID]; BattleGroundSet m_BattleGrounds[MAX_BATTLEGROUND_TYPE_ID];
std::vector<uint64> m_QueueUpdateScheduler; std::vector<uint64> m_QueueUpdateScheduler;
std::set<uint32> m_ClientBattleGroundIds[MAX_BATTLEGROUND_TYPE_ID][MAX_BATTLEGROUND_QUEUES]; //the instanceids just visible for the client std::set<uint32> m_ClientBattleGroundIds[MAX_BATTLEGROUND_TYPE_ID][MAX_BATTLEGROUND_BRACKETS]; //the instanceids just visible for the client
uint32 m_NextRatingDiscardUpdate; uint32 m_NextRatingDiscardUpdate;
time_t m_NextAutoDistributionTime; time_t m_NextAutoDistributionTime;
uint32 m_AutoDistributionTimeChecker; uint32 m_AutoDistributionTimeChecker;

View file

@ -771,7 +771,7 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
} }
case ACTION_T_FORCE_DESPAWN: case ACTION_T_FORCE_DESPAWN:
{ {
m_creature->ForcedDespawn(); m_creature->ForcedDespawn(action.forced_despawn.msDelay);
break; break;
} }
case ACTION_T_SET_INVINCIBILITY_HP_LEVEL: case ACTION_T_SET_INVINCIBILITY_HP_LEVEL:

View file

@ -364,7 +364,12 @@ struct CreatureEventAI_Action
{ {
uint32 sheath; uint32 sheath;
} set_sheath; } set_sheath;
// ACTION_T_SET_INVINCIBILITY_HP_LEVEL = 42 // ACTION_T_FORCE_DESPAWN = 41
struct
{
uint32 msDelay;
} forced_despawn;
// ACTION_T_SET_INVINCIBILITY_HP_LEVEL = 42
struct struct
{ {
uint32 hp_level; uint32 hp_level;

View file

@ -1477,7 +1477,7 @@ uint32 Group::CanJoinBattleGroundQueue(BattleGroundTypeId bgTypeId, BattleGround
if(!reference) if(!reference)
return BG_JOIN_ERR_OFFLINE_MEMBER; return BG_JOIN_ERR_OFFLINE_MEMBER;
BGQueueIdBasedOnLevel queue_id = reference->GetBattleGroundQueueIdFromLevel(); BattleGroundBracketId bracket_id = reference->GetBattleGroundBracketIdFromLevel();
uint32 arenaTeamId = reference->GetArenaTeamId(arenaSlot); uint32 arenaTeamId = reference->GetArenaTeamId(arenaSlot);
uint32 team = reference->GetTeam(); uint32 team = reference->GetTeam();
@ -1492,7 +1492,7 @@ uint32 Group::CanJoinBattleGroundQueue(BattleGroundTypeId bgTypeId, BattleGround
if(member->GetTeam() != team) if(member->GetTeam() != team)
return BG_JOIN_ERR_MIXED_FACTION; return BG_JOIN_ERR_MIXED_FACTION;
// not in the same battleground level braket, don't let join // not in the same battleground level braket, don't let join
if(member->GetBattleGroundQueueIdFromLevel() != queue_id) if(member->GetBattleGroundBracketIdFromLevel() != bracket_id)
return BG_JOIN_ERR_MIXED_LEVELS; return BG_JOIN_ERR_MIXED_LEVELS;
// don't let join rated matches if the arena team id doesn't match // don't let join rated matches if the arena team id doesn't match
if(isRated && member->GetArenaTeamId(arenaSlot) != arenaTeamId) if(isRated && member->GetArenaTeamId(arenaSlot) != arenaTeamId)

View file

@ -217,7 +217,7 @@ BattleGroundMap* MapInstanced::CreateBattleGroundMap(uint32 InstanceId, BattleGr
sLog.outDebug("MapInstanced::CreateBattleGroundMap: instance:%d for map:%d and bgType:%d created.", InstanceId, GetId(), bg->GetTypeID()); sLog.outDebug("MapInstanced::CreateBattleGroundMap: instance:%d for map:%d and bgType:%d created.", InstanceId, GetId(), bg->GetTypeID());
// 0-59 normal spawn 60-69 difficulty_1, 70-79 difficulty_2, 80 dufficulty_3 // 0-59 normal spawn 60-69 difficulty_1, 70-79 difficulty_2, 80 dufficulty_3
uint8 spawnMode = (bg->GetQueueId() > QUEUE_ID_MAX_LEVEL_59) ? (bg->GetQueueId() - QUEUE_ID_MAX_LEVEL_59) : 0; uint8 spawnMode = (bg->GetBracketId() > BG_BRACKET_ID_MAX_LEVEL_59) ? (bg->GetBracketId() - BG_BRACKET_ID_MAX_LEVEL_59) : 0;
// some bgs don't have different spawnmodes, with this we can stay close to dbc-data // some bgs don't have different spawnmodes, with this we can stay close to dbc-data
while (!GetMapDifficultyData(GetId(), Difficulty(spawnMode))) while (!GetMapDifficultyData(GetId(), Difficulty(spawnMode)))
spawnMode--; spawnMode--;

View file

@ -19179,16 +19179,16 @@ bool Player::GetBGAccessByLevel(BattleGroundTypeId bgTypeId) const
return true; return true;
} }
BGQueueIdBasedOnLevel Player::GetBattleGroundQueueIdFromLevel() const BattleGroundBracketId Player::GetBattleGroundBracketIdFromLevel() const
{ {
// for ranges 0 - 19, 20 - 29, 30 - 39, 40 - 49, 50 - 59, 60 - 69, 70 - 79, 80 // for ranges 0 - 19, 20 - 29, 30 - 39, 40 - 49, 50 - 59, 60 - 69, 70 - 79, 80
uint32 queue_id = ( getLevel() / 10) - 1; uint32 bracket_id = ( getLevel() / 10) - 1;
if( queue_id >= MAX_BATTLEGROUND_QUEUES ) if( bracket_id >= MAX_BATTLEGROUND_BRACKETS )
{ {
sLog.outError("BattleGround: too high queue_id %u for player %u (acc: %u) with level %u", queue_id, GetGUIDLow(), GetSession()->GetAccountId(), getLevel()); sLog.outError("BattleGround: too high bracket_id %u for player %u (acc: %u) with level %u", bracket_id, GetGUIDLow(), GetSession()->GetAccountId(), getLevel());
return QUEUE_ID_MAX_LEVEL_80; return BG_BRACKET_ID_LAST;
} }
return BGQueueIdBasedOnLevel(queue_id); return BattleGroundBracketId(bracket_id);
} }
float Player::GetReputationPriceDiscount( Creature const* pCreature ) const float Player::GetReputationPriceDiscount( Creature const* pCreature ) const

View file

@ -2017,7 +2017,7 @@ class MANGOS_DLL_SPEC Player : public Unit
BattleGround* GetBattleGround() const; BattleGround* GetBattleGround() const;
BGQueueIdBasedOnLevel GetBattleGroundQueueIdFromLevel() const; BattleGroundBracketId GetBattleGroundBracketIdFromLevel() const;
bool InBattleGroundQueue() const bool InBattleGroundQueue() const
{ {

View file

@ -1175,6 +1175,7 @@ void Spell::EffectDummy(uint32 i)
return; return;
} }
case 46167: // Planning for the Future: Create Snowfall Glade Pup Cover
case 50926: // Gluttonous Lurkers: Create Zul'Drak Rat Cover case 50926: // Gluttonous Lurkers: Create Zul'Drak Rat Cover
case 51026: // Create Drakkari Medallion Cover case 51026: // Create Drakkari Medallion Cover
case 51592: // Pickup Primordial Hatchling case 51592: // Pickup Primordial Hatchling
@ -1187,6 +1188,7 @@ void Spell::EffectDummy(uint32 i)
switch(m_spellInfo->Id) switch(m_spellInfo->Id)
{ {
case 46167: spellId = 46773; break;
case 50926: spellId = 50927; break; case 50926: spellId = 50927; break;
case 51026: spellId = 50737; break; case 51026: spellId = 50737; break;
case 51592: spellId = 51593; break; case 51592: spellId = 51593; break;

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "9124" #define REVISION_NR "9129"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__

View file

@ -1,6 +1,6 @@
#ifndef __REVISION_SQL_H__ #ifndef __REVISION_SQL_H__
#define __REVISION_SQL_H__ #define __REVISION_SQL_H__
#define REVISION_DB_CHARACTERS "required_8874_01_characters_character_skills" #define REVISION_DB_CHARACTERS "required_8874_01_characters_character_skills"
#define REVISION_DB_MANGOS "required_9121_01_mangos_npc_spellclick_spells" #define REVISION_DB_MANGOS "required_9125_01_mangos_npc_spellclick_spells"
#define REVISION_DB_REALMD "required_9010_01_realmd_realmlist" #define REVISION_DB_REALMD "required_9010_01_realmd_realmlist"
#endif // __REVISION_SQL_H__ #endif // __REVISION_SQL_H__