Merge branch 'master' into Playerbot
# Conflicts: # src/server/apps/worldserver/worldserver.conf.dist # src/server/game/Battlegrounds/Battleground.h # src/server/game/Entities/Player/Player.cpp # src/server/game/World/World.cpp
This commit is contained in:
@@ -2423,14 +2423,16 @@ Rate.InstanceResetTime = 1
|
||||
# The lower the rate the less experience is required.
|
||||
# Default: 0.05
|
||||
#
|
||||
|
||||
Rate.Pet.LevelXP = 0.05
|
||||
|
||||
#
|
||||
# WaterBreath.Timer
|
||||
# Description: The timer for player's breath underwater in minutes
|
||||
# Default: 3
|
||||
# Description: The timer for player's breath underwater in milliseconds
|
||||
# Default: 180000 (3 minutes)
|
||||
#
|
||||
WaterBreath.Timer = 3
|
||||
|
||||
WaterBreath.Timer = 180000
|
||||
|
||||
#
|
||||
# SkillGain.Crafting
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "MapReference.h"
|
||||
#include "Player.h"
|
||||
#include "Vehicle.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "Language.h"
|
||||
|
||||
class PhasedRespawn : public BasicEvent
|
||||
@@ -226,6 +227,8 @@ void CreatureAI::EnterEvadeMode(EvadeReason why)
|
||||
me->DespawnOnEvade();
|
||||
me->m_Events.AddEvent(new PhasedRespawn(*me), me->m_Events.CalculateTime(20000));
|
||||
}
|
||||
|
||||
sScriptMgr->OnUnitEnterEvadeMode(me, why);
|
||||
}
|
||||
|
||||
/*void CreatureAI::AttackedBy(Unit* attacker)
|
||||
|
||||
@@ -5099,8 +5099,8 @@ void SmartScript::SetScript9(SmartScriptHolder& e, uint32 entry)
|
||||
return;
|
||||
}
|
||||
|
||||
// Do NOT allow to start a new actionlist if a previous one is already running. We need to always finish the current actionlist
|
||||
if (!mTimedActionList.empty())
|
||||
// Do NOT allow to start a new actionlist if a previous one is already running, unless explicitly allowed. We need to always finish the current actionlist
|
||||
if (!e.action.timedActionList.allowOverride && !mTimedActionList.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1774,9 +1774,13 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
||||
AC_SAI_IS_BOOLEAN_VALID(e, e.action.setHealthRegen.regenHealth);
|
||||
break;
|
||||
}
|
||||
case SMART_ACTION_CALL_TIMED_ACTIONLIST:
|
||||
{
|
||||
AC_SAI_IS_BOOLEAN_VALID(e, e.action.timedActionList.allowOverride);
|
||||
break;
|
||||
}
|
||||
case SMART_ACTION_FLEE_FOR_ASSIST:
|
||||
case SMART_ACTION_MOVE_TO_POS:
|
||||
case SMART_ACTION_CALL_TIMED_ACTIONLIST:
|
||||
case SMART_ACTION_EVADE:
|
||||
case SMART_ACTION_SET_ACTIVE:
|
||||
case SMART_ACTION_START_CLOSEST_WAYPOINT:
|
||||
|
||||
@@ -1081,6 +1081,7 @@ struct SmartAction
|
||||
{
|
||||
uint32 id;
|
||||
uint32 timerType;
|
||||
SAIBool allowOverride;
|
||||
} timedActionList;
|
||||
|
||||
struct
|
||||
|
||||
@@ -80,6 +80,8 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM:
|
||||
break;
|
||||
default:
|
||||
if (dataType != ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT)
|
||||
@@ -242,6 +244,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_TEAMS_SCORES:
|
||||
return true; // not check correctness node indexes
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM:
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_ITEM_QUALITY:
|
||||
if (equipped_item.item_quality >= MAX_ITEM_QUALITY)
|
||||
{
|
||||
LOG_ERROR("sql.sql", "Table `achievement_criteria_requirement` (Entry: {} Type: {}) for requirement ACHIEVEMENT_CRITERIA_REQUIRE_S_EQUIPED_ITEM ({}) has unknown quality state in value1 ({}), ignored.",
|
||||
@@ -434,6 +437,13 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un
|
||||
|
||||
return false;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_ITEM_QUALITY:
|
||||
{
|
||||
ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(miscvalue1);
|
||||
if (!pProto)
|
||||
return false;
|
||||
return pProto->Quality == item.item_quality;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_TEAMS_SCORES:
|
||||
{
|
||||
Battleground* bg = source->GetBattleground();
|
||||
@@ -1534,6 +1544,9 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
||||
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(miscValue1);
|
||||
if (!proto || proto->Quality < ITEM_QUALITY_EPIC)
|
||||
continue;
|
||||
AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);
|
||||
if (!data || !data->Meets(GetPlayer(), unit, miscValue1))
|
||||
continue;
|
||||
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
|
||||
break;
|
||||
}
|
||||
@@ -2321,16 +2334,17 @@ void AchievementMgr::BuildAllDataPacket(WorldPacket* data) const
|
||||
}
|
||||
|
||||
*data << int32(-1);
|
||||
time_t now = GameTime::GetGameTime().count();
|
||||
|
||||
for (CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter != m_criteriaProgress.end(); ++iter)
|
||||
{
|
||||
*data << uint32(iter->first);
|
||||
data->appendPackGUID(iter->second.counter);
|
||||
*data << GetPlayer()->GetPackGUID();
|
||||
*data << uint32(0);
|
||||
*data << uint32(0); // TODO: This should be 1 if it is a failed timed criteria
|
||||
data->AppendPackedTime(iter->second.date);
|
||||
*data << uint32(0);
|
||||
*data << uint32(0);
|
||||
*data << uint32(now - iter->second.date);
|
||||
*data << uint32(now - iter->second.date);
|
||||
}
|
||||
|
||||
*data << int32(-1);
|
||||
|
||||
@@ -43,38 +43,39 @@ struct CriteriaProgress
|
||||
enum AchievementCriteriaDataType
|
||||
{
|
||||
// value1 value2 comment
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE = 0, // 0 0
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE = 1, // creature_id 0
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE = 2, // class_id race_id
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE = 0, // 0 0
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE = 1, // creature_id 0
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE = 2, // class_id race_id
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH = 3, // health_percent 0
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD = 4, // own_team 0 not corpse (not released body), own_team == false if enemy team expected
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA = 5, // spell_id effect_idx
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA = 6, // area id 0
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA = 7, // spell_id effect_idx
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE = 8, // minvalue value provided with achievement update must be not less that limit
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL = 9, // minlevel minlevel of target
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_GENDER = 10, // gender 0=male; 1=female
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT = 11, // scripted requirement
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY = 12, // difficulty normal/heroic difficulty for current event map
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT = 13, // count "with less than %u people in the zone"
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM = 14, // team HORDE(67), ALLIANCE(469)
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_DRUNK = 15, // drunken_state 0 (enum DrunkenState) of player
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY = 16, // holiday_id 0 event in holiday time
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE = 17, // min_score max_score player's team win bg and opposition team have team score in range
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT = 18, // 0 0 maker instance script call for check current criteria requirements fit
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM = 19, // item_level item_quality for equipped item in slot to check item level and quality
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID = 20, // map_id 0 player must be on map with id in map_id
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE = 21, // class_id race_id
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_NTH_BIRTHDAY = 22, // N login on day of N-th Birthday
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_KNOWN_TITLE = 23, // title_id known (pvp) title, values from dbc
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_TEAMS_SCORES = 24, // winner_score loser score player's team win bg and their teams have exact scores
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD = 4, // own_team 0 not corpse (not released body), own_team == false if enemy team expected
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA = 5, // spell_id effect_idx
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA = 6, // area id 0
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA = 7, // spell_id effect_idx
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE = 8, // minvalue value provided with achievement update must be not less that limit
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL = 9, // minlevel minlevel of target
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_GENDER = 10, // gender 0=male; 1=female
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT = 11, // scripted requirement
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY = 12, // difficulty normal/heroic difficulty for current event map
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT = 13, // count "with less than %u people in the zone"
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM = 14, // team HORDE(67), ALLIANCE(469)
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_DRUNK = 15, // drunken_state 0 (enum DrunkenState) of player
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY = 16, // holiday_id 0 event in holiday time
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE = 17, // min_score max_score player's team win bg and opposition team have team score in range
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT = 18, // 0 0 maker instance script call for check current criteria requirements fit
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM = 19, // item_level item_quality for equipped item in slot to check item level and quality
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID = 20, // map_id 0 player must be on map with id in map_id
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE = 21, // class_id race_id
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_NTH_BIRTHDAY = 22, // N login on day of N-th Birthday
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_KNOWN_TITLE = 23, // title_id known (pvp) title, values from dbc
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_TEAMS_SCORES = 24, // winner_score loser score player's team win bg and their teams have exact scores
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_ITEM_QUALITY = 25 // item_quality
|
||||
};
|
||||
#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 25 // maximum value in AchievementCriteriaDataType enum
|
||||
#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 26 // maximum value in AchievementCriteriaDataType enum
|
||||
|
||||
enum AchievementCommonCategories
|
||||
{
|
||||
ACHIEVEMENT_CATEOGRY_GENERAL = -1,
|
||||
ACHIEVEMENT_CATEGORY_STATISTICS = 1
|
||||
ACHIEVEMENT_CATEOGRY_GENERAL = -1,
|
||||
ACHIEVEMENT_CATEGORY_STATISTICS = 1
|
||||
};
|
||||
|
||||
class Player;
|
||||
@@ -85,117 +86,122 @@ struct AchievementCriteriaData
|
||||
AchievementCriteriaDataType dataType{ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE};
|
||||
union
|
||||
{
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE = 0 (no data)
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE = 1
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE = 0 (no data)
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE = 1
|
||||
struct
|
||||
{
|
||||
uint32 id;
|
||||
} creature;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE = 2
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE = 21
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE = 2
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE = 21
|
||||
struct
|
||||
{
|
||||
uint32 class_id;
|
||||
uint32 race_id;
|
||||
} classRace;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH = 3
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH = 3
|
||||
struct
|
||||
{
|
||||
uint32 percent;
|
||||
} health;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD = 4
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD = 4
|
||||
struct
|
||||
{
|
||||
uint32 own_team_flag;
|
||||
} player_dead;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA = 5
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA = 7
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA = 5
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA = 7
|
||||
struct
|
||||
{
|
||||
uint32 spell_id;
|
||||
uint32 effect_idx;
|
||||
} aura;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA = 6
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA = 6
|
||||
struct
|
||||
{
|
||||
uint32 id;
|
||||
} area;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE = 8
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE = 8
|
||||
struct
|
||||
{
|
||||
uint32 value;
|
||||
uint32 compType;
|
||||
} value;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL = 9
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL = 9
|
||||
struct
|
||||
{
|
||||
uint32 minlevel;
|
||||
} level;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_GENDER = 10
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_GENDER = 10
|
||||
struct
|
||||
{
|
||||
uint32 gender;
|
||||
} gender;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT = 11 (no data)
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY = 12
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT = 11 (no data)
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY = 12
|
||||
struct
|
||||
{
|
||||
uint32 difficulty;
|
||||
} difficulty;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT = 13
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT = 13
|
||||
struct
|
||||
{
|
||||
uint32 maxcount;
|
||||
} map_players;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM = 14
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM = 14
|
||||
struct
|
||||
{
|
||||
uint32 team;
|
||||
} team;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_DRUNK = 15
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_DRUNK = 15
|
||||
struct
|
||||
{
|
||||
uint32 state;
|
||||
} drunk;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY = 16
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY = 16
|
||||
struct
|
||||
{
|
||||
uint32 id;
|
||||
} holiday;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE= 17
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE = 17
|
||||
struct
|
||||
{
|
||||
uint32 min_score;
|
||||
uint32 max_score;
|
||||
} bg_loss_team_score;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT = 18 (no data)
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM = 19
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT = 18 (no data)
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM = 19
|
||||
struct
|
||||
{
|
||||
uint32 item_level;
|
||||
uint32 item_quality;
|
||||
} equipped_item;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID = 20
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID = 20
|
||||
struct
|
||||
{
|
||||
uint32 mapId;
|
||||
} map_id;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_NTH_BIRTHDAY = 22
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_NTH_BIRTHDAY = 22
|
||||
struct
|
||||
{
|
||||
uint32 nth_birthday;
|
||||
} birthday_login;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_KNOWN_TITLE = 23
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_KNOWN_TITLE = 23
|
||||
struct
|
||||
{
|
||||
uint32 title_id;
|
||||
} known_title;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_TEAMS_SCORES = 24
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_TEAMS_SCORES = 24
|
||||
struct
|
||||
{
|
||||
uint32 winner_score;
|
||||
uint32 loser_score;
|
||||
} teams_scores;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_ITEM_QUALITY = 25
|
||||
struct
|
||||
{
|
||||
uint32 item_quality;
|
||||
} item;
|
||||
// ...
|
||||
struct
|
||||
{
|
||||
|
||||
@@ -56,23 +56,23 @@ enum BattlegroundDesertionType
|
||||
|
||||
enum BattlegroundMaps
|
||||
{
|
||||
MAP_BG_ALTERAC_VALLEY = 30,
|
||||
MAP_BG_WARSONG_GULCH = 489,
|
||||
MAP_BG_ARATHI_BASIN = 529,
|
||||
MAP_BG_EYE_OF_THE_STORM = 566,
|
||||
MAP_BG_STRAND_OF_THE_ANCIENTS = 607,
|
||||
MAP_BG_ISLE_OF_CONQUEST = 628
|
||||
MAP_BG_ALTERAC_VALLEY = 30,
|
||||
MAP_BG_WARSONG_GULCH = 489,
|
||||
MAP_BG_ARATHI_BASIN = 529,
|
||||
MAP_BG_EYE_OF_THE_STORM = 566,
|
||||
MAP_BG_STRAND_OF_THE_ANCIENTS = 607,
|
||||
MAP_BG_ISLE_OF_CONQUEST = 628
|
||||
};
|
||||
|
||||
enum BattlegroundBroadcastTexts
|
||||
{
|
||||
BG_TEXT_ALLIANCE_WINS = 10633,
|
||||
BG_TEXT_HORDE_WINS = 10634,
|
||||
BG_TEXT_ALLIANCE_WINS = 10633,
|
||||
BG_TEXT_HORDE_WINS = 10634,
|
||||
|
||||
BG_TEXT_START_TWO_MINUTES = 18193,
|
||||
BG_TEXT_START_ONE_MINUTE = 18194,
|
||||
BG_TEXT_START_HALF_MINUTE = 18195,
|
||||
BG_TEXT_BATTLE_HAS_BEGUN = 18196,
|
||||
BG_TEXT_START_TWO_MINUTES = 18193,
|
||||
BG_TEXT_START_ONE_MINUTE = 18194,
|
||||
BG_TEXT_START_HALF_MINUTE = 18195,
|
||||
BG_TEXT_BATTLE_HAS_BEGUN = 18196,
|
||||
};
|
||||
|
||||
enum BattlegroundSounds
|
||||
@@ -122,8 +122,8 @@ enum BattlegroundMarksCount
|
||||
|
||||
enum BattlegroundCreatures
|
||||
{
|
||||
BG_CREATURE_ENTRY_A_SPIRITGUIDE = 13116, // alliance
|
||||
BG_CREATURE_ENTRY_H_SPIRITGUIDE = 13117, // horde
|
||||
BG_CREATURE_ENTRY_A_SPIRITGUIDE = 13116, // alliance
|
||||
BG_CREATURE_ENTRY_H_SPIRITGUIDE = 13117, // horde
|
||||
};
|
||||
|
||||
enum BattlegroundSpells
|
||||
@@ -143,18 +143,18 @@ enum BattlegroundSpells
|
||||
|
||||
enum BattlegroundReputations
|
||||
{
|
||||
BG_REP_AV_HORDE = 729,
|
||||
BG_REP_AV_ALLIANCE = 730,
|
||||
BG_REP_AB_HORDE = 510,
|
||||
BG_REP_AB_ALLIANCE = 509,
|
||||
BG_REP_WS_HORDE = 889,
|
||||
BG_REP_WS_ALLIANCE = 890,
|
||||
BG_REP_AV_HORDE = 729,
|
||||
BG_REP_AV_ALLIANCE = 730,
|
||||
BG_REP_AB_HORDE = 510,
|
||||
BG_REP_AB_ALLIANCE = 509,
|
||||
BG_REP_WS_HORDE = 889,
|
||||
BG_REP_WS_ALLIANCE = 890,
|
||||
};
|
||||
|
||||
enum BattlegroundTimeIntervals
|
||||
{
|
||||
CHECK_PLAYER_POSITION_INVERVAL = 9000, // ms
|
||||
//REMIND_INTERVAL = 10000, // ms
|
||||
//REMIND_INTERVAL = 10000, // ms
|
||||
INVITATION_REMIND_TIME = 20000, // ms
|
||||
INVITE_ACCEPT_WAIT_TIME = 60000, // ms
|
||||
TIME_TO_AUTOREMOVE = 120000, // ms
|
||||
@@ -190,11 +190,11 @@ const uint32 Buff_Entries[3] = { BG_OBJECTID_SPEEDBUFF_ENTRY, BG_OBJECTID_REGENB
|
||||
|
||||
enum BattlegroundStatus
|
||||
{
|
||||
STATUS_NONE = 0, // first status, should mean bg is not instance
|
||||
STATUS_WAIT_QUEUE = 1, // means bg is empty and waiting for queue
|
||||
STATUS_WAIT_JOIN = 2, // this means, that BG has already started and it is waiting for more players
|
||||
STATUS_IN_PROGRESS = 3, // means bg is running
|
||||
STATUS_WAIT_LEAVE = 4 // means some faction has won BG and it is ending
|
||||
STATUS_NONE = 0, // first status, should mean bg is not instance
|
||||
STATUS_WAIT_QUEUE = 1, // means bg is empty and waiting for queue
|
||||
STATUS_WAIT_JOIN = 2, // this means, that BG has already started and it is waiting for more players
|
||||
STATUS_IN_PROGRESS = 3, // means bg is running
|
||||
STATUS_WAIT_LEAVE = 4 // means some faction has won BG and it is ending
|
||||
};
|
||||
|
||||
struct BattlegroundObjectInfo
|
||||
@@ -208,33 +208,33 @@ struct BattlegroundObjectInfo
|
||||
|
||||
enum ArenaType : uint8
|
||||
{
|
||||
ARENA_TYPE_NONE = 0,
|
||||
ARENA_TYPE_2v2 = 2,
|
||||
ARENA_TYPE_3v3 = 3,
|
||||
ARENA_TYPE_5v5 = 5
|
||||
ARENA_TYPE_NONE = 0,
|
||||
ARENA_TYPE_2v2 = 2,
|
||||
ARENA_TYPE_3v3 = 3,
|
||||
ARENA_TYPE_5v5 = 5
|
||||
};
|
||||
|
||||
enum BattlegroundType
|
||||
{
|
||||
TYPE_BATTLEGROUND = 3,
|
||||
TYPE_ARENA = 4
|
||||
TYPE_BATTLEGROUND = 3,
|
||||
TYPE_ARENA = 4
|
||||
};
|
||||
|
||||
enum BattlegroundStartingEvents
|
||||
{
|
||||
BG_STARTING_EVENT_NONE = 0x00,
|
||||
BG_STARTING_EVENT_1 = 0x01,
|
||||
BG_STARTING_EVENT_2 = 0x02,
|
||||
BG_STARTING_EVENT_3 = 0x04,
|
||||
BG_STARTING_EVENT_4 = 0x08
|
||||
BG_STARTING_EVENT_NONE = 0x00,
|
||||
BG_STARTING_EVENT_1 = 0x01,
|
||||
BG_STARTING_EVENT_2 = 0x02,
|
||||
BG_STARTING_EVENT_3 = 0x04,
|
||||
BG_STARTING_EVENT_4 = 0x08
|
||||
};
|
||||
|
||||
enum BattlegroundStartingEventsIds
|
||||
{
|
||||
BG_STARTING_EVENT_FIRST = 0,
|
||||
BG_STARTING_EVENT_SECOND = 1,
|
||||
BG_STARTING_EVENT_THIRD = 2,
|
||||
BG_STARTING_EVENT_FOURTH = 3
|
||||
BG_STARTING_EVENT_FIRST = 0,
|
||||
BG_STARTING_EVENT_SECOND = 1,
|
||||
BG_STARTING_EVENT_THIRD = 2,
|
||||
BG_STARTING_EVENT_FOURTH = 3
|
||||
};
|
||||
|
||||
constexpr auto BG_STARTING_EVENT_COUNT = 4;
|
||||
|
||||
@@ -31,63 +31,63 @@ struct Condition;
|
||||
|
||||
enum ConditionTypes
|
||||
{
|
||||
// value1 value2 value3
|
||||
CONDITION_NONE = 0, // 0 0 0 always true
|
||||
CONDITION_AURA = 1, // spell_id effindex use target? true if player (or target, if value3) has aura of spell_id with effect effindex
|
||||
CONDITION_ITEM = 2, // item_id count bank true if has #count of item_ids (if 'bank' is set it searches in bank slots too)
|
||||
CONDITION_ITEM_EQUIPPED = 3, // item_id 0 0 true if has item_id equipped
|
||||
CONDITION_ZONEID = 4, // zone_id 0 0 true if in zone_id
|
||||
CONDITION_REPUTATION_RANK = 5, // faction_id rankMask 0 true if has min_rank for faction_id
|
||||
CONDITION_TEAM = 6, // player_team 0, 0 469 - Alliance, 67 - Horde)
|
||||
CONDITION_SKILL = 7, // skill_id skill_value 0 true if has skill_value for skill_id
|
||||
CONDITION_QUESTREWARDED = 8, // quest_id 0 0 true if quest_id was rewarded before
|
||||
CONDITION_QUESTTAKEN = 9, // quest_id 0, 0 true while quest active
|
||||
CONDITION_DRUNKENSTATE = 10, // DrunkenState 0, 0 true if player is drunk enough
|
||||
CONDITION_WORLD_STATE = 11, // index value 0 true if world has the value for the index
|
||||
CONDITION_ACTIVE_EVENT = 12, // event_id 0 0 true if event is active
|
||||
CONDITION_INSTANCE_INFO = 13, // entry data type true if the instance info defined by type (enum InstanceInfo) equals data.
|
||||
CONDITION_QUEST_NONE = 14, // quest_id 0 0 true if doesn't have quest saved
|
||||
CONDITION_CLASS = 15, // class 0 0 true if player's class is equal to class
|
||||
CONDITION_RACE = 16, // race 0 0 true if player's race is equal to race
|
||||
CONDITION_ACHIEVEMENT = 17, // achievement_id 0 0 true if achievement is complete
|
||||
CONDITION_TITLE = 18, // title id 0 0 true if player has title
|
||||
CONDITION_SPAWNMASK = 19, // spawnMask 0 0 true if in spawnMask
|
||||
CONDITION_GENDER = 20, // gender 0 0 true if player's gender is equal to gender
|
||||
CONDITION_UNIT_STATE = 21, // unitState 0 0 true if unit has unitState
|
||||
CONDITION_MAPID = 22, // map_id 0 0 true if in map_id
|
||||
CONDITION_AREAID = 23, // area_id 0 0 true if in area_id
|
||||
CONDITION_CREATURE_TYPE = 24, // cinfo.type 0 0 true if creature_template.type = value1
|
||||
CONDITION_SPELL = 25, // spell_id 0 0 true if player has learned spell
|
||||
CONDITION_PHASEMASK = 26, // phasemask 0 0 true if object is in phasemask
|
||||
CONDITION_LEVEL = 27, // level ComparisonType 0 true if unit's level is equal to param1 (param2 can modify the statement)
|
||||
CONDITION_QUEST_COMPLETE = 28, // quest_id 0 0 true if player has quest_id with all objectives complete, but not yet rewarded
|
||||
CONDITION_NEAR_CREATURE = 29, // creature entry distance dead true if there is a creature of entry in range
|
||||
CONDITION_NEAR_GAMEOBJECT = 30, // gameobject entry distance 0 true if there is a gameobject of entry in range
|
||||
CONDITION_OBJECT_ENTRY_GUID = 31, // TypeID entry guid/Attackable true if object is type TypeID and the entry is 0 or matches entry of the object or matches guid of the object
|
||||
CONDITION_TYPE_MASK = 32, // TypeMask 0 0 true if object is type object's TypeMask matches provided TypeMask
|
||||
CONDITION_RELATION_TO = 33, // ConditionTarget RelationType 0 true if object is in given relation with object specified by ConditionTarget
|
||||
CONDITION_REACTION_TO = 34, // ConditionTarget rankMask 0 true if object's reaction matches rankMask object specified by ConditionTarget
|
||||
CONDITION_DISTANCE_TO = 35, // ConditionTarget distance ComparisonType true if object and ConditionTarget are within distance given by parameters
|
||||
CONDITION_ALIVE = 36, // 0 0 0 true if unit is alive
|
||||
CONDITION_HP_VAL = 37, // hpVal ComparisonType 0 true if unit's hp matches given value
|
||||
CONDITION_HP_PCT = 38, // hpPct ComparisonType 0 true if unit's hp matches given pct
|
||||
CONDITION_REALM_ACHIEVEMENT = 39, // achievement_id 0 0 true if realm achievement is complete
|
||||
CONDITION_IN_WATER = 40, // 0 0 0 true if unit in water
|
||||
CONDITION_TERRAIN_SWAP = 41, // don't use on 3.3.5a
|
||||
CONDITION_STAND_STATE = 42, // stateType state 0 true if unit matches specified sitstate (0,x: has exactly state x; 1,0: any standing state; 1,1: any sitting state;)
|
||||
CONDITION_DAILY_QUEST_DONE = 43, // quest id 0 0 true if daily quest has been completed for the day
|
||||
CONDITION_CHARMED = 44, // 0 0 0 true if unit is currently charmed
|
||||
CONDITION_PET_TYPE = 45, // mask 0 0 true if player has a pet of given type(s)
|
||||
CONDITION_TAXI = 46, // 0 0 0 true if player is on taxi
|
||||
CONDITION_QUESTSTATE = 47, // quest_id state_mask 0 true if player is in any of the provided quest states for the quest (1 = not taken, 2 = completed, 8 = in progress, 32 = failed, 64 = rewarded)
|
||||
CONDITION_QUEST_OBJECTIVE_PROGRESS = 48, // quest_id objectiveIndex objectiveCount true if player has reached the specified objectiveCount quest progress for the objectiveIndex for the specified quest
|
||||
CONDITION_DIFFICULTY_ID = 49, // Difficulty 0 0 true is map has difficulty id
|
||||
CONDITION_TC_END = 50, // placeholder
|
||||
// value1 value2 value3
|
||||
CONDITION_NONE = 0, // 0 0 0 always true
|
||||
CONDITION_AURA = 1, // spell_id effindex use target? true if player (or target, if value3) has aura of spell_id with effect effindex
|
||||
CONDITION_ITEM = 2, // item_id count bank true if has #count of item_ids (if 'bank' is set it searches in bank slots too)
|
||||
CONDITION_ITEM_EQUIPPED = 3, // item_id 0 0 true if has item_id equipped
|
||||
CONDITION_ZONEID = 4, // zone_id 0 0 true if in zone_id
|
||||
CONDITION_REPUTATION_RANK = 5, // faction_id rankMask 0 true if has min_rank for faction_id
|
||||
CONDITION_TEAM = 6, // player_team 0, 0 469 - Alliance, 67 - Horde)
|
||||
CONDITION_SKILL = 7, // skill_id skill_value 0 true if has skill_value for skill_id
|
||||
CONDITION_QUESTREWARDED = 8, // quest_id 0 0 true if quest_id was rewarded before
|
||||
CONDITION_QUESTTAKEN = 9, // quest_id 0, 0 true while quest active
|
||||
CONDITION_DRUNKENSTATE = 10, // DrunkenState 0, 0 true if player is drunk enough
|
||||
CONDITION_WORLD_STATE = 11, // index value 0 true if world has the value for the index
|
||||
CONDITION_ACTIVE_EVENT = 12, // event_id 0 0 true if event is active
|
||||
CONDITION_INSTANCE_INFO = 13, // entry data type true if the instance info defined by type (enum InstanceInfo) equals data.
|
||||
CONDITION_QUEST_NONE = 14, // quest_id 0 0 true if doesn't have quest saved
|
||||
CONDITION_CLASS = 15, // class 0 0 true if player's class is equal to class
|
||||
CONDITION_RACE = 16, // race 0 0 true if player's race is equal to race
|
||||
CONDITION_ACHIEVEMENT = 17, // achievement_id 0 0 true if achievement is complete
|
||||
CONDITION_TITLE = 18, // title id 0 0 true if player has title
|
||||
CONDITION_SPAWNMASK = 19, // spawnMask 0 0 true if in spawnMask
|
||||
CONDITION_GENDER = 20, // gender 0 0 true if player's gender is equal to gender
|
||||
CONDITION_UNIT_STATE = 21, // unitState 0 0 true if unit has unitState
|
||||
CONDITION_MAPID = 22, // map_id 0 0 true if in map_id
|
||||
CONDITION_AREAID = 23, // area_id 0 0 true if in area_id
|
||||
CONDITION_CREATURE_TYPE = 24, // cinfo.type 0 0 true if creature_template.type = value1
|
||||
CONDITION_SPELL = 25, // spell_id 0 0 true if player has learned spell
|
||||
CONDITION_PHASEMASK = 26, // phasemask 0 0 true if object is in phasemask
|
||||
CONDITION_LEVEL = 27, // level ComparisonType 0 true if unit's level is equal to param1 (param2 can modify the statement)
|
||||
CONDITION_QUEST_COMPLETE = 28, // quest_id 0 0 true if player has quest_id with all objectives complete, but not yet rewarded
|
||||
CONDITION_NEAR_CREATURE = 29, // creature entry distance dead true if there is a creature of entry in range
|
||||
CONDITION_NEAR_GAMEOBJECT = 30, // gameobject entry distance 0 true if there is a gameobject of entry in range
|
||||
CONDITION_OBJECT_ENTRY_GUID = 31, // TypeID entry guid/Attackable true if object is type TypeID and the entry is 0 or matches entry of the object or matches guid of the object
|
||||
CONDITION_TYPE_MASK = 32, // TypeMask 0 0 true if object is type object's TypeMask matches provided TypeMask
|
||||
CONDITION_RELATION_TO = 33, // ConditionTarget RelationType 0 true if object is in given relation with object specified by ConditionTarget
|
||||
CONDITION_REACTION_TO = 34, // ConditionTarget rankMask 0 true if object's reaction matches rankMask object specified by ConditionTarget
|
||||
CONDITION_DISTANCE_TO = 35, // ConditionTarget distance ComparisonType true if object and ConditionTarget are within distance given by parameters
|
||||
CONDITION_ALIVE = 36, // 0 0 0 true if unit is alive
|
||||
CONDITION_HP_VAL = 37, // hpVal ComparisonType 0 true if unit's hp matches given value
|
||||
CONDITION_HP_PCT = 38, // hpPct ComparisonType 0 true if unit's hp matches given pct
|
||||
CONDITION_REALM_ACHIEVEMENT = 39, // achievement_id 0 0 true if realm achievement is complete
|
||||
CONDITION_IN_WATER = 40, // 0 0 0 true if unit in water
|
||||
CONDITION_TERRAIN_SWAP = 41, // don't use on 3.3.5a
|
||||
CONDITION_STAND_STATE = 42, // stateType state 0 true if unit matches specified sitstate (0,x: has exactly state x; 1,0: any standing state; 1,1: any sitting state;)
|
||||
CONDITION_DAILY_QUEST_DONE = 43, // quest id 0 0 true if daily quest has been completed for the day
|
||||
CONDITION_CHARMED = 44, // 0 0 0 true if unit is currently charmed
|
||||
CONDITION_PET_TYPE = 45, // mask 0 0 true if player has a pet of given type(s)
|
||||
CONDITION_TAXI = 46, // 0 0 0 true if player is on taxi
|
||||
CONDITION_QUESTSTATE = 47, // quest_id state_mask 0 true if player is in any of the provided quest states for the quest (1 = not taken, 2 = completed, 8 = in progress, 32 = failed, 64 = rewarded)
|
||||
CONDITION_QUEST_OBJECTIVE_PROGRESS = 48, // quest_id objectiveIndex objectiveCount true if player has reached the specified objectiveCount quest progress for the objectiveIndex for the specified quest
|
||||
CONDITION_DIFFICULTY_ID = 49, // Difficulty 0 0 true is map has difficulty id
|
||||
CONDITION_TC_END = 50, // placeholder
|
||||
|
||||
CONDITION_AC_START = 100,
|
||||
CONDITION_QUEST_SATISFY_EXCLUSIVE = 101, // quest_id 0 0 true if satisfied exclusive group
|
||||
CONDITION_HAS_AURA_TYPE = 102, // aura_type 0 0 true if has aura type
|
||||
CONDITION_AC_END = 103 // placeholder
|
||||
CONDITION_QUEST_SATISFY_EXCLUSIVE = 101, // quest_id 0 0 true if satisfied exclusive group
|
||||
CONDITION_HAS_AURA_TYPE = 102, // aura_type 0 0 true if has aura type
|
||||
CONDITION_AC_END = 103 // placeholder
|
||||
};
|
||||
|
||||
/*! Documentation on implementing a new ConditionSourceType:
|
||||
|
||||
@@ -73,7 +73,7 @@ struct M2Header
|
||||
uint32 ofsTransLookup; // Everything needs its lookup. Here are the transparencies.
|
||||
uint32 nUVAnimLookup;
|
||||
uint32 ofsUVAnimLookup;
|
||||
G3D::AABox BoundingBox; // min/max( [1].z, 2.0277779f ) - 0.16f seems to be the maximum camera height
|
||||
G3D::AABox BoundingBox; // min/max( [1].z, 2.0277779f ) - 0.16f seems to be the maximum camera height
|
||||
float BoundingSphereRadius;
|
||||
G3D::AABox CollisionBox;
|
||||
float CollisionSphereRadius;
|
||||
@@ -118,15 +118,15 @@ struct M2Track
|
||||
|
||||
struct M2Camera
|
||||
{
|
||||
uint32_t type; // 0: portrait, 1: characterinfo; -1: else (flyby etc.); referenced backwards in the lookup table.
|
||||
float fov; // No radians, no degrees. Multiply by 35 to get degrees.
|
||||
uint32_t type; // 0: portrait, 1: characterinfo; -1: else (flyby etc.); referenced backwards in the lookup table.
|
||||
float fov; // No radians, no degrees. Multiply by 35 to get degrees.
|
||||
float far_clip;
|
||||
float near_clip;
|
||||
M2Track positions; // How the camera's position moves. Should be 3*3 floats.
|
||||
M2Track positions; // How the camera's position moves. Should be 3*3 floats.
|
||||
G3D::Vector3 position_base;
|
||||
M2Track target_positions; // How the target moves. Should be 3*3 floats.
|
||||
M2Track target_positions; // How the target moves. Should be 3*3 floats.
|
||||
G3D::Vector3 target_position_base;
|
||||
M2Track rolldata; // The camera can have some roll-effect. Its 0 to 2*Pi.
|
||||
M2Track rolldata; // The camera can have some roll-effect. Its 0 to 2*Pi.
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
@@ -62,15 +62,15 @@ namespace lfg
|
||||
|
||||
private:
|
||||
// General
|
||||
LfgState m_State; ///< State if group in LFG
|
||||
LfgState m_OldState; ///< Old State
|
||||
ObjectGuid m_Leader; ///< Leader GUID
|
||||
LfgGuidSet m_Players; ///< Players in group
|
||||
LfgState m_State; ///< State if group in LFG
|
||||
LfgState m_OldState; ///< Old State
|
||||
ObjectGuid m_Leader; ///< Leader GUID
|
||||
LfgGuidSet m_Players; ///< Players in group
|
||||
// Dungeon
|
||||
uint32 m_Dungeon; ///< Dungeon entry
|
||||
uint32 m_Dungeon; ///< Dungeon entry
|
||||
bool _isLFGGroup;
|
||||
// Vote Kick
|
||||
uint8 m_KicksLeft; ///< Number of kicks left
|
||||
uint8 m_KicksLeft; ///< Number of kicks left
|
||||
};
|
||||
|
||||
} // namespace lfg
|
||||
|
||||
@@ -38,9 +38,9 @@ namespace lfg
|
||||
|
||||
enum LfgOptions
|
||||
{
|
||||
LFG_OPTION_ENABLE_DUNGEON_FINDER = 0x01,
|
||||
LFG_OPTION_ENABLE_RAID_BROWSER = 0x02,
|
||||
LFG_OPTION_ENABLE_SEASONAL_BOSSES = 0x04
|
||||
LFG_OPTION_ENABLE_DUNGEON_FINDER = 0x01,
|
||||
LFG_OPTION_ENABLE_RAID_BROWSER = 0x02,
|
||||
LFG_OPTION_ENABLE_SEASONAL_BOSSES = 0x04
|
||||
};
|
||||
|
||||
enum LFGMgrEnum
|
||||
@@ -330,7 +330,7 @@ namespace lfg
|
||||
Quest const* quest;
|
||||
};
|
||||
|
||||
/// Reward info
|
||||
// Reward info
|
||||
struct LfgReward
|
||||
{
|
||||
LfgReward(uint32 _maxLevel = 0, uint32 _firstQuest = 0, uint32 _otherQuest = 0):
|
||||
@@ -341,35 +341,35 @@ namespace lfg
|
||||
uint32 otherQuest;
|
||||
};
|
||||
|
||||
/// Stores player data related to proposal to join
|
||||
// Stores player data related to proposal to join
|
||||
struct LfgProposalPlayer
|
||||
{
|
||||
LfgProposalPlayer() = default;
|
||||
uint8 role{0}; ///< Proposed role
|
||||
LfgAnswer accept{LFG_ANSWER_PENDING}; ///< Accept status (-1 not answer | 0 Not agree | 1 agree)
|
||||
uint8 role{0}; ///< Proposed role
|
||||
LfgAnswer accept{LFG_ANSWER_PENDING}; ///< Accept status (-1 not answer | 0 Not agree | 1 agree)
|
||||
ObjectGuid group; ///< Original group guid. 0 if no original group
|
||||
};
|
||||
|
||||
/// Stores group data related to proposal to join
|
||||
// Stores group data related to proposal to join
|
||||
struct LfgProposal
|
||||
{
|
||||
LfgProposal(uint32 dungeon = 0): dungeonId(dungeon)
|
||||
{ }
|
||||
|
||||
uint32 id{0}; ///< Proposal Id
|
||||
uint32 id{0}; ///< Proposal Id
|
||||
uint32 dungeonId; ///< Dungeon to join
|
||||
LfgProposalState state{LFG_PROPOSAL_INITIATING}; ///< State of the proposal
|
||||
LfgProposalState state{LFG_PROPOSAL_INITIATING}; ///< State of the proposal
|
||||
ObjectGuid group; ///< Proposal group (0 if new)
|
||||
ObjectGuid leader; ///< Leader guid.
|
||||
time_t cancelTime{0}; ///< Time when we will cancel this proposal
|
||||
uint32 encounters{0}; ///< Dungeon Encounters
|
||||
bool isNew{true}; ///< Determines if it's new group or not
|
||||
time_t cancelTime{0}; ///< Time when we will cancel this proposal
|
||||
uint32 encounters{0}; ///< Dungeon Encounters
|
||||
bool isNew{true}; ///< Determines if it's new group or not
|
||||
Lfg5Guids queues; ///< Queue Ids to remove/readd
|
||||
LfgGuidList showorder; ///< Show order in update window
|
||||
LfgProposalPlayerContainer players; ///< Players data
|
||||
};
|
||||
|
||||
/// Stores all rolecheck info of a group that wants to join
|
||||
// Stores all rolecheck info of a group that wants to join
|
||||
struct LfgRoleCheck
|
||||
{
|
||||
time_t cancelTime; ///< Time when the rolecheck will fail
|
||||
@@ -380,7 +380,7 @@ namespace lfg
|
||||
ObjectGuid leader; ///< Leader of the group
|
||||
};
|
||||
|
||||
/// Stores information of a current vote to kick someone from a group
|
||||
// Stores information of a current vote to kick someone from a group
|
||||
struct LfgPlayerBoot
|
||||
{
|
||||
time_t cancelTime; ///< Time left to vote
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
namespace lfg
|
||||
{
|
||||
|
||||
enum LfgCompatibility
|
||||
{
|
||||
LFG_COMPATIBILITY_PENDING,
|
||||
@@ -38,7 +37,7 @@ namespace lfg
|
||||
LFG_COMPATIBLES_MATCH // Must be the last one
|
||||
};
|
||||
|
||||
/// Stores player or group queue info
|
||||
// Stores player or group queue info
|
||||
struct LfgQueueData
|
||||
{
|
||||
LfgQueueData();
|
||||
@@ -48,21 +47,21 @@ namespace lfg
|
||||
dps(LFG_DPS_NEEDED), dungeons(std::move(_dungeons)), roles(std::move(_roles))
|
||||
{ }
|
||||
|
||||
time_t joinTime; ///< Player queue join time (to calculate wait times)
|
||||
time_t lastRefreshTime; ///< pussywizard
|
||||
uint8 tanks{LFG_TANKS_NEEDED}; ///< Tanks needed
|
||||
uint8 healers{LFG_HEALERS_NEEDED}; ///< Healers needed
|
||||
uint8 dps{LFG_DPS_NEEDED}; ///< Dps needed
|
||||
LfgDungeonSet dungeons; ///< Selected Player/Group Dungeon/s
|
||||
LfgRolesMap roles; ///< Selected Player Role/s
|
||||
Lfg5Guids bestCompatible; ///< Best compatible combination of people queued
|
||||
time_t joinTime; // Player queue join time (to calculate wait times)
|
||||
time_t lastRefreshTime; // pussywizard
|
||||
uint8 tanks{LFG_TANKS_NEEDED}; // Tanks needed
|
||||
uint8 healers{LFG_HEALERS_NEEDED}; // Healers needed
|
||||
uint8 dps{LFG_DPS_NEEDED}; // Dps needed
|
||||
LfgDungeonSet dungeons; // Selected Player/Group Dungeon/s
|
||||
LfgRolesMap roles; // Selected Player Role/s
|
||||
Lfg5Guids bestCompatible; // Best compatible combination of people queued
|
||||
};
|
||||
|
||||
struct LfgWaitTime
|
||||
{
|
||||
LfgWaitTime() = default;
|
||||
int32 time{-1}; ///< Wait time
|
||||
uint32 number{0}; ///< Number of people used to get that wait time
|
||||
int32 time{-1}; // Wait time
|
||||
uint32 number{0}; // Number of people used to get that wait time
|
||||
};
|
||||
|
||||
typedef std::map<uint32, LfgWaitTime> LfgWaitTimesContainer;
|
||||
@@ -110,19 +109,18 @@ namespace lfg
|
||||
LfgCompatibility CheckCompatibility(Lfg5Guids const& checkWith, const ObjectGuid& newGuid, uint64& foundMask, uint32& foundCount, const std::set<Lfg5Guids>& currentCompatibles);
|
||||
|
||||
// Queue
|
||||
uint32 m_QueueStatusTimer; ///< used to check interval of sending queue status
|
||||
LfgQueueDataContainer QueueDataStore; ///< Queued groups
|
||||
LfgCompatibleContainer CompatibleList; ///< Compatible dungeons
|
||||
LfgCompatibleContainer CompatibleTempList; ///< new compatibles are added to this container while main one is being iterated
|
||||
uint32 m_QueueStatusTimer; // used to check interval of sending queue status
|
||||
LfgQueueDataContainer QueueDataStore; // Queued groups
|
||||
LfgCompatibleContainer CompatibleList; // Compatible dungeons
|
||||
LfgCompatibleContainer CompatibleTempList; // new compatibles are added to this container while main one is being iterated
|
||||
|
||||
LfgWaitTimesContainer waitTimesAvgStore; ///< Average wait time to find a group queuing as multiple roles
|
||||
LfgWaitTimesContainer waitTimesTankStore; ///< Average wait time to find a group queuing as tank
|
||||
LfgWaitTimesContainer waitTimesHealerStore; ///< Average wait time to find a group queuing as healer
|
||||
LfgWaitTimesContainer waitTimesDpsStore; ///< Average wait time to find a group queuing as dps
|
||||
LfgGuidList newToQueueStore; ///< New groups to add to queue
|
||||
LfgWaitTimesContainer waitTimesAvgStore; // Average wait time to find a group queuing as multiple roles
|
||||
LfgWaitTimesContainer waitTimesTankStore; // Average wait time to find a group queuing as tank
|
||||
LfgWaitTimesContainer waitTimesHealerStore; // Average wait time to find a group queuing as healer
|
||||
LfgWaitTimesContainer waitTimesDpsStore; // Average wait time to find a group queuing as dps
|
||||
LfgGuidList newToQueueStore; // New groups to add to queue
|
||||
LfgGuidList restoredAfterProposal;
|
||||
};
|
||||
|
||||
} // namespace lfg
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -284,6 +284,8 @@ void Creature::AddToWorld()
|
||||
GetZoneScript()->OnCreatureCreate(this);
|
||||
}
|
||||
|
||||
loot.sourceWorldObjectGUID = GetGUID();
|
||||
|
||||
sScriptMgr->OnCreatureAddWorld(this);
|
||||
}
|
||||
}
|
||||
@@ -3438,7 +3440,7 @@ bool Creature::IsMovementPreventedByCasting() const
|
||||
{
|
||||
Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL];
|
||||
// first check if currently a movement allowed channel is active and we're not casting
|
||||
if (spell && spell->getState() != SPELL_STATE_FINISHED && spell->IsChannelActive() && spell->GetSpellInfo()->IsMoveAllowedChannel())
|
||||
if (spell && spell->getState() != SPELL_STATE_FINISHED && spell->IsChannelActive() && spell->GetSpellInfo()->IsActionAllowedChannel())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -383,8 +383,6 @@ public:
|
||||
|
||||
void ModifyThreatPercentTemp(Unit* victim, int32 percent, Milliseconds duration);
|
||||
|
||||
void ResetFaction() { SetFaction(GetCreatureTemplate()->faction); }
|
||||
|
||||
protected:
|
||||
bool CreateFromProto(ObjectGuid::LowType guidlow, uint32 Entry, uint32 vehId, const CreatureData* data = nullptr);
|
||||
bool InitEntry(uint32 entry, const CreatureData* data = nullptr);
|
||||
|
||||
@@ -29,6 +29,7 @@ GossipMenu::GossipMenu()
|
||||
{
|
||||
_menuId = 0;
|
||||
_locale = DEFAULT_LOCALE;
|
||||
_senderGUID.Clear();
|
||||
}
|
||||
|
||||
GossipMenu::~GossipMenu()
|
||||
@@ -188,8 +189,10 @@ void PlayerMenu::ClearMenus()
|
||||
_questMenu.ClearMenu();
|
||||
}
|
||||
|
||||
void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID) const
|
||||
void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID)
|
||||
{
|
||||
_gossipMenu.SetSenderGUID(objectGUID);
|
||||
|
||||
WorldPacket data(SMSG_GOSSIP_MESSAGE, 24 + _gossipMenu.GetMenuItemCount() * 100 + _questMenu.GetMenuItemCount() * 75); // guess size
|
||||
data << objectGUID;
|
||||
data << uint32(_gossipMenu.GetMenuId()); // new 2.4.0
|
||||
@@ -234,8 +237,10 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID) const
|
||||
_session->SendPacket(&data);
|
||||
}
|
||||
|
||||
void PlayerMenu::SendCloseGossip() const
|
||||
void PlayerMenu::SendCloseGossip()
|
||||
{
|
||||
_gossipMenu.SetSenderGUID(ObjectGuid::Empty);
|
||||
|
||||
WorldPacket data(SMSG_GOSSIP_COMPLETE, 0);
|
||||
_session->SendPacket(&data);
|
||||
}
|
||||
|
||||
@@ -213,11 +213,15 @@ public:
|
||||
return _menuItems;
|
||||
}
|
||||
|
||||
void SetSenderGUID(ObjectGuid guid) { _senderGUID = guid; }
|
||||
[[nodiscard]] ObjectGuid GetSenderGUID() const { return _senderGUID; }
|
||||
|
||||
private:
|
||||
GossipMenuItemContainer _menuItems;
|
||||
GossipMenuItemDataContainer _menuItemData;
|
||||
uint32 _menuId;
|
||||
LocaleConstant _locale;
|
||||
ObjectGuid _senderGUID;
|
||||
};
|
||||
|
||||
class QuestMenu
|
||||
@@ -266,8 +270,8 @@ public:
|
||||
[[nodiscard]] uint32 GetGossipOptionAction(uint32 selection) const { return _gossipMenu.GetMenuItemAction(selection); }
|
||||
[[nodiscard]] bool IsGossipOptionCoded(uint32 selection) const { return _gossipMenu.IsMenuItemCoded(selection); }
|
||||
|
||||
void SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID) const;
|
||||
void SendCloseGossip() const;
|
||||
void SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID);
|
||||
void SendCloseGossip();
|
||||
void SendPointOfInterest(uint32 poiId) const;
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
@@ -159,6 +159,8 @@ void GameObject::AddToWorld()
|
||||
|
||||
WorldObject::AddToWorld();
|
||||
|
||||
loot.sourceWorldObjectGUID = GetGUID();
|
||||
|
||||
sScriptMgr->OnGameObjectAddWorld(this);
|
||||
}
|
||||
}
|
||||
@@ -2054,20 +2056,19 @@ void GameObject::CastSpell(Unit* target, uint32 spellId)
|
||||
if (!spellInfo)
|
||||
return;
|
||||
|
||||
bool self = false;
|
||||
bool self = true;
|
||||
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
{
|
||||
if (spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)
|
||||
if (spellInfo->Effects[i].TargetA.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER || spellInfo->Effects[i].TargetB.GetTarget())
|
||||
{
|
||||
self = true;
|
||||
self = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (self)
|
||||
if (self && target && target->GetGUID() != GetGUID())
|
||||
{
|
||||
if (target)
|
||||
target->CastSpell(target, spellInfo, true);
|
||||
target->CastSpell(target, spellInfo, true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,9 +60,9 @@ enum ItemModType
|
||||
ITEM_MOD_EXPERTISE_RATING = 37,
|
||||
ITEM_MOD_ATTACK_POWER = 38,
|
||||
ITEM_MOD_RANGED_ATTACK_POWER = 39,
|
||||
//ITEM_MOD_FERAL_ATTACK_POWER = 40, not in 3.3
|
||||
ITEM_MOD_SPELL_HEALING_DONE = 41, // deprecated
|
||||
ITEM_MOD_SPELL_DAMAGE_DONE = 42, // deprecated
|
||||
//ITEM_MOD_FERAL_ATTACK_POWER = 40, not in 3.3
|
||||
ITEM_MOD_SPELL_HEALING_DONE = 41, // deprecated
|
||||
ITEM_MOD_SPELL_DAMAGE_DONE = 42, // deprecated
|
||||
ITEM_MOD_MANA_REGENERATION = 43,
|
||||
ITEM_MOD_ARMOR_PENETRATION_RATING = 44,
|
||||
ITEM_MOD_SPELL_POWER = 45,
|
||||
@@ -75,7 +75,7 @@ enum ItemModType
|
||||
|
||||
enum ItemSpelltriggerType
|
||||
{
|
||||
ITEM_SPELLTRIGGER_ON_USE = 0, // use after equip cooldown
|
||||
ITEM_SPELLTRIGGER_ON_USE = 0, // use after equip cooldown
|
||||
ITEM_SPELLTRIGGER_ON_EQUIP = 1,
|
||||
ITEM_SPELLTRIGGER_CHANCE_ON_HIT = 2,
|
||||
ITEM_SPELLTRIGGER_SOULSTONE = 4,
|
||||
@@ -85,20 +85,20 @@ enum ItemSpelltriggerType
|
||||
* other hand the item is destroyed if the aura is removed ("removed on
|
||||
* death" of spell 57348 makes me think so)
|
||||
*/
|
||||
ITEM_SPELLTRIGGER_ON_NO_DELAY_USE = 5, // no equip cooldown
|
||||
ITEM_SPELLTRIGGER_LEARN_SPELL_ID = 6 // used in item_template.spell_2 with spell_id with SPELL_GENERIC_LEARN in spell_1
|
||||
ITEM_SPELLTRIGGER_ON_NO_DELAY_USE = 5, // no equip cooldown
|
||||
ITEM_SPELLTRIGGER_LEARN_SPELL_ID = 6 // used in item_template.spell_2 with spell_id with SPELL_GENERIC_LEARN in spell_1
|
||||
};
|
||||
|
||||
#define MAX_ITEM_SPELLTRIGGER 7
|
||||
|
||||
enum ItemBondingType
|
||||
{
|
||||
NO_BIND = 0,
|
||||
BIND_WHEN_PICKED_UP = 1,
|
||||
BIND_WHEN_EQUIPED = 2,
|
||||
BIND_WHEN_USE = 3,
|
||||
BIND_QUEST_ITEM = 4,
|
||||
BIND_QUEST_ITEM1 = 5 // not used in game
|
||||
NO_BIND = 0,
|
||||
BIND_WHEN_PICKED_UP = 1,
|
||||
BIND_WHEN_EQUIPED = 2,
|
||||
BIND_WHEN_USE = 3,
|
||||
BIND_QUEST_ITEM = 4,
|
||||
BIND_QUEST_ITEM1 = 5 // not used in game
|
||||
};
|
||||
|
||||
#define MAX_BIND_TYPE 6
|
||||
@@ -597,7 +597,7 @@ struct _ItemStat
|
||||
};
|
||||
struct _Spell
|
||||
{
|
||||
int32 SpellId; // id from Spell.dbc
|
||||
int32 SpellId; // id from Spell.dbc
|
||||
uint32 SpellTrigger;
|
||||
int32 SpellCharges;
|
||||
float SpellPPMRate;
|
||||
@@ -701,7 +701,7 @@ struct ItemTemplate
|
||||
uint32 MinMoneyLoot;
|
||||
uint32 MaxMoneyLoot;
|
||||
uint32 FlagsCu;
|
||||
WorldPacket queryData; // pussywizard
|
||||
WorldPacket queryData; // pussywizard
|
||||
|
||||
// helpers
|
||||
[[nodiscard]] bool HasSignature() const
|
||||
|
||||
@@ -1230,9 +1230,9 @@ bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool
|
||||
return distsq < maxdist * maxdist;
|
||||
}
|
||||
|
||||
Position WorldObject::GetHitSpherePointFor(Position const& dest) const
|
||||
Position WorldObject::GetHitSpherePointFor(Position const& dest, Optional<float> collisionHeight) const
|
||||
{
|
||||
G3D::Vector3 vThis(GetPositionX(), GetPositionY(), GetPositionZ() + GetCollisionHeight());
|
||||
G3D::Vector3 vThis(GetPositionX(), GetPositionY(), GetPositionZ() + (collisionHeight ? *collisionHeight : GetCollisionHeight()));
|
||||
G3D::Vector3 vObj(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ());
|
||||
G3D::Vector3 contactPoint = vThis + (vObj - vThis).directionOrZero() * std::min(dest.GetExactDist(this), GetCombatReach());
|
||||
|
||||
@@ -1341,7 +1341,7 @@ bool WorldObject::IsWithinLOS(float ox, float oy, float oz, VMAP::ModelIgnoreFla
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WorldObject::IsWithinLOSInMap(WorldObject const* obj, VMAP::ModelIgnoreFlags ignoreFlags, LineOfSightChecks checks) const
|
||||
bool WorldObject::IsWithinLOSInMap(WorldObject const* obj, VMAP::ModelIgnoreFlags ignoreFlags, LineOfSightChecks checks, Optional<float> collisionHeight /*= {}*/) const
|
||||
{
|
||||
if (!IsInMap(obj))
|
||||
return false;
|
||||
@@ -1353,7 +1353,7 @@ bool WorldObject::IsWithinLOSInMap(WorldObject const* obj, VMAP::ModelIgnoreFlag
|
||||
oz += obj->GetCollisionHeight();
|
||||
}
|
||||
else
|
||||
obj->GetHitSpherePointFor({ GetPositionX(), GetPositionY(), GetPositionZ() + GetCollisionHeight() }, ox, oy, oz);
|
||||
obj->GetHitSpherePointFor({ GetPositionX(), GetPositionY(), GetPositionZ() + (collisionHeight ? *collisionHeight : GetCollisionHeight()) }, ox, oy, oz);
|
||||
|
||||
float x, y, z;
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
@@ -1362,14 +1362,14 @@ bool WorldObject::IsWithinLOSInMap(WorldObject const* obj, VMAP::ModelIgnoreFlag
|
||||
z += GetCollisionHeight();
|
||||
}
|
||||
else
|
||||
GetHitSpherePointFor({ obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ() + obj->GetCollisionHeight() }, x, y, z);
|
||||
GetHitSpherePointFor({ obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ() + obj->GetCollisionHeight() }, x, y, z, collisionHeight);
|
||||
|
||||
return GetMap()->isInLineOfSight(x, y, z, ox, oy, oz, GetPhaseMask(), checks, ignoreFlags);
|
||||
}
|
||||
|
||||
void WorldObject::GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z) const
|
||||
void WorldObject::GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z, Optional<float> collisionHeight) const
|
||||
{
|
||||
Position pos = GetHitSpherePointFor(dest);
|
||||
Position pos = GetHitSpherePointFor(dest, collisionHeight);
|
||||
x = pos.GetPositionX();
|
||||
y = pos.GetPositionY();
|
||||
z = pos.GetPositionZ();
|
||||
|
||||
@@ -67,8 +67,8 @@ enum NotifyFlags
|
||||
|
||||
enum GOSummonType
|
||||
{
|
||||
GO_SUMMON_TIMED_OR_CORPSE_DESPAWN = 0, // despawns after a specified time OR when the summoner dies
|
||||
GO_SUMMON_TIMED_DESPAWN = 1 // despawns after a specified time
|
||||
GO_SUMMON_TIMED_OR_CORPSE_DESPAWN = 0, // despawns after a specified time OR when the summoner dies
|
||||
GO_SUMMON_TIMED_DESPAWN = 1 // despawns after a specified time
|
||||
};
|
||||
|
||||
class WorldPacket;
|
||||
@@ -463,9 +463,9 @@ public:
|
||||
bool IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D = true, bool useBoundingRadius = true) const;
|
||||
bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true, bool useBoundingRadius = true) const;
|
||||
[[nodiscard]] bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags = VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks = LINEOFSIGHT_ALL_CHECKS) const;
|
||||
[[nodiscard]] bool IsWithinLOSInMap(WorldObject const* obj, VMAP::ModelIgnoreFlags ignoreFlags = VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks = LINEOFSIGHT_ALL_CHECKS) const;
|
||||
[[nodiscard]] Position GetHitSpherePointFor(Position const& dest) const;
|
||||
void GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z) const;
|
||||
[[nodiscard]] bool IsWithinLOSInMap(WorldObject const* obj, VMAP::ModelIgnoreFlags ignoreFlags = VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks = LINEOFSIGHT_ALL_CHECKS, Optional<float> collisionHeight = { }) const;
|
||||
[[nodiscard]] Position GetHitSpherePointFor(Position const& dest, Optional<float> collisionHeight = { }) const;
|
||||
void GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z, Optional<float> collisionHeight = { }) const;
|
||||
bool GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2, bool is3D = true) const;
|
||||
bool IsInRange(WorldObject const* obj, float minRange, float maxRange, bool is3D = true) const;
|
||||
[[nodiscard]] bool IsInRange2d(float x, float y, float minRange, float maxRange) const;
|
||||
|
||||
@@ -23,31 +23,31 @@
|
||||
#define CONTACT_DISTANCE 0.5f
|
||||
#define INTERACTION_DISTANCE 5.5f
|
||||
#define ATTACK_DISTANCE 5.0f
|
||||
#define VISIBILITY_COMPENSATION 15.0f // increase searchers
|
||||
#define VISIBILITY_COMPENSATION 15.0f // increase searchers
|
||||
#define INSPECT_DISTANCE 28.0f
|
||||
#define VISIBILITY_INC_FOR_GOBJECTS 30.0f // pussywizard
|
||||
#define SPELL_SEARCHER_COMPENSATION 30.0f // increase searchers size in case we have large npc near cell border
|
||||
#define VISIBILITY_INC_FOR_GOBJECTS 30.0f // pussywizard
|
||||
#define SPELL_SEARCHER_COMPENSATION 30.0f // increase searchers size in case we have large npc near cell border
|
||||
#define TRADE_DISTANCE 11.11f
|
||||
#define MAX_VISIBILITY_DISTANCE 250.0f // max distance for visible objects, experimental
|
||||
#define MAX_VISIBILITY_DISTANCE 250.0f // max distance for visible objects, experimental
|
||||
#define SIGHT_RANGE_UNIT 50.0f
|
||||
#define MAX_SEARCHER_DISTANCE 150.0f // pussywizard: replace the use of MAX_VISIBILITY_DISTANCE in searchers, because MAX_VISIBILITY_DISTANCE is quite too big for this purpose
|
||||
#define MAX_SEARCHER_DISTANCE 150.0f // pussywizard: replace the use of MAX_VISIBILITY_DISTANCE in searchers, because MAX_VISIBILITY_DISTANCE is quite too big for this purpose
|
||||
#define VISIBILITY_DISTANCE_INFINITE 533.0f
|
||||
#define VISIBILITY_DISTANCE_GIGANTIC 400.0f
|
||||
#define VISIBILITY_DISTANCE_LARGE 200.0f
|
||||
#define VISIBILITY_DISTANCE_NORMAL 100.0f
|
||||
#define VISIBILITY_DISTANCE_SMALL 50.0f
|
||||
#define VISIBILITY_DISTANCE_TINY 25.0f
|
||||
#define DEFAULT_VISIBILITY_DISTANCE 100.0f // default visible distance, 100 yards on continents
|
||||
#define DEFAULT_VISIBILITY_INSTANCE 170.0f // default visible distance in instances, 170 yards
|
||||
#define DEFAULT_VISIBILITY_DISTANCE 100.0f // default visible distance, 100 yards on continents
|
||||
#define DEFAULT_VISIBILITY_INSTANCE 170.0f // default visible distance in instances, 170 yards
|
||||
#define VISIBILITY_DIST_WINTERGRASP 175.0f
|
||||
#define DEFAULT_VISIBILITY_BGARENAS 533.0f // default visible distance in BG/Arenas, roughly 533 yards
|
||||
#define DEFAULT_VISIBILITY_BGARENAS 533.0f // default visible distance in BG/Arenas, roughly 533 yards
|
||||
|
||||
#define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects
|
||||
#define DEFAULT_COMBAT_REACH 1.5f
|
||||
#define MIN_MELEE_REACH 2.0f
|
||||
#define NOMINAL_MELEE_RANGE 5.0f
|
||||
#define MELEE_RANGE (NOMINAL_MELEE_RANGE - MIN_MELEE_REACH * 2) //center to center for players
|
||||
#define DEFAULT_COLLISION_HEIGHT 2.03128f // Most common value in dbc
|
||||
#define DEFAULT_COLLISION_HEIGHT 2.03128f // Most common value in dbc
|
||||
|
||||
// used for creating values for respawn for example
|
||||
inline uint32 PAIR64_HIPART(uint64 x);
|
||||
|
||||
@@ -47,8 +47,8 @@ enum TypeMask
|
||||
{
|
||||
TYPEMASK_OBJECT = 0x0001,
|
||||
TYPEMASK_ITEM = 0x0002,
|
||||
TYPEMASK_CONTAINER = 0x0006, // TYPEMASK_ITEM | 0x0004
|
||||
TYPEMASK_UNIT = 0x0008, // creature
|
||||
TYPEMASK_CONTAINER = 0x0006, // TYPEMASK_ITEM | 0x0004
|
||||
TYPEMASK_UNIT = 0x0008, // creature
|
||||
TYPEMASK_PLAYER = 0x0010,
|
||||
TYPEMASK_GAMEOBJECT = 0x0020,
|
||||
TYPEMASK_DYNAMICOBJECT = 0x0040,
|
||||
|
||||
@@ -42,7 +42,7 @@ struct ObjectPosSelector
|
||||
float dist; // dist to central point (including central point size)
|
||||
};
|
||||
|
||||
typedef std::multimap<float, UsedPos> UsedPosList; // std::abs(angle)->Node
|
||||
typedef std::multimap<float, UsedPos> UsedPosList; // std::abs(angle)->Node
|
||||
|
||||
ObjectPosSelector(float x, float y, float size, float dist);
|
||||
|
||||
@@ -60,7 +60,7 @@ struct ObjectPosSelector
|
||||
float angle_step2 = GetAngle(nextUsedPos.second);
|
||||
|
||||
float next_angle = nextUsedPos.first;
|
||||
if (nextUsedPos.second.sign * sign < 0) // last node from diff. list (-pi+alpha)
|
||||
if (nextUsedPos.second.sign * sign < 0) // last node from diff. list (-pi+alpha)
|
||||
next_angle = 2 * M_PI - next_angle; // move to positive
|
||||
|
||||
return std::fabs(angle) + angle_step2 <= next_angle;
|
||||
|
||||
@@ -28,9 +28,9 @@ enum ReactStates : uint8;
|
||||
|
||||
enum PetType : uint8
|
||||
{
|
||||
SUMMON_PET = 0,
|
||||
HUNTER_PET = 1,
|
||||
MAX_PET_TYPE = 4
|
||||
SUMMON_PET = 0,
|
||||
HUNTER_PET = 1,
|
||||
MAX_PET_TYPE = 4
|
||||
};
|
||||
|
||||
constexpr auto MAX_PET_STABLES = 4;
|
||||
@@ -38,54 +38,54 @@ constexpr auto MAX_PET_STABLES = 4;
|
||||
// stored in character_pet.slot
|
||||
enum PetSaveMode : int8
|
||||
{
|
||||
PET_SAVE_AS_DELETED = -1, // not saved in fact
|
||||
PET_SAVE_AS_CURRENT = 0, // in current slot (with player)
|
||||
PET_SAVE_FIRST_STABLE_SLOT = 1,
|
||||
PET_SAVE_LAST_STABLE_SLOT = MAX_PET_STABLES, // last in DB stable slot index (including), all higher have same meaning as PET_SAVE_NOT_IN_SLOT
|
||||
PET_SAVE_NOT_IN_SLOT = 100 // for avoid conflict with stable size grow will use 100
|
||||
PET_SAVE_AS_DELETED = -1, // not saved in fact
|
||||
PET_SAVE_AS_CURRENT = 0, // in current slot (with player)
|
||||
PET_SAVE_FIRST_STABLE_SLOT = 1,
|
||||
PET_SAVE_LAST_STABLE_SLOT = MAX_PET_STABLES, // last in DB stable slot index (including), all higher have same meaning as PET_SAVE_NOT_IN_SLOT
|
||||
PET_SAVE_NOT_IN_SLOT = 100 // for avoid conflict with stable size grow will use 100
|
||||
};
|
||||
|
||||
enum HappinessState
|
||||
{
|
||||
UNHAPPY = 1,
|
||||
CONTENT = 2,
|
||||
HAPPY = 3
|
||||
UNHAPPY = 1,
|
||||
CONTENT = 2,
|
||||
HAPPY = 3
|
||||
};
|
||||
|
||||
enum PetSpellState
|
||||
{
|
||||
PETSPELL_UNCHANGED = 0,
|
||||
PETSPELL_CHANGED = 1,
|
||||
PETSPELL_NEW = 2,
|
||||
PETSPELL_REMOVED = 3
|
||||
PETSPELL_UNCHANGED = 0,
|
||||
PETSPELL_CHANGED = 1,
|
||||
PETSPELL_NEW = 2,
|
||||
PETSPELL_REMOVED = 3
|
||||
};
|
||||
|
||||
enum PetSpellType
|
||||
{
|
||||
PETSPELL_NORMAL = 0,
|
||||
PETSPELL_FAMILY = 1,
|
||||
PETSPELL_TALENT = 2
|
||||
PETSPELL_NORMAL = 0,
|
||||
PETSPELL_FAMILY = 1,
|
||||
PETSPELL_TALENT = 2
|
||||
};
|
||||
|
||||
enum ActionFeedback
|
||||
{
|
||||
FEEDBACK_NONE = 0,
|
||||
FEEDBACK_PET_DEAD = 1,
|
||||
FEEDBACK_NOTHING_TO_ATT = 2,
|
||||
FEEDBACK_CANT_ATT_TARGET = 3
|
||||
FEEDBACK_NONE = 0,
|
||||
FEEDBACK_PET_DEAD = 1,
|
||||
FEEDBACK_NOTHING_TO_ATT = 2,
|
||||
FEEDBACK_CANT_ATT_TARGET = 3
|
||||
};
|
||||
|
||||
enum PetTalk
|
||||
{
|
||||
PET_TALK_SPECIAL_SPELL = 0,
|
||||
PET_TALK_ATTACK = 1
|
||||
PET_TALK_SPECIAL_SPELL = 0,
|
||||
PET_TALK_ATTACK = 1
|
||||
};
|
||||
|
||||
enum PetLoadState
|
||||
{
|
||||
PET_LOAD_OK = 0,
|
||||
PET_LOAD_NO_RESULT = 1,
|
||||
PET_LOAD_ERROR = 2
|
||||
PET_LOAD_OK = 0,
|
||||
PET_LOAD_NO_RESULT = 1,
|
||||
PET_LOAD_ERROR = 2
|
||||
};
|
||||
|
||||
enum NPCEntries
|
||||
|
||||
@@ -813,7 +813,7 @@ int32 Player::getMaxTimer(MirrorTimerType timer)
|
||||
{
|
||||
if (!IsAlive() || HasAuraType(SPELL_AURA_WATER_BREATHING) || GetSession()->GetSecurity() >= AccountTypes(sWorld->getIntConfig(CONFIG_DISABLE_BREATHING)))
|
||||
return DISABLED_MIRROR_TIMER;
|
||||
int32 UnderWaterTime = static_cast<int32>(sWorld->getFloatConfig(CONFIG_WATER_BREATH_TIMER) * MINUTE * IN_MILLISECONDS);
|
||||
int32 UnderWaterTime = sWorld->getIntConfig(CONFIG_WATER_BREATH_TIMER);
|
||||
AuraEffectList const& mModWaterBreathing = GetAuraEffectsByType(SPELL_AURA_MOD_WATER_BREATHING);
|
||||
for (AuraEffectList::const_iterator i = mModWaterBreathing.begin(); i != mModWaterBreathing.end(); ++i)
|
||||
AddPct(UnderWaterTime, (*i)->GetAmount());
|
||||
@@ -13192,7 +13192,7 @@ void Player::StoreLootItem(uint8 lootSlot, Loot* loot)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!item->AllowedForPlayer(this))
|
||||
if (!item->AllowedForPlayer(this, loot->sourceWorldObjectGUID))
|
||||
{
|
||||
SendLootRelease(GetLootGUID());
|
||||
return;
|
||||
|
||||
@@ -33,7 +33,8 @@ Totem::Totem(SummonPropertiesEntry const* properties, ObjectGuid owner) : Minion
|
||||
|
||||
void Totem::Update(uint32 time)
|
||||
{
|
||||
if (!GetOwner()->IsAlive() || !IsAlive())
|
||||
Unit* owner = GetOwner();
|
||||
if (!owner || !owner->IsAlive() || !IsAlive())
|
||||
{
|
||||
UnSummon(); // remove self
|
||||
return;
|
||||
|
||||
@@ -3623,8 +3623,12 @@ void Unit::SetCurrentCastedSpell(Spell* pSpell)
|
||||
{
|
||||
// generic spells always break channeled not delayed spells
|
||||
if (Spell* s = GetCurrentSpell(CURRENT_CHANNELED_SPELL))
|
||||
if (s->GetSpellInfo()->Id != 69051) // pussywizard: FoS, boss Devourer of Souls, Mirrored Soul, does not have any special attribute
|
||||
{
|
||||
if (!s->GetSpellInfo()->IsActionAllowedChannel())
|
||||
{
|
||||
InterruptSpell(CURRENT_CHANNELED_SPELL, false);
|
||||
}
|
||||
}
|
||||
|
||||
// autorepeat breaking
|
||||
if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL])
|
||||
@@ -3659,7 +3663,14 @@ void Unit::SetCurrentCastedSpell(Spell* pSpell)
|
||||
if (pSpell->m_spellInfo->Id != 75)
|
||||
{
|
||||
// generic autorepeats break generic non-delayed and channeled non-delayed spells
|
||||
InterruptSpell(CURRENT_GENERIC_SPELL, false);
|
||||
if (Spell* s = GetCurrentSpell(CURRENT_CHANNELED_SPELL))
|
||||
{
|
||||
if (!s->GetSpellInfo()->IsActionAllowedChannel())
|
||||
{
|
||||
InterruptSpell(CURRENT_CHANNELED_SPELL, false);
|
||||
}
|
||||
}
|
||||
|
||||
InterruptSpell(CURRENT_CHANNELED_SPELL, false);
|
||||
}
|
||||
// special action: set first cast flag
|
||||
@@ -3794,7 +3805,7 @@ bool Unit::IsMovementPreventedByCasting() const
|
||||
{
|
||||
if (spell->getState() != SPELL_STATE_FINISHED && spell->IsChannelActive())
|
||||
{
|
||||
if (spell->GetSpellInfo()->IsMoveAllowedChannel())
|
||||
if (spell->GetSpellInfo()->IsActionAllowedChannel())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -3805,15 +3816,6 @@ bool Unit::IsMovementPreventedByCasting() const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Unit::CanMoveDuringChannel() const
|
||||
{
|
||||
if (Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL])
|
||||
if (spell->getState() != SPELL_STATE_FINISHED)
|
||||
return spell->GetSpellInfo()->HasAttribute(SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL) && spell->IsChannelActive();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Unit::isInFrontInMap(Unit const* target, float distance, float arc) const
|
||||
{
|
||||
return IsWithinDistInMap(target, distance) && HasInArc(arc, target);
|
||||
@@ -13181,7 +13183,7 @@ void Unit::SetInCombatState(bool PvP, Unit* enemy, uint32 duration)
|
||||
|
||||
// xinef: if we somehow engage in combat (scripts, dunno) with player, remove this flag so he can fight back
|
||||
if (GetTypeId() == TYPEID_UNIT && enemy && IsImmuneToPC() && enemy->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
SetImmuneToPC(true); // unit has engaged in combat, remove immunity so players can fight back
|
||||
SetImmuneToPC(false); // unit has engaged in combat, remove immunity so players can fight back
|
||||
|
||||
if (IsInCombat())
|
||||
return;
|
||||
@@ -13203,6 +13205,8 @@ void Unit::SetInCombatState(bool PvP, Unit* enemy, uint32 duration)
|
||||
|
||||
if (creature->GetFormation())
|
||||
creature->GetFormation()->MemberEngagingTarget(creature, enemy);
|
||||
|
||||
sScriptMgr->OnUnitEnterCombat(creature, enemy);
|
||||
}
|
||||
|
||||
creature->RefreshSwimmingFlag();
|
||||
@@ -16375,6 +16379,8 @@ void Unit::SetDisplayId(uint32 modelId)
|
||||
// Set Gender by modelId
|
||||
if (CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(modelId))
|
||||
SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender);
|
||||
|
||||
sScriptMgr->OnDisplayIdChange(this, modelId);
|
||||
}
|
||||
|
||||
void Unit::RestoreDisplayId()
|
||||
@@ -17512,6 +17518,7 @@ void Unit::Kill(Unit* killer, Unit* victim, bool durabilityLoss, WeaponAttackTyp
|
||||
if (CreatureAI* ai = creature->AI())
|
||||
{
|
||||
ai->JustDied(killer);
|
||||
sScriptMgr->OnUnitDeath(creature, killer);
|
||||
}
|
||||
|
||||
if (TempSummon* summon = creature->ToTempSummon())
|
||||
|
||||
@@ -2031,9 +2031,6 @@ public:
|
||||
// delayed+channeled spells are always interrupted
|
||||
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid = 0, bool withInstant = true, bool bySelf = false);
|
||||
|
||||
// Check if our current channel spell has attribute SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL
|
||||
[[nodiscard]] bool CanMoveDuringChannel() const;
|
||||
|
||||
[[nodiscard]] Spell* GetCurrentSpell(CurrentSpellTypes spellType) const { return m_currentSpells[spellType]; }
|
||||
[[nodiscard]] Spell* GetCurrentSpell(uint32 spellType) const { return m_currentSpells[spellType]; }
|
||||
[[nodiscard]] Spell* FindCurrentSpellBySpellId(uint32 spell_id) const;
|
||||
|
||||
@@ -51,11 +51,11 @@ enum VehicleFlags
|
||||
|
||||
enum VehicleSpells
|
||||
{
|
||||
VEHICLE_SPELL_RIDE_HARDCODED = 46598,
|
||||
VEHICLE_SPELL_PARACHUTE = 45472,
|
||||
VEHICLE_SPELL_RIDE_HARDCODED = 46598,
|
||||
VEHICLE_SPELL_PARACHUTE = 45472,
|
||||
|
||||
VEHICLE_SPELL_GEIST_CONTROL_END = 58119,
|
||||
VEHICLE_SPELL_SHADE_CONTROL_END = 58664
|
||||
VEHICLE_SPELL_GEIST_CONTROL_END = 58119,
|
||||
VEHICLE_SPELL_SHADE_CONTROL_END = 58664
|
||||
};
|
||||
|
||||
enum VehicleNPCs
|
||||
|
||||
@@ -24,16 +24,16 @@
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
#define max_ge_check_delay DAY // 1 day in seconds
|
||||
#define max_ge_check_delay DAY // 1 day in seconds
|
||||
|
||||
enum GameEventState
|
||||
{
|
||||
GAMEEVENT_NORMAL = 0, // standard game events
|
||||
GAMEEVENT_WORLD_INACTIVE = 1, // not yet started
|
||||
GAMEEVENT_WORLD_CONDITIONS = 2, // condition matching phase
|
||||
GAMEEVENT_WORLD_NEXTPHASE = 3, // conditions are met, now 'length' timer to start next event
|
||||
GAMEEVENT_WORLD_FINISHED = 4, // next events are started, unapply this one
|
||||
GAMEEVENT_INTERNAL = 5, // never handled in update
|
||||
GAMEEVENT_NORMAL = 0, // standard game events
|
||||
GAMEEVENT_WORLD_INACTIVE = 1, // not yet started
|
||||
GAMEEVENT_WORLD_CONDITIONS = 2, // condition matching phase
|
||||
GAMEEVENT_WORLD_NEXTPHASE = 3, // conditions are met, now 'length' timer to start next event
|
||||
GAMEEVENT_WORLD_FINISHED = 4, // next events are started, unapply this one
|
||||
GAMEEVENT_INTERNAL = 5, // never handled in update
|
||||
};
|
||||
|
||||
struct GameEventFinishCondition
|
||||
@@ -83,10 +83,10 @@ struct ModelEquip
|
||||
|
||||
struct NPCVendorEntry
|
||||
{
|
||||
uint32 entry; // creature entry
|
||||
uint32 item; // item id
|
||||
int32 maxcount; // 0 for infinite
|
||||
uint32 incrtime; // time for restore items amount if maxcount != 0
|
||||
uint32 entry; // creature entry
|
||||
uint32 item; // item id
|
||||
int32 maxcount; // 0 for infinite
|
||||
uint32 incrtime; // time for restore items amount if maxcount != 0
|
||||
uint32 ExtendedCost;
|
||||
};
|
||||
|
||||
|
||||
@@ -925,7 +925,19 @@ namespace Acore
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!i_obj->IsWithinDistInMap(u, i_range) || !i_owner->IsValidAttackTarget(u) || !i_obj->IsWithinLOSInMap(u))
|
||||
uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
|
||||
Optional<float> collisionHeight = { };
|
||||
if (i_obj->GetTypeId() == TYPEID_GAMEOBJECT)
|
||||
{
|
||||
losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
|
||||
if (i_owner->IsPlayer())
|
||||
{
|
||||
collisionHeight = i_owner->GetCollisionHeight();
|
||||
}
|
||||
}
|
||||
|
||||
if (!i_obj->IsWithinDistInMap(u, i_range) || !i_owner->IsValidAttackTarget(u) ||
|
||||
!i_obj->IsWithinLOSInMap(u, VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks(losChecks), collisionHeight))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1015,7 +1015,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject)
|
||||
continue;
|
||||
if (member->IsAtLootRewardDistance(pLootedObject))
|
||||
{
|
||||
if (i->AllowedForPlayer(member))
|
||||
if (i->AllowedForPlayer(member, loot->sourceWorldObjectGUID))
|
||||
{
|
||||
r->totalPlayersRolling++;
|
||||
|
||||
@@ -1099,7 +1099,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject)
|
||||
|
||||
if (member->IsAtLootRewardDistance(pLootedObject))
|
||||
{
|
||||
if (i->AllowedForPlayer(member))
|
||||
if (i->AllowedForPlayer(member, loot->sourceWorldObjectGUID))
|
||||
{
|
||||
r->totalPlayersRolling++;
|
||||
r->playerVote[member->GetGUID()] = NOT_EMITED_YET;
|
||||
@@ -1157,7 +1157,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject)
|
||||
if (!playerToRoll)
|
||||
continue;
|
||||
|
||||
if (i->AllowedForPlayer(playerToRoll) && playerToRoll->IsAtLootRewardDistance(lootedObject))
|
||||
if (i->AllowedForPlayer(playerToRoll, loot->sourceWorldObjectGUID) && playerToRoll->IsAtLootRewardDistance(lootedObject))
|
||||
{
|
||||
r->totalPlayersRolling++;
|
||||
if (playerToRoll->GetPassOnGroupLoot())
|
||||
@@ -1231,7 +1231,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject)
|
||||
if (!playerToRoll)
|
||||
continue;
|
||||
|
||||
if (i->AllowedForPlayer(playerToRoll) && playerToRoll->IsAtLootRewardDistance(lootedObject))
|
||||
if (i->AllowedForPlayer(playerToRoll, loot->sourceWorldObjectGUID) && playerToRoll->IsAtLootRewardDistance(lootedObject))
|
||||
{
|
||||
r->totalPlayersRolling++;
|
||||
r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET;
|
||||
|
||||
@@ -1573,6 +1573,23 @@ void WorldSession::HandleRemoveGlyph(WorldPacket& recvData)
|
||||
if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
|
||||
{
|
||||
_player->RemoveAurasDueToSpell(glyphEntry->SpellId);
|
||||
|
||||
// Removed any triggered auras
|
||||
Unit::AuraMap& ownedAuras = _player->GetOwnedAuras();
|
||||
for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
|
||||
{
|
||||
Aura* aura = iter->second;
|
||||
if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
|
||||
{
|
||||
if (triggeredByAuraSpellInfo->Id == glyphEntry->SpellId)
|
||||
{
|
||||
_player->RemoveOwnedAura(iter);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
|
||||
_player->SendLearnPacket(glyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
|
||||
_player->SetGlyph(slot, 0, true);
|
||||
_player->SendTalentsInfoData(false);
|
||||
|
||||
@@ -469,7 +469,7 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recvData)
|
||||
|
||||
ItemPosCountVec dest;
|
||||
InventoryResult msg = target->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, item.itemid, item.count);
|
||||
if (!item.AllowedForPlayer(target, true))
|
||||
if (!item.AllowedForPlayer(target, loot->sourceWorldObjectGUID))
|
||||
msg = EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
|
||||
if (msg != EQUIP_ERR_OK)
|
||||
{
|
||||
|
||||
@@ -98,6 +98,12 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket& recv_data)
|
||||
if (_player->PlayerTalkClass->IsGossipOptionCoded(gossipListId))
|
||||
recv_data >> code;
|
||||
|
||||
// Prevent cheating on C++ scripted menus
|
||||
if (_player->PlayerTalkClass->GetGossipMenu().GetSenderGUID() != guid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Creature* unit = nullptr;
|
||||
GameObject* go = nullptr;
|
||||
Item* item = nullptr;
|
||||
@@ -528,6 +534,16 @@ void WorldSession::HandleSetSelectionOpcode(WorldPacket& recv_data)
|
||||
ObjectGuid guid;
|
||||
recv_data >> guid;
|
||||
|
||||
if (!guid)
|
||||
{
|
||||
// Clear any active gossip related to current selection if not present at player's client
|
||||
GossipMenu& gossipMenu = _player->PlayerTalkClass->GetGossipMenu();
|
||||
if (gossipMenu.GetSenderGUID() == _player->GetTarget())
|
||||
{
|
||||
_player->PlayerTalkClass->SendCloseGossip();
|
||||
}
|
||||
}
|
||||
|
||||
_player->SetSelection(guid);
|
||||
|
||||
// Change target of current autoshoot spell
|
||||
|
||||
@@ -38,9 +38,11 @@ void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket& recvData)
|
||||
uint32 questStatus = DIALOG_STATUS_NONE;
|
||||
|
||||
GossipMenu& gossipMenu = _player->PlayerTalkClass->GetGossipMenu();
|
||||
// Did we already get get a gossip menu? if so no need to status query
|
||||
if (!gossipMenu.Empty())
|
||||
// Did we already get a gossip menu with that NPC? if so no need to status query
|
||||
if (gossipMenu.GetSenderGUID() == guid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Object* questGiver = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT);
|
||||
if (!questGiver)
|
||||
|
||||
@@ -491,7 +491,7 @@ void WorldSession::HandleCancelAuraOpcode(WorldPacket& recvPacket)
|
||||
if (!spellInfo)
|
||||
return;
|
||||
|
||||
// not allow remove spells with attr SPELL_ATTR0_CANT_CANCEL
|
||||
// not allow remove spells with attr SPELL_ATTR0_NO_AURA_CANCEL
|
||||
if (spellInfo->HasAttribute(SPELL_ATTR0_NO_AURA_CANCEL))
|
||||
{
|
||||
return;
|
||||
@@ -569,12 +569,33 @@ void WorldSession::HandleCancelAutoRepeatSpellOpcode(WorldPacket& /*recvPacket*/
|
||||
|
||||
void WorldSession::HandleCancelChanneling(WorldPacket& recvData)
|
||||
{
|
||||
recvData.read_skip<uint32>(); // spellid, not used
|
||||
uint32 spellID = 0;
|
||||
recvData >> spellID;
|
||||
|
||||
// ignore for remote control state (for player case)
|
||||
Unit* mover = _player->m_mover;
|
||||
if (mover != _player && mover->GetTypeId() == TYPEID_PLAYER)
|
||||
if (!mover)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID);
|
||||
if (!spellInfo)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// not allow remove spells with attr SPELL_ATTR0_NO_AURA_CANCEL
|
||||
if (spellInfo->HasAttribute(SPELL_ATTR0_NO_AURA_CANCEL))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Spell* spell = mover->GetCurrentSpell(CURRENT_CHANNELED_SPELL);
|
||||
if (!spell || spell->GetSpellInfo()->Id != spellInfo->Id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mover->InterruptSpell(CURRENT_CHANNELED_SPELL);
|
||||
}
|
||||
|
||||
@@ -404,7 +404,7 @@ LootItem::LootItem(LootStoreItem const& li)
|
||||
}
|
||||
|
||||
// Basic checks for player/item compatibility - if false no chance to see the item in the loot
|
||||
bool LootItem::AllowedForPlayer(Player const* player, bool isGivenByMasterLooter /*= false*/, bool allowQuestLoot /*= true*/) const
|
||||
bool LootItem::AllowedForPlayer(Player const* player, bool isGivenByMasterLooter /*= false*/, bool allowQuestLoot /*= true*/, ObjectGuid source) const
|
||||
{
|
||||
ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(itemid);
|
||||
if (!pProto)
|
||||
@@ -472,6 +472,11 @@ bool LootItem::AllowedForPlayer(Player const* player, bool isGivenByMasterLooter
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sScriptMgr->OnAllowedForPlayerLootCheck(player, source))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -515,7 +520,7 @@ void Loot::AddItem(LootStoreItem const& item)
|
||||
{
|
||||
if (auto member = itr->GetSource())
|
||||
{
|
||||
if (generatedLoot.AllowedForPlayer(member))
|
||||
if (generatedLoot.AllowedForPlayer(member, sourceWorldObjectGUID))
|
||||
{
|
||||
canSeeItemInLootWindow = true;
|
||||
break;
|
||||
@@ -523,7 +528,7 @@ void Loot::AddItem(LootStoreItem const& item)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (generatedLoot.AllowedForPlayer(player))
|
||||
else if (generatedLoot.AllowedForPlayer(player, sourceWorldObjectGUID))
|
||||
{
|
||||
canSeeItemInLootWindow = true;
|
||||
}
|
||||
@@ -626,7 +631,7 @@ void Loot::FillNotNormalLootFor(Player* player)
|
||||
else
|
||||
item = &quest_items[i - itemsSize];
|
||||
|
||||
if (!item->is_looted && item->freeforall && item->AllowedForPlayer(player))
|
||||
if (!item->is_looted && item->freeforall && item->AllowedForPlayer(player, sourceWorldObjectGUID))
|
||||
if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item->itemid))
|
||||
if (proto->IsCurrencyToken())
|
||||
player->StoreLootItem(i, this);
|
||||
@@ -640,7 +645,7 @@ QuestItemList* Loot::FillFFALoot(Player* player)
|
||||
for (uint8 i = 0; i < items.size(); ++i)
|
||||
{
|
||||
LootItem& item = items[i];
|
||||
if (!item.is_looted && item.freeforall && item.AllowedForPlayer(player))
|
||||
if (!item.is_looted && item.freeforall && item.AllowedForPlayer(player, containerGUID))
|
||||
{
|
||||
ql->push_back(QuestItem(i));
|
||||
++unlootedCount;
|
||||
@@ -701,7 +706,7 @@ QuestItemList* Loot::FillNonQuestNonFFAConditionalLoot(Player* player)
|
||||
for (uint8 i = 0; i < items.size(); ++i)
|
||||
{
|
||||
LootItem& item = items[i];
|
||||
if (!item.is_looted && !item.freeforall && (item.AllowedForPlayer(player) || (item.follow_loot_rules && player->GetGroup() && ((player->GetGroup()->GetLootMethod() == MASTER_LOOT && player->GetGroup()->GetMasterLooterGuid() == player->GetGUID()) || player->GetGroup()->GetLootMethod() != MASTER_LOOT ))))
|
||||
if (!item.is_looted && !item.freeforall && (item.AllowedForPlayer(player, sourceWorldObjectGUID) || (item.follow_loot_rules && player->GetGroup() && ((player->GetGroup()->GetLootMethod() == MASTER_LOOT && player->GetGroup()->GetMasterLooterGuid() == player->GetGUID()) || player->GetGroup()->GetLootMethod() != MASTER_LOOT ))))
|
||||
{
|
||||
item.AddAllowedLooter(player);
|
||||
|
||||
@@ -820,7 +825,7 @@ LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem * *qit
|
||||
if (qitem)
|
||||
*qitem = qitem2;
|
||||
item = &quest_items[qitem2->index];
|
||||
if (item->follow_loot_rules && !item->AllowedForPlayer(player)) // pussywizard: such items (follow_loot_rules) are added to every player, but not everyone is allowed, check it here
|
||||
if (item->follow_loot_rules && !item->AllowedForPlayer(player, sourceWorldObjectGUID)) // pussywizard: such items (follow_loot_rules) are added to every player, but not everyone is allowed, check it here
|
||||
return nullptr;
|
||||
is_looted = qitem2->is_looted;
|
||||
}
|
||||
@@ -989,7 +994,7 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
|
||||
// blocked rolled items and quest items, and !ffa items
|
||||
for (uint8 i = 0; i < l.items.size(); ++i)
|
||||
{
|
||||
if (!l.items[i].is_looted && !l.items[i].freeforall && (l.items[i].conditions.empty() || isMasterLooter) && l.items[i].AllowedForPlayer(lv.viewer))
|
||||
if (!l.items[i].is_looted && !l.items[i].freeforall && (l.items[i].conditions.empty() || isMasterLooter) && l.items[i].AllowedForPlayer(lv.viewer, l.sourceWorldObjectGUID))
|
||||
{
|
||||
uint8 slot_type = 0;
|
||||
|
||||
@@ -1047,7 +1052,7 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
|
||||
{
|
||||
for (uint8 i = 0; i < l.items.size(); ++i)
|
||||
{
|
||||
if (!l.items[i].is_looted && !l.items[i].freeforall && l.items[i].conditions.empty() && l.items[i].AllowedForPlayer(lv.viewer))
|
||||
if (!l.items[i].is_looted && !l.items[i].freeforall && l.items[i].conditions.empty() && l.items[i].AllowedForPlayer(lv.viewer, l.sourceWorldObjectGUID))
|
||||
{
|
||||
if (l.roundRobinPlayer && lv.viewer->GetGUID() != l.roundRobinPlayer)
|
||||
// item shall not be displayed.
|
||||
@@ -1066,7 +1071,7 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
|
||||
uint8 slot_type = lv.permission == OWNER_PERMISSION ? LOOT_SLOT_TYPE_OWNER : LOOT_SLOT_TYPE_ALLOW_LOOT;
|
||||
for (uint8 i = 0; i < l.items.size(); ++i)
|
||||
{
|
||||
if (!l.items[i].is_looted && !l.items[i].freeforall && l.items[i].conditions.empty() && l.items[i].AllowedForPlayer(lv.viewer))
|
||||
if (!l.items[i].is_looted && !l.items[i].freeforall && l.items[i].conditions.empty() && l.items[i].AllowedForPlayer(lv.viewer, l.sourceWorldObjectGUID))
|
||||
{
|
||||
b << uint8(i) << l.items[i];
|
||||
b << uint8(slot_type);
|
||||
|
||||
@@ -31,22 +31,22 @@
|
||||
|
||||
enum RollType
|
||||
{
|
||||
ROLL_PASS = 0,
|
||||
ROLL_NEED = 1,
|
||||
ROLL_GREED = 2,
|
||||
ROLL_DISENCHANT = 3,
|
||||
MAX_ROLL_TYPE = 4
|
||||
ROLL_PASS = 0,
|
||||
ROLL_NEED = 1,
|
||||
ROLL_GREED = 2,
|
||||
ROLL_DISENCHANT = 3,
|
||||
MAX_ROLL_TYPE = 4
|
||||
};
|
||||
|
||||
enum RollMask
|
||||
{
|
||||
ROLL_FLAG_TYPE_PASS = 0x01,
|
||||
ROLL_FLAG_TYPE_NEED = 0x02,
|
||||
ROLL_FLAG_TYPE_GREED = 0x04,
|
||||
ROLL_FLAG_TYPE_DISENCHANT = 0x08,
|
||||
ROLL_FLAG_TYPE_PASS = 0x01,
|
||||
ROLL_FLAG_TYPE_NEED = 0x02,
|
||||
ROLL_FLAG_TYPE_GREED = 0x04,
|
||||
ROLL_FLAG_TYPE_DISENCHANT = 0x08,
|
||||
|
||||
ROLL_ALL_TYPE_NO_DISENCHANT = 0x07,
|
||||
ROLL_ALL_TYPE_MASK = 0x0F
|
||||
ROLL_ALL_TYPE_NO_DISENCHANT = 0x07,
|
||||
ROLL_ALL_TYPE_MASK = 0x0F
|
||||
};
|
||||
|
||||
#define MAX_NR_LOOT_ITEMS 18
|
||||
@@ -56,40 +56,40 @@ enum RollMask
|
||||
|
||||
enum LootMethod
|
||||
{
|
||||
FREE_FOR_ALL = 0,
|
||||
ROUND_ROBIN = 1,
|
||||
MASTER_LOOT = 2,
|
||||
GROUP_LOOT = 3,
|
||||
NEED_BEFORE_GREED = 4
|
||||
FREE_FOR_ALL = 0,
|
||||
ROUND_ROBIN = 1,
|
||||
MASTER_LOOT = 2,
|
||||
GROUP_LOOT = 3,
|
||||
NEED_BEFORE_GREED = 4
|
||||
};
|
||||
|
||||
enum PermissionTypes
|
||||
{
|
||||
ALL_PERMISSION = 0,
|
||||
GROUP_PERMISSION = 1,
|
||||
MASTER_PERMISSION = 2,
|
||||
RESTRICTED_PERMISSION = 3,
|
||||
ROUND_ROBIN_PERMISSION = 4,
|
||||
OWNER_PERMISSION = 5,
|
||||
NONE_PERMISSION = 6
|
||||
ALL_PERMISSION = 0,
|
||||
GROUP_PERMISSION = 1,
|
||||
MASTER_PERMISSION = 2,
|
||||
RESTRICTED_PERMISSION = 3,
|
||||
ROUND_ROBIN_PERMISSION = 4,
|
||||
OWNER_PERMISSION = 5,
|
||||
NONE_PERMISSION = 6
|
||||
};
|
||||
|
||||
enum LootType
|
||||
{
|
||||
LOOT_NONE = 0,
|
||||
LOOT_NONE = 0,
|
||||
|
||||
LOOT_CORPSE = 1,
|
||||
LOOT_PICKPOCKETING = 2,
|
||||
LOOT_FISHING = 3,
|
||||
LOOT_DISENCHANTING = 4,
|
||||
LOOT_CORPSE = 1,
|
||||
LOOT_PICKPOCKETING = 2,
|
||||
LOOT_FISHING = 3,
|
||||
LOOT_DISENCHANTING = 4,
|
||||
// ignored always by client
|
||||
LOOT_SKINNING = 6,
|
||||
LOOT_PROSPECTING = 7,
|
||||
LOOT_MILLING = 8,
|
||||
LOOT_SKINNING = 6,
|
||||
LOOT_PROSPECTING = 7,
|
||||
LOOT_MILLING = 8,
|
||||
|
||||
LOOT_FISHINGHOLE = 20, // unsupported by client, sending LOOT_FISHING instead
|
||||
LOOT_INSIGNIA = 21, // unsupported by client, sending LOOT_CORPSE instead
|
||||
LOOT_FISHING_JUNK = 22 // unsupported by client, sending LOOT_FISHING instead
|
||||
LOOT_FISHINGHOLE = 20, // unsupported by client, sending LOOT_FISHING instead
|
||||
LOOT_INSIGNIA = 21, // unsupported by client, sending LOOT_CORPSE instead
|
||||
LOOT_FISHING_JUNK = 22 // unsupported by client, sending LOOT_FISHING instead
|
||||
};
|
||||
|
||||
enum LootError
|
||||
@@ -112,11 +112,11 @@ enum LootError
|
||||
// type of Loot Item in Loot View
|
||||
enum LootSlotType
|
||||
{
|
||||
LOOT_SLOT_TYPE_ALLOW_LOOT = 0, // player can loot the item.
|
||||
LOOT_SLOT_TYPE_ROLL_ONGOING = 1, // roll is ongoing. player cannot loot.
|
||||
LOOT_SLOT_TYPE_MASTER = 2, // item can only be distributed by group loot master.
|
||||
LOOT_SLOT_TYPE_LOCKED = 3, // item is shown in red. player cannot loot.
|
||||
LOOT_SLOT_TYPE_OWNER = 4, // ignore binding confirmation and etc, for single player looting
|
||||
LOOT_SLOT_TYPE_ALLOW_LOOT = 0, // player can loot the item.
|
||||
LOOT_SLOT_TYPE_ROLL_ONGOING = 1, // roll is ongoing. player cannot loot.
|
||||
LOOT_SLOT_TYPE_MASTER = 2, // item can only be distributed by group loot master.
|
||||
LOOT_SLOT_TYPE_LOCKED = 3, // item is shown in red. player cannot loot.
|
||||
LOOT_SLOT_TYPE_OWNER = 4, // ignore binding confirmation and etc, for single player looting
|
||||
};
|
||||
|
||||
class Player;
|
||||
@@ -127,15 +127,15 @@ struct Loot;
|
||||
|
||||
struct LootStoreItem
|
||||
{
|
||||
uint32 itemid; // id of the item
|
||||
int32 reference; // referenced TemplateleId
|
||||
float chance; // chance to drop for both quest and non-quest items, chance to be used for refs
|
||||
bool needs_quest : 1; // quest drop (quest is required for item to drop)
|
||||
uint32 itemid; // id of the item
|
||||
int32 reference; // referenced TemplateleId
|
||||
float chance; // chance to drop for both quest and non-quest items, chance to be used for refs
|
||||
bool needs_quest : 1; // quest drop (quest is required for item to drop)
|
||||
uint16 lootmode;
|
||||
uint8 groupid : 7;
|
||||
uint8 mincount; // mincount for drop items
|
||||
uint8 maxcount; // max drop count for the item mincount or Ref multiplicator
|
||||
ConditionList conditions; // additional loot condition
|
||||
uint8 mincount; // mincount for drop items
|
||||
uint8 maxcount; // max drop count for the item mincount or Ref multiplicator
|
||||
ConditionList conditions; // additional loot condition
|
||||
|
||||
// Constructor
|
||||
// displayid is filled in IsValid() which must be called after
|
||||
@@ -144,7 +144,7 @@ struct LootStoreItem
|
||||
lootmode(_lootmode), groupid(_groupid), mincount(_mincount), maxcount(_maxcount)
|
||||
{}
|
||||
|
||||
bool Roll(bool rate, Player const* player, Loot& loot, LootStore const& store) const; // Checks if the entry takes it's chance (at loot generation)
|
||||
bool Roll(bool rate, Player const* player, Loot& loot, LootStore const& store) const; // Checks if the entry takes it's chance (at loot generation)
|
||||
[[nodiscard]] bool IsValid(LootStore const& store, uint32 entry) const;
|
||||
// Checks correctness of values
|
||||
};
|
||||
@@ -176,8 +176,8 @@ struct LootItem
|
||||
LootItem() = default;
|
||||
|
||||
// Basic checks for player/item compatibility - if false no chance to see the item in the loot
|
||||
bool AllowedForPlayer(Player const* player, bool isGivenByMasterLooter = false, bool allowQuestLoot = true) const;
|
||||
|
||||
bool AllowedForPlayer(Player const* player, bool isGivenByMasterLooter = false, bool allowQuestLoot = true, ObjectGuid source = ObjectGuid::Empty) const;
|
||||
bool AllowedForPlayer(Player const* player, ObjectGuid source) { return AllowedForPlayer(player, false, true, source); };
|
||||
void AddAllowedLooter(Player const* player);
|
||||
[[nodiscard]] const AllowedLooterSet& GetAllowedLooters() const { return allowedGUIDs; }
|
||||
};
|
||||
@@ -327,6 +327,7 @@ struct Loot
|
||||
|
||||
// GUID of container that holds this loot (item_instance.entry), set for items that can be looted
|
||||
ObjectGuid containerGUID;
|
||||
ObjectGuid sourceWorldObjectGUID;
|
||||
GameObject* sourceGameObject{nullptr};
|
||||
|
||||
Loot(uint32 _gold = 0) : gold(_gold) { }
|
||||
|
||||
@@ -161,3 +161,18 @@ void ScriptMgr::OnLoadSpellCustomAttr(SpellInfo* spell)
|
||||
script->OnLoadSpellCustomAttr(spell);
|
||||
});
|
||||
}
|
||||
|
||||
bool ScriptMgr::OnAllowedForPlayerLootCheck(Player const* player, ObjectGuid source)
|
||||
{
|
||||
auto ret = IsValidBoolScript<GlobalScript>([&](GlobalScript* script)
|
||||
{
|
||||
return script->OnAllowedForPlayerLootCheck(player, source);
|
||||
});
|
||||
|
||||
if (ret && *ret)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -210,3 +210,35 @@ void ScriptMgr::OnUnitUpdate(Unit* unit, uint32 diff)
|
||||
script->OnUnitUpdate(unit, diff);
|
||||
});
|
||||
}
|
||||
|
||||
void ScriptMgr::OnDisplayIdChange(Unit* unit, uint32 displayId)
|
||||
{
|
||||
ExecuteScript<UnitScript>([&](UnitScript* script)
|
||||
{
|
||||
script->OnDisplayIdChange(unit, displayId);
|
||||
});
|
||||
}
|
||||
|
||||
void ScriptMgr::OnUnitEnterEvadeMode(Unit* unit, uint8 evadeReason)
|
||||
{
|
||||
ExecuteScript<UnitScript>([&](UnitScript* script)
|
||||
{
|
||||
script->OnUnitEnterEvadeMode(unit, evadeReason);
|
||||
});
|
||||
}
|
||||
|
||||
void ScriptMgr::OnUnitEnterCombat(Unit* unit, Unit* victim)
|
||||
{
|
||||
ExecuteScript<UnitScript>([&](UnitScript* script)
|
||||
{
|
||||
script->OnUnitEnterCombat(unit, victim);
|
||||
});
|
||||
}
|
||||
|
||||
void ScriptMgr::OnUnitDeath(Unit* unit, Unit* killer)
|
||||
{
|
||||
ExecuteScript<UnitScript>([&](UnitScript* script)
|
||||
{
|
||||
script->OnUnitDeath(unit, killer);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -460,6 +460,12 @@ public:
|
||||
* @param diff Contains information about the diff time
|
||||
*/
|
||||
virtual void OnUnitUpdate(Unit* /*unit*/, uint32 /*diff*/) { }
|
||||
|
||||
virtual void OnDisplayIdChange(Unit* /*unit*/, uint32 /*displayId*/) { }
|
||||
|
||||
virtual void OnUnitEnterEvadeMode(Unit* /*unit*/, uint8 /*evadeReason*/) { }
|
||||
virtual void OnUnitEnterCombat(Unit* /*unit*/, Unit* /*victim*/) { }
|
||||
virtual void OnUnitDeath(Unit* /*unit*/, Unit* /*killer*/) { }
|
||||
};
|
||||
|
||||
class MovementHandlerScript : public ScriptObject
|
||||
@@ -1551,6 +1557,9 @@ public:
|
||||
|
||||
// Called after loading spell dbc corrections
|
||||
virtual void OnLoadSpellCustomAttr(SpellInfo* /*spell*/) { }
|
||||
|
||||
// Called when checking if a player can see the creature loot
|
||||
virtual bool OnAllowedForPlayerLootCheck(Player const* /*player*/, ObjectGuid /*source*/) { return false; };
|
||||
};
|
||||
|
||||
class BGScript : public ScriptObject
|
||||
@@ -2412,6 +2421,7 @@ public: /* GlobalScript */
|
||||
bool OnIsAffectedBySpellModCheck(SpellInfo const* affectSpell, SpellInfo const* checkSpell, SpellModifier const* mod);
|
||||
bool OnSpellHealingBonusTakenNegativeModifiers(Unit const* target, Unit const* caster, SpellInfo const* spellInfo, float& val);
|
||||
void OnLoadSpellCustomAttr(SpellInfo* spell);
|
||||
bool OnAllowedForPlayerLootCheck(Player const* player, ObjectGuid source);
|
||||
|
||||
public: /* Scheduled scripts */
|
||||
uint32 IncreaseScheduledScriptsCount() { return ++_scheduledScripts; }
|
||||
@@ -2437,6 +2447,10 @@ public: /* UnitScript */
|
||||
bool IsCustomBuildValuesUpdate(Unit const* unit, uint8 updateType, ByteBuffer& fieldBuffer, Player const* target, uint16 index);
|
||||
bool OnBuildValuesUpdate(Unit const* unit, uint8 updateType, ByteBuffer& fieldBuffer, Player* target, uint16 index);
|
||||
void OnUnitUpdate(Unit* unit, uint32 diff);
|
||||
void OnDisplayIdChange(Unit* unit, uint32 displayId);
|
||||
void OnUnitEnterEvadeMode(Unit* unit, uint8 why);
|
||||
void OnUnitEnterCombat(Unit* unit, Unit* victim);
|
||||
void OnUnitDeath(Unit* unit, Unit* killer);
|
||||
|
||||
public: /* MovementHandlerScript */
|
||||
void OnPlayerMove(Player* player, MovementInfo movementInfo, uint32 opcode);
|
||||
|
||||
@@ -38,13 +38,13 @@ enum AURA_FLAGS
|
||||
|
||||
enum AuraEffectHandleModes
|
||||
{
|
||||
AURA_EFFECT_HANDLE_DEFAULT = 0x0,
|
||||
AURA_EFFECT_HANDLE_REAL = 0x01, // handler applies/removes effect from unit
|
||||
AURA_EFFECT_HANDLE_SEND_FOR_CLIENT = 0x02, // handler sends apply/remove packet to unit
|
||||
AURA_EFFECT_HANDLE_CHANGE_AMOUNT = 0x04, // handler updates effect on target after effect amount change
|
||||
AURA_EFFECT_HANDLE_REAPPLY = 0x08, // handler updates effect on target after aura is reapplied on target
|
||||
AURA_EFFECT_HANDLE_STAT = 0x10, // handler updates effect on target when stat removal/apply is needed for calculations by core
|
||||
AURA_EFFECT_HANDLE_SKILL = 0x20, // handler updates effect on target when skill removal/apply is needed for calculations by core
|
||||
AURA_EFFECT_HANDLE_DEFAULT = 0x0,
|
||||
AURA_EFFECT_HANDLE_REAL = 0x01, // handler applies/removes effect from unit
|
||||
AURA_EFFECT_HANDLE_SEND_FOR_CLIENT = 0x02, // handler sends apply/remove packet to unit
|
||||
AURA_EFFECT_HANDLE_CHANGE_AMOUNT = 0x04, // handler updates effect on target after effect amount change
|
||||
AURA_EFFECT_HANDLE_REAPPLY = 0x08, // handler updates effect on target after aura is reapplied on target
|
||||
AURA_EFFECT_HANDLE_STAT = 0x10, // handler updates effect on target when stat removal/apply is needed for calculations by core
|
||||
AURA_EFFECT_HANDLE_SKILL = 0x20, // handler updates effect on target when skill removal/apply is needed for calculations by core
|
||||
AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK = (AURA_EFFECT_HANDLE_SEND_FOR_CLIENT | AURA_EFFECT_HANDLE_REAL), // any case handler need to send packet
|
||||
AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK = (AURA_EFFECT_HANDLE_CHANGE_AMOUNT | AURA_EFFECT_HANDLE_REAL), // any case handler applies effect depending on amount
|
||||
AURA_EFFECT_HANDLE_CHANGE_AMOUNT_SEND_FOR_CLIENT_MASK = (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK),
|
||||
@@ -54,330 +54,330 @@ enum AuraEffectHandleModes
|
||||
//m_schoolAbsorb
|
||||
enum DAMAGE_ABSORB_TYPE
|
||||
{
|
||||
ALL_DAMAGE_ABSORB = -2,
|
||||
ONLY_MAGIC_ABSORB = -1,
|
||||
ALL_DAMAGE_ABSORB = -2,
|
||||
ONLY_MAGIC_ABSORB = -1,
|
||||
};
|
||||
|
||||
enum AuraType
|
||||
{
|
||||
SPELL_AURA_NONE = 0,
|
||||
SPELL_AURA_BIND_SIGHT = 1,
|
||||
SPELL_AURA_MOD_POSSESS = 2,
|
||||
SPELL_AURA_PERIODIC_DAMAGE = 3,
|
||||
SPELL_AURA_DUMMY = 4,
|
||||
SPELL_AURA_MOD_CONFUSE = 5,
|
||||
SPELL_AURA_MOD_CHARM = 6,
|
||||
SPELL_AURA_MOD_FEAR = 7,
|
||||
SPELL_AURA_PERIODIC_HEAL = 8,
|
||||
SPELL_AURA_MOD_ATTACKSPEED = 9,
|
||||
SPELL_AURA_MOD_THREAT = 10,
|
||||
SPELL_AURA_MOD_TAUNT = 11,
|
||||
SPELL_AURA_MOD_STUN = 12,
|
||||
SPELL_AURA_MOD_DAMAGE_DONE = 13,
|
||||
SPELL_AURA_MOD_DAMAGE_TAKEN = 14,
|
||||
SPELL_AURA_DAMAGE_SHIELD = 15,
|
||||
SPELL_AURA_MOD_STEALTH = 16,
|
||||
SPELL_AURA_MOD_STEALTH_DETECT = 17,
|
||||
SPELL_AURA_MOD_INVISIBILITY = 18,
|
||||
SPELL_AURA_MOD_INVISIBILITY_DETECT = 19,
|
||||
SPELL_AURA_OBS_MOD_HEALTH = 20, //20, 21 unofficial
|
||||
SPELL_AURA_OBS_MOD_POWER = 21,
|
||||
SPELL_AURA_MOD_RESISTANCE = 22,
|
||||
SPELL_AURA_PERIODIC_TRIGGER_SPELL = 23,
|
||||
SPELL_AURA_PERIODIC_ENERGIZE = 24,
|
||||
SPELL_AURA_MOD_PACIFY = 25,
|
||||
SPELL_AURA_MOD_ROOT = 26,
|
||||
SPELL_AURA_MOD_SILENCE = 27,
|
||||
SPELL_AURA_REFLECT_SPELLS = 28,
|
||||
SPELL_AURA_MOD_STAT = 29,
|
||||
SPELL_AURA_MOD_SKILL = 30,
|
||||
SPELL_AURA_MOD_INCREASE_SPEED = 31,
|
||||
SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED = 32,
|
||||
SPELL_AURA_MOD_DECREASE_SPEED = 33,
|
||||
SPELL_AURA_MOD_INCREASE_HEALTH = 34,
|
||||
SPELL_AURA_MOD_INCREASE_ENERGY = 35,
|
||||
SPELL_AURA_MOD_SHAPESHIFT = 36,
|
||||
SPELL_AURA_EFFECT_IMMUNITY = 37,
|
||||
SPELL_AURA_STATE_IMMUNITY = 38,
|
||||
SPELL_AURA_SCHOOL_IMMUNITY = 39,
|
||||
SPELL_AURA_DAMAGE_IMMUNITY = 40,
|
||||
SPELL_AURA_DISPEL_IMMUNITY = 41,
|
||||
SPELL_AURA_PROC_TRIGGER_SPELL = 42,
|
||||
SPELL_AURA_PROC_TRIGGER_DAMAGE = 43,
|
||||
SPELL_AURA_TRACK_CREATURES = 44,
|
||||
SPELL_AURA_TRACK_RESOURCES = 45,
|
||||
SPELL_AURA_46 = 46, // Ignore all Gear test spells
|
||||
SPELL_AURA_MOD_PARRY_PERCENT = 47,
|
||||
SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT = 48, // One periodic spell
|
||||
SPELL_AURA_MOD_DODGE_PERCENT = 49,
|
||||
SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT = 50,
|
||||
SPELL_AURA_MOD_BLOCK_PERCENT = 51,
|
||||
SPELL_AURA_MOD_WEAPON_CRIT_PERCENT = 52,
|
||||
SPELL_AURA_PERIODIC_LEECH = 53,
|
||||
SPELL_AURA_MOD_HIT_CHANCE = 54,
|
||||
SPELL_AURA_MOD_SPELL_HIT_CHANCE = 55,
|
||||
SPELL_AURA_TRANSFORM = 56,
|
||||
SPELL_AURA_MOD_SPELL_CRIT_CHANCE = 57,
|
||||
SPELL_AURA_MOD_INCREASE_SWIM_SPEED = 58,
|
||||
SPELL_AURA_MOD_DAMAGE_DONE_CREATURE = 59,
|
||||
SPELL_AURA_MOD_PACIFY_SILENCE = 60,
|
||||
SPELL_AURA_MOD_SCALE = 61,
|
||||
SPELL_AURA_PERIODIC_HEALTH_FUNNEL = 62,
|
||||
SPELL_AURA_63 = 63, // old SPELL_AURA_PERIODIC_MANA_FUNNEL
|
||||
SPELL_AURA_PERIODIC_MANA_LEECH = 64,
|
||||
SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK = 65,
|
||||
SPELL_AURA_FEIGN_DEATH = 66,
|
||||
SPELL_AURA_MOD_DISARM = 67,
|
||||
SPELL_AURA_MOD_STALKED = 68,
|
||||
SPELL_AURA_SCHOOL_ABSORB = 69,
|
||||
SPELL_AURA_EXTRA_ATTACKS = 70,
|
||||
SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL = 71,
|
||||
SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT = 72,
|
||||
SPELL_AURA_MOD_POWER_COST_SCHOOL = 73,
|
||||
SPELL_AURA_REFLECT_SPELLS_SCHOOL = 74,
|
||||
SPELL_AURA_MOD_LANGUAGE = 75,
|
||||
SPELL_AURA_FAR_SIGHT = 76,
|
||||
SPELL_AURA_MECHANIC_IMMUNITY = 77,
|
||||
SPELL_AURA_MOUNTED = 78,
|
||||
SPELL_AURA_MOD_DAMAGE_PERCENT_DONE = 79,
|
||||
SPELL_AURA_MOD_PERCENT_STAT = 80,
|
||||
SPELL_AURA_SPLIT_DAMAGE_PCT = 81,
|
||||
SPELL_AURA_WATER_BREATHING = 82,
|
||||
SPELL_AURA_MOD_BASE_RESISTANCE = 83,
|
||||
SPELL_AURA_MOD_REGEN = 84,
|
||||
SPELL_AURA_MOD_POWER_REGEN = 85,
|
||||
SPELL_AURA_CHANNEL_DEATH_ITEM = 86,
|
||||
SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN = 87,
|
||||
SPELL_AURA_MOD_HEALTH_REGEN_PERCENT = 88,
|
||||
SPELL_AURA_PERIODIC_DAMAGE_PERCENT = 89,
|
||||
SPELL_AURA_90 = 90, // old SPELL_AURA_MOD_RESIST_CHANCE
|
||||
SPELL_AURA_MOD_DETECT_RANGE = 91,
|
||||
SPELL_AURA_PREVENTS_FLEEING = 92,
|
||||
SPELL_AURA_MOD_UNATTACKABLE = 93,
|
||||
SPELL_AURA_INTERRUPT_REGEN = 94,
|
||||
SPELL_AURA_GHOST = 95,
|
||||
SPELL_AURA_SPELL_MAGNET = 96,
|
||||
SPELL_AURA_MANA_SHIELD = 97,
|
||||
SPELL_AURA_MOD_SKILL_TALENT = 98,
|
||||
SPELL_AURA_MOD_ATTACK_POWER = 99,
|
||||
SPELL_AURA_AURAS_VISIBLE = 100,
|
||||
SPELL_AURA_MOD_RESISTANCE_PCT = 101,
|
||||
SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS = 102,
|
||||
SPELL_AURA_MOD_TOTAL_THREAT = 103,
|
||||
SPELL_AURA_WATER_WALK = 104,
|
||||
SPELL_AURA_FEATHER_FALL = 105,
|
||||
SPELL_AURA_HOVER = 106,
|
||||
SPELL_AURA_ADD_FLAT_MODIFIER = 107,
|
||||
SPELL_AURA_ADD_PCT_MODIFIER = 108,
|
||||
SPELL_AURA_ADD_TARGET_TRIGGER = 109,
|
||||
SPELL_AURA_MOD_POWER_REGEN_PERCENT = 110,
|
||||
SPELL_AURA_ADD_CASTER_HIT_TRIGGER = 111,
|
||||
SPELL_AURA_OVERRIDE_CLASS_SCRIPTS = 112,
|
||||
SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN = 113,
|
||||
SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT = 114,
|
||||
SPELL_AURA_MOD_HEALING = 115,
|
||||
SPELL_AURA_MOD_REGEN_DURING_COMBAT = 116,
|
||||
SPELL_AURA_MOD_MECHANIC_RESISTANCE = 117,
|
||||
SPELL_AURA_MOD_HEALING_PCT = 118,
|
||||
SPELL_AURA_119 = 119, // old SPELL_AURA_SHARE_PET_TRACKING
|
||||
SPELL_AURA_UNTRACKABLE = 120,
|
||||
SPELL_AURA_EMPATHY = 121,
|
||||
SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT = 122,
|
||||
SPELL_AURA_MOD_TARGET_RESISTANCE = 123,
|
||||
SPELL_AURA_MOD_RANGED_ATTACK_POWER = 124,
|
||||
SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN = 125,
|
||||
SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT = 126,
|
||||
SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS = 127,
|
||||
SPELL_AURA_MOD_POSSESS_PET = 128,
|
||||
SPELL_AURA_MOD_SPEED_ALWAYS = 129,
|
||||
SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS = 130,
|
||||
SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS = 131,
|
||||
SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT = 132,
|
||||
SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT = 133,
|
||||
SPELL_AURA_MOD_MANA_REGEN_INTERRUPT = 134,
|
||||
SPELL_AURA_MOD_HEALING_DONE = 135,
|
||||
SPELL_AURA_MOD_HEALING_DONE_PERCENT = 136,
|
||||
SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE = 137,
|
||||
SPELL_AURA_MOD_MELEE_HASTE = 138,
|
||||
SPELL_AURA_FORCE_REACTION = 139,
|
||||
SPELL_AURA_MOD_RANGED_HASTE = 140,
|
||||
SPELL_AURA_MOD_RANGED_AMMO_HASTE = 141,
|
||||
SPELL_AURA_MOD_BASE_RESISTANCE_PCT = 142,
|
||||
SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE = 143,
|
||||
SPELL_AURA_SAFE_FALL = 144,
|
||||
SPELL_AURA_MOD_PET_TALENT_POINTS = 145,
|
||||
SPELL_AURA_ALLOW_TAME_PET_TYPE = 146,
|
||||
SPELL_AURA_MECHANIC_IMMUNITY_MASK = 147,
|
||||
SPELL_AURA_RETAIN_COMBO_POINTS = 148,
|
||||
SPELL_AURA_REDUCE_PUSHBACK = 149, // Reduce Pushback
|
||||
SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT = 150,
|
||||
SPELL_AURA_TRACK_STEALTHED = 151, // Track Stealthed
|
||||
SPELL_AURA_MOD_DETECTED_RANGE = 152, // Mod Detected Range
|
||||
SPELL_AURA_SPLIT_DAMAGE_FLAT = 153, // Split Damage Flat
|
||||
SPELL_AURA_MOD_STEALTH_LEVEL = 154, // Stealth Level Modifier
|
||||
SPELL_AURA_MOD_WATER_BREATHING = 155, // Mod Water Breathing
|
||||
SPELL_AURA_MOD_REPUTATION_GAIN = 156, // Mod Reputation Gain
|
||||
SPELL_AURA_PET_DAMAGE_MULTI = 157, // Mod Pet Damage
|
||||
SPELL_AURA_MOD_SHIELD_BLOCKVALUE = 158,
|
||||
SPELL_AURA_NO_PVP_CREDIT = 159,
|
||||
SPELL_AURA_MOD_AOE_AVOIDANCE = 160,
|
||||
SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT = 161,
|
||||
SPELL_AURA_POWER_BURN = 162,
|
||||
SPELL_AURA_MOD_CRIT_DAMAGE_BONUS = 163,
|
||||
SPELL_AURA_164 = 164,
|
||||
SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS = 165,
|
||||
SPELL_AURA_MOD_ATTACK_POWER_PCT = 166,
|
||||
SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT = 167,
|
||||
SPELL_AURA_MOD_DAMAGE_DONE_VERSUS = 168,
|
||||
SPELL_AURA_MOD_CRIT_PERCENT_VERSUS = 169,
|
||||
SPELL_AURA_DETECT_AMORE = 170,
|
||||
SPELL_AURA_MOD_SPEED_NOT_STACK = 171,
|
||||
SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK = 172,
|
||||
SPELL_AURA_173 = 173, // old SPELL_AURA_ALLOW_CHAMPION_SPELLS
|
||||
SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT = 174, // by defeult intelect, dependent from SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT
|
||||
SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT = 175,
|
||||
SPELL_AURA_SPIRIT_OF_REDEMPTION = 176,
|
||||
SPELL_AURA_AOE_CHARM = 177,
|
||||
SPELL_AURA_MOD_DEBUFF_RESISTANCE = 178,
|
||||
SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE = 179,
|
||||
SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS = 180,
|
||||
SPELL_AURA_181 = 181, // old SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS - possible flat spell crit damage versus
|
||||
SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT = 182,
|
||||
SPELL_AURA_MOD_CRITICAL_THREAT = 183,
|
||||
SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE = 184,
|
||||
SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE = 185,
|
||||
SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE = 186,
|
||||
SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE = 187,
|
||||
SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE = 188,
|
||||
SPELL_AURA_MOD_RATING = 189,
|
||||
SPELL_AURA_MOD_FACTION_REPUTATION_GAIN = 190,
|
||||
SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED = 191,
|
||||
SPELL_AURA_MOD_MELEE_RANGED_HASTE = 192,
|
||||
SPELL_AURA_MELEE_SLOW = 193,
|
||||
SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL = 194,
|
||||
SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL = 195,
|
||||
SPELL_AURA_MOD_COOLDOWN = 196, // only 24818 Noxious Breath
|
||||
SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE = 197,
|
||||
SPELL_AURA_198 = 198, // old SPELL_AURA_MOD_ALL_WEAPON_SKILLS
|
||||
SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT = 199,
|
||||
SPELL_AURA_MOD_XP_PCT = 200,
|
||||
SPELL_AURA_FLY = 201,
|
||||
SPELL_AURA_IGNORE_COMBAT_RESULT = 202,
|
||||
SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE = 203,
|
||||
SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE = 204,
|
||||
SPELL_AURA_MOD_SCHOOL_CRIT_DMG_TAKEN = 205,
|
||||
SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED = 206,
|
||||
SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED = 207,
|
||||
SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED = 208,
|
||||
SPELL_AURA_MOD_MOUNTED_FLIGHT_SPEED_ALWAYS = 209,
|
||||
SPELL_AURA_MOD_VEHICLE_SPEED_ALWAYS = 210,
|
||||
SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK = 211,
|
||||
SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT = 212,
|
||||
SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT = 213,
|
||||
SPELL_AURA_214 = 214,
|
||||
SPELL_AURA_ARENA_PREPARATION = 215,
|
||||
SPELL_AURA_HASTE_SPELLS = 216,
|
||||
SPELL_AURA_MOD_MELEE_HASTE_2 = 217, // NYI
|
||||
SPELL_AURA_HASTE_RANGED = 218,
|
||||
SPELL_AURA_MOD_MANA_REGEN_FROM_STAT = 219,
|
||||
SPELL_AURA_MOD_RATING_FROM_STAT = 220,
|
||||
SPELL_AURA_IGNORED = 221,
|
||||
SPELL_AURA_222 = 222,
|
||||
SPELL_AURA_RAID_PROC_FROM_CHARGE = 223,
|
||||
SPELL_AURA_224 = 224,
|
||||
SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE = 225,
|
||||
SPELL_AURA_PERIODIC_DUMMY = 226,
|
||||
SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE = 227,
|
||||
SPELL_AURA_DETECT_STEALTH = 228,
|
||||
SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE = 229,
|
||||
SPELL_AURA_230 = 230,
|
||||
SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE = 231,
|
||||
SPELL_AURA_MECHANIC_DURATION_MOD = 232,
|
||||
SPELL_AURA_CHANGE_MODEL_FOR_ALL_HUMANOIDS = 233, // client-side only
|
||||
SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK = 234,
|
||||
SPELL_AURA_MOD_DISPEL_RESIST = 235,
|
||||
SPELL_AURA_CONTROL_VEHICLE = 236,
|
||||
SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER = 237,
|
||||
SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER = 238,
|
||||
SPELL_AURA_MOD_SCALE_2 = 239,
|
||||
SPELL_AURA_MOD_EXPERTISE = 240,
|
||||
SPELL_AURA_FORCE_MOVE_FORWARD = 241,
|
||||
SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING = 242,
|
||||
SPELL_AURA_MOD_FACTION = 243,
|
||||
SPELL_AURA_COMPREHEND_LANGUAGE = 244,
|
||||
SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL = 245,
|
||||
SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK = 246,
|
||||
SPELL_AURA_CLONE_CASTER = 247,
|
||||
SPELL_AURA_MOD_COMBAT_RESULT_CHANCE = 248,
|
||||
SPELL_AURA_CONVERT_RUNE = 249,
|
||||
SPELL_AURA_MOD_INCREASE_HEALTH_2 = 250,
|
||||
SPELL_AURA_MOD_ENEMY_DODGE = 251,
|
||||
SPELL_AURA_MOD_SPEED_SLOW_ALL = 252,
|
||||
SPELL_AURA_MOD_BLOCK_CRIT_CHANCE = 253,
|
||||
SPELL_AURA_MOD_DISARM_OFFHAND = 254,
|
||||
SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT = 255,
|
||||
SPELL_AURA_NO_REAGENT_USE = 256,
|
||||
SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS = 257,
|
||||
SPELL_AURA_258 = 258,
|
||||
SPELL_AURA_MOD_HOT_PCT = 259,
|
||||
SPELL_AURA_SCREEN_EFFECT = 260,
|
||||
SPELL_AURA_PHASE = 261,
|
||||
SPELL_AURA_ABILITY_IGNORE_AURASTATE = 262,
|
||||
SPELL_AURA_ALLOW_ONLY_ABILITY = 263,
|
||||
SPELL_AURA_264 = 264,
|
||||
SPELL_AURA_265 = 265,
|
||||
SPELL_AURA_266 = 266,
|
||||
SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL = 267,
|
||||
SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT = 268,
|
||||
SPELL_AURA_MOD_IGNORE_TARGET_RESIST = 269,
|
||||
SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST = 270, // Possibly need swap vs 195 aura used only in 1 spell Chaos Bolt Passive
|
||||
SPELL_AURA_MOD_DAMAGE_FROM_CASTER = 271,
|
||||
SPELL_AURA_IGNORE_MELEE_RESET = 272,
|
||||
SPELL_AURA_X_RAY = 273,
|
||||
SPELL_AURA_ABILITY_CONSUME_NO_AMMO = 274,
|
||||
SPELL_AURA_MOD_IGNORE_SHAPESHIFT = 275,
|
||||
SPELL_AURA_MOD_DAMAGE_DONE_FOR_MECHANIC = 276, // NYI
|
||||
SPELL_AURA_MOD_MAX_AFFECTED_TARGETS = 277,
|
||||
SPELL_AURA_MOD_DISARM_RANGED = 278,
|
||||
SPELL_AURA_INITIALIZE_IMAGES = 279,
|
||||
SPELL_AURA_MOD_ARMOR_PENETRATION_PCT = 280,
|
||||
SPELL_AURA_MOD_HONOR_GAIN_PCT = 281,
|
||||
SPELL_AURA_MOD_BASE_HEALTH_PCT = 282,
|
||||
SPELL_AURA_MOD_HEALING_RECEIVED = 283, // Possibly only for some spell family class spells
|
||||
SPELL_AURA_LINKED = 284,
|
||||
SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR = 285,
|
||||
SPELL_AURA_ABILITY_PERIODIC_CRIT = 286,
|
||||
SPELL_AURA_DEFLECT_SPELLS = 287,
|
||||
SPELL_AURA_IGNORE_HIT_DIRECTION = 288,
|
||||
SPELL_AURA_PREVENT_DURABILITY_LOSS = 289,
|
||||
SPELL_AURA_MOD_CRIT_PCT = 290,
|
||||
SPELL_AURA_MOD_XP_QUEST_PCT = 291,
|
||||
SPELL_AURA_OPEN_STABLE = 292,
|
||||
SPELL_AURA_OVERRIDE_SPELLS = 293,
|
||||
SPELL_AURA_PREVENT_REGENERATE_POWER = 294,
|
||||
SPELL_AURA_295 = 295,
|
||||
SPELL_AURA_SET_VEHICLE_ID = 296,
|
||||
SPELL_AURA_BLOCK_SPELL_FAMILY = 297,
|
||||
SPELL_AURA_STRANGULATE = 298,
|
||||
SPELL_AURA_299 = 299,
|
||||
SPELL_AURA_SHARE_DAMAGE_PCT = 300,
|
||||
SPELL_AURA_SCHOOL_HEAL_ABSORB = 301,
|
||||
SPELL_AURA_302 = 302,
|
||||
SPELL_AURA_MOD_DAMAGE_DONE_VERSUS_AURASTATE = 303,
|
||||
SPELL_AURA_MOD_FAKE_INEBRIATE = 304,
|
||||
SPELL_AURA_MOD_MINIMUM_SPEED = 305,
|
||||
SPELL_AURA_306 = 306,
|
||||
SPELL_AURA_HEAL_ABSORB_TEST = 307,
|
||||
SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER = 308,
|
||||
SPELL_AURA_309 = 309,
|
||||
SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE = 310,
|
||||
SPELL_AURA_311 = 311,
|
||||
SPELL_AURA_312 = 312,
|
||||
SPELL_AURA_313 = 313,
|
||||
SPELL_AURA_PREVENT_RESURRECTION = 314,
|
||||
SPELL_AURA_UNDERWATER_WALKING = 315,
|
||||
SPELL_AURA_PERIODIC_HASTE = 316,
|
||||
TOTAL_AURAS = 317
|
||||
SPELL_AURA_NONE = 0,
|
||||
SPELL_AURA_BIND_SIGHT = 1,
|
||||
SPELL_AURA_MOD_POSSESS = 2,
|
||||
SPELL_AURA_PERIODIC_DAMAGE = 3,
|
||||
SPELL_AURA_DUMMY = 4,
|
||||
SPELL_AURA_MOD_CONFUSE = 5,
|
||||
SPELL_AURA_MOD_CHARM = 6,
|
||||
SPELL_AURA_MOD_FEAR = 7,
|
||||
SPELL_AURA_PERIODIC_HEAL = 8,
|
||||
SPELL_AURA_MOD_ATTACKSPEED = 9,
|
||||
SPELL_AURA_MOD_THREAT = 10,
|
||||
SPELL_AURA_MOD_TAUNT = 11,
|
||||
SPELL_AURA_MOD_STUN = 12,
|
||||
SPELL_AURA_MOD_DAMAGE_DONE = 13,
|
||||
SPELL_AURA_MOD_DAMAGE_TAKEN = 14,
|
||||
SPELL_AURA_DAMAGE_SHIELD = 15,
|
||||
SPELL_AURA_MOD_STEALTH = 16,
|
||||
SPELL_AURA_MOD_STEALTH_DETECT = 17,
|
||||
SPELL_AURA_MOD_INVISIBILITY = 18,
|
||||
SPELL_AURA_MOD_INVISIBILITY_DETECT = 19,
|
||||
SPELL_AURA_OBS_MOD_HEALTH = 20, // unofficial
|
||||
SPELL_AURA_OBS_MOD_POWER = 21, // unofficial
|
||||
SPELL_AURA_MOD_RESISTANCE = 22,
|
||||
SPELL_AURA_PERIODIC_TRIGGER_SPELL = 23,
|
||||
SPELL_AURA_PERIODIC_ENERGIZE = 24,
|
||||
SPELL_AURA_MOD_PACIFY = 25,
|
||||
SPELL_AURA_MOD_ROOT = 26,
|
||||
SPELL_AURA_MOD_SILENCE = 27,
|
||||
SPELL_AURA_REFLECT_SPELLS = 28,
|
||||
SPELL_AURA_MOD_STAT = 29,
|
||||
SPELL_AURA_MOD_SKILL = 30,
|
||||
SPELL_AURA_MOD_INCREASE_SPEED = 31,
|
||||
SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED = 32,
|
||||
SPELL_AURA_MOD_DECREASE_SPEED = 33,
|
||||
SPELL_AURA_MOD_INCREASE_HEALTH = 34,
|
||||
SPELL_AURA_MOD_INCREASE_ENERGY = 35,
|
||||
SPELL_AURA_MOD_SHAPESHIFT = 36,
|
||||
SPELL_AURA_EFFECT_IMMUNITY = 37,
|
||||
SPELL_AURA_STATE_IMMUNITY = 38,
|
||||
SPELL_AURA_SCHOOL_IMMUNITY = 39,
|
||||
SPELL_AURA_DAMAGE_IMMUNITY = 40,
|
||||
SPELL_AURA_DISPEL_IMMUNITY = 41,
|
||||
SPELL_AURA_PROC_TRIGGER_SPELL = 42,
|
||||
SPELL_AURA_PROC_TRIGGER_DAMAGE = 43,
|
||||
SPELL_AURA_TRACK_CREATURES = 44,
|
||||
SPELL_AURA_TRACK_RESOURCES = 45,
|
||||
SPELL_AURA_46 = 46, // Ignore all Gear test spells
|
||||
SPELL_AURA_MOD_PARRY_PERCENT = 47,
|
||||
SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT = 48, // One periodic spell
|
||||
SPELL_AURA_MOD_DODGE_PERCENT = 49,
|
||||
SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT = 50,
|
||||
SPELL_AURA_MOD_BLOCK_PERCENT = 51,
|
||||
SPELL_AURA_MOD_WEAPON_CRIT_PERCENT = 52,
|
||||
SPELL_AURA_PERIODIC_LEECH = 53,
|
||||
SPELL_AURA_MOD_HIT_CHANCE = 54,
|
||||
SPELL_AURA_MOD_SPELL_HIT_CHANCE = 55,
|
||||
SPELL_AURA_TRANSFORM = 56,
|
||||
SPELL_AURA_MOD_SPELL_CRIT_CHANCE = 57,
|
||||
SPELL_AURA_MOD_INCREASE_SWIM_SPEED = 58,
|
||||
SPELL_AURA_MOD_DAMAGE_DONE_CREATURE = 59,
|
||||
SPELL_AURA_MOD_PACIFY_SILENCE = 60,
|
||||
SPELL_AURA_MOD_SCALE = 61,
|
||||
SPELL_AURA_PERIODIC_HEALTH_FUNNEL = 62,
|
||||
SPELL_AURA_63 = 63, // old SPELL_AURA_PERIODIC_MANA_FUNNEL
|
||||
SPELL_AURA_PERIODIC_MANA_LEECH = 64,
|
||||
SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK = 65,
|
||||
SPELL_AURA_FEIGN_DEATH = 66,
|
||||
SPELL_AURA_MOD_DISARM = 67,
|
||||
SPELL_AURA_MOD_STALKED = 68,
|
||||
SPELL_AURA_SCHOOL_ABSORB = 69,
|
||||
SPELL_AURA_EXTRA_ATTACKS = 70,
|
||||
SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL = 71,
|
||||
SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT = 72,
|
||||
SPELL_AURA_MOD_POWER_COST_SCHOOL = 73,
|
||||
SPELL_AURA_REFLECT_SPELLS_SCHOOL = 74,
|
||||
SPELL_AURA_MOD_LANGUAGE = 75,
|
||||
SPELL_AURA_FAR_SIGHT = 76,
|
||||
SPELL_AURA_MECHANIC_IMMUNITY = 77,
|
||||
SPELL_AURA_MOUNTED = 78,
|
||||
SPELL_AURA_MOD_DAMAGE_PERCENT_DONE = 79,
|
||||
SPELL_AURA_MOD_PERCENT_STAT = 80,
|
||||
SPELL_AURA_SPLIT_DAMAGE_PCT = 81,
|
||||
SPELL_AURA_WATER_BREATHING = 82,
|
||||
SPELL_AURA_MOD_BASE_RESISTANCE = 83,
|
||||
SPELL_AURA_MOD_REGEN = 84,
|
||||
SPELL_AURA_MOD_POWER_REGEN = 85,
|
||||
SPELL_AURA_CHANNEL_DEATH_ITEM = 86,
|
||||
SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN = 87,
|
||||
SPELL_AURA_MOD_HEALTH_REGEN_PERCENT = 88,
|
||||
SPELL_AURA_PERIODIC_DAMAGE_PERCENT = 89,
|
||||
SPELL_AURA_90 = 90, // old SPELL_AURA_MOD_RESIST_CHANCE
|
||||
SPELL_AURA_MOD_DETECT_RANGE = 91,
|
||||
SPELL_AURA_PREVENTS_FLEEING = 92,
|
||||
SPELL_AURA_MOD_UNATTACKABLE = 93,
|
||||
SPELL_AURA_INTERRUPT_REGEN = 94,
|
||||
SPELL_AURA_GHOST = 95,
|
||||
SPELL_AURA_SPELL_MAGNET = 96,
|
||||
SPELL_AURA_MANA_SHIELD = 97,
|
||||
SPELL_AURA_MOD_SKILL_TALENT = 98,
|
||||
SPELL_AURA_MOD_ATTACK_POWER = 99,
|
||||
SPELL_AURA_AURAS_VISIBLE = 100,
|
||||
SPELL_AURA_MOD_RESISTANCE_PCT = 101,
|
||||
SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS = 102,
|
||||
SPELL_AURA_MOD_TOTAL_THREAT = 103,
|
||||
SPELL_AURA_WATER_WALK = 104,
|
||||
SPELL_AURA_FEATHER_FALL = 105,
|
||||
SPELL_AURA_HOVER = 106,
|
||||
SPELL_AURA_ADD_FLAT_MODIFIER = 107,
|
||||
SPELL_AURA_ADD_PCT_MODIFIER = 108,
|
||||
SPELL_AURA_ADD_TARGET_TRIGGER = 109,
|
||||
SPELL_AURA_MOD_POWER_REGEN_PERCENT = 110,
|
||||
SPELL_AURA_ADD_CASTER_HIT_TRIGGER = 111,
|
||||
SPELL_AURA_OVERRIDE_CLASS_SCRIPTS = 112,
|
||||
SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN = 113,
|
||||
SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT = 114,
|
||||
SPELL_AURA_MOD_HEALING = 115,
|
||||
SPELL_AURA_MOD_REGEN_DURING_COMBAT = 116,
|
||||
SPELL_AURA_MOD_MECHANIC_RESISTANCE = 117,
|
||||
SPELL_AURA_MOD_HEALING_PCT = 118,
|
||||
SPELL_AURA_119 = 119, // old SPELL_AURA_SHARE_PET_TRACKING
|
||||
SPELL_AURA_UNTRACKABLE = 120,
|
||||
SPELL_AURA_EMPATHY = 121,
|
||||
SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT = 122,
|
||||
SPELL_AURA_MOD_TARGET_RESISTANCE = 123,
|
||||
SPELL_AURA_MOD_RANGED_ATTACK_POWER = 124,
|
||||
SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN = 125,
|
||||
SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT = 126,
|
||||
SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS = 127,
|
||||
SPELL_AURA_MOD_POSSESS_PET = 128,
|
||||
SPELL_AURA_MOD_SPEED_ALWAYS = 129,
|
||||
SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS = 130,
|
||||
SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS = 131,
|
||||
SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT = 132,
|
||||
SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT = 133,
|
||||
SPELL_AURA_MOD_MANA_REGEN_INTERRUPT = 134,
|
||||
SPELL_AURA_MOD_HEALING_DONE = 135,
|
||||
SPELL_AURA_MOD_HEALING_DONE_PERCENT = 136,
|
||||
SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE = 137,
|
||||
SPELL_AURA_MOD_MELEE_HASTE = 138,
|
||||
SPELL_AURA_FORCE_REACTION = 139,
|
||||
SPELL_AURA_MOD_RANGED_HASTE = 140,
|
||||
SPELL_AURA_MOD_RANGED_AMMO_HASTE = 141,
|
||||
SPELL_AURA_MOD_BASE_RESISTANCE_PCT = 142,
|
||||
SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE = 143,
|
||||
SPELL_AURA_SAFE_FALL = 144,
|
||||
SPELL_AURA_MOD_PET_TALENT_POINTS = 145,
|
||||
SPELL_AURA_ALLOW_TAME_PET_TYPE = 146,
|
||||
SPELL_AURA_MECHANIC_IMMUNITY_MASK = 147,
|
||||
SPELL_AURA_RETAIN_COMBO_POINTS = 148,
|
||||
SPELL_AURA_REDUCE_PUSHBACK = 149, // Reduce Pushback
|
||||
SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT = 150,
|
||||
SPELL_AURA_TRACK_STEALTHED = 151, // Track Stealthed
|
||||
SPELL_AURA_MOD_DETECTED_RANGE = 152, // Mod Detected Range
|
||||
SPELL_AURA_SPLIT_DAMAGE_FLAT = 153, // Split Damage Flat
|
||||
SPELL_AURA_MOD_STEALTH_LEVEL = 154, // Stealth Level Modifier
|
||||
SPELL_AURA_MOD_WATER_BREATHING = 155, // Mod Water Breathing
|
||||
SPELL_AURA_MOD_REPUTATION_GAIN = 156, // Mod Reputation Gain
|
||||
SPELL_AURA_PET_DAMAGE_MULTI = 157, // Mod Pet Damage
|
||||
SPELL_AURA_MOD_SHIELD_BLOCKVALUE = 158,
|
||||
SPELL_AURA_NO_PVP_CREDIT = 159,
|
||||
SPELL_AURA_MOD_AOE_AVOIDANCE = 160,
|
||||
SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT = 161,
|
||||
SPELL_AURA_POWER_BURN = 162,
|
||||
SPELL_AURA_MOD_CRIT_DAMAGE_BONUS = 163,
|
||||
SPELL_AURA_164 = 164,
|
||||
SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS = 165,
|
||||
SPELL_AURA_MOD_ATTACK_POWER_PCT = 166,
|
||||
SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT = 167,
|
||||
SPELL_AURA_MOD_DAMAGE_DONE_VERSUS = 168,
|
||||
SPELL_AURA_MOD_CRIT_PERCENT_VERSUS = 169,
|
||||
SPELL_AURA_DETECT_AMORE = 170,
|
||||
SPELL_AURA_MOD_SPEED_NOT_STACK = 171,
|
||||
SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK = 172,
|
||||
SPELL_AURA_173 = 173, // old SPELL_AURA_ALLOW_CHAMPION_SPELLS
|
||||
SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT = 174, // by defeult intelect, dependent from SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT
|
||||
SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT = 175,
|
||||
SPELL_AURA_SPIRIT_OF_REDEMPTION = 176,
|
||||
SPELL_AURA_AOE_CHARM = 177,
|
||||
SPELL_AURA_MOD_DEBUFF_RESISTANCE = 178,
|
||||
SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE = 179,
|
||||
SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS = 180,
|
||||
SPELL_AURA_181 = 181, // old SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS - possible flat spell crit damage versus
|
||||
SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT = 182,
|
||||
SPELL_AURA_MOD_CRITICAL_THREAT = 183,
|
||||
SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE = 184,
|
||||
SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE = 185,
|
||||
SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE = 186,
|
||||
SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE = 187,
|
||||
SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE = 188,
|
||||
SPELL_AURA_MOD_RATING = 189,
|
||||
SPELL_AURA_MOD_FACTION_REPUTATION_GAIN = 190,
|
||||
SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED = 191,
|
||||
SPELL_AURA_MOD_MELEE_RANGED_HASTE = 192,
|
||||
SPELL_AURA_MELEE_SLOW = 193,
|
||||
SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL = 194,
|
||||
SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL = 195,
|
||||
SPELL_AURA_MOD_COOLDOWN = 196, // only 24818 Noxious Breath
|
||||
SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE = 197,
|
||||
SPELL_AURA_198 = 198, // old SPELL_AURA_MOD_ALL_WEAPON_SKILLS
|
||||
SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT = 199,
|
||||
SPELL_AURA_MOD_XP_PCT = 200,
|
||||
SPELL_AURA_FLY = 201,
|
||||
SPELL_AURA_IGNORE_COMBAT_RESULT = 202,
|
||||
SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE = 203,
|
||||
SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE = 204,
|
||||
SPELL_AURA_MOD_SCHOOL_CRIT_DMG_TAKEN = 205,
|
||||
SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED = 206,
|
||||
SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED = 207,
|
||||
SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED = 208,
|
||||
SPELL_AURA_MOD_MOUNTED_FLIGHT_SPEED_ALWAYS = 209,
|
||||
SPELL_AURA_MOD_VEHICLE_SPEED_ALWAYS = 210,
|
||||
SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK = 211,
|
||||
SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT = 212,
|
||||
SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT = 213,
|
||||
SPELL_AURA_214 = 214,
|
||||
SPELL_AURA_ARENA_PREPARATION = 215,
|
||||
SPELL_AURA_HASTE_SPELLS = 216,
|
||||
SPELL_AURA_MOD_MELEE_HASTE_2 = 217, // NYI
|
||||
SPELL_AURA_HASTE_RANGED = 218,
|
||||
SPELL_AURA_MOD_MANA_REGEN_FROM_STAT = 219,
|
||||
SPELL_AURA_MOD_RATING_FROM_STAT = 220,
|
||||
SPELL_AURA_IGNORED = 221,
|
||||
SPELL_AURA_222 = 222,
|
||||
SPELL_AURA_RAID_PROC_FROM_CHARGE = 223,
|
||||
SPELL_AURA_224 = 224,
|
||||
SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE = 225,
|
||||
SPELL_AURA_PERIODIC_DUMMY = 226,
|
||||
SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE = 227,
|
||||
SPELL_AURA_DETECT_STEALTH = 228,
|
||||
SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE = 229,
|
||||
SPELL_AURA_230 = 230,
|
||||
SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE = 231,
|
||||
SPELL_AURA_MECHANIC_DURATION_MOD = 232,
|
||||
SPELL_AURA_CHANGE_MODEL_FOR_ALL_HUMANOIDS = 233, // client-side only
|
||||
SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK = 234,
|
||||
SPELL_AURA_MOD_DISPEL_RESIST = 235,
|
||||
SPELL_AURA_CONTROL_VEHICLE = 236,
|
||||
SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER = 237,
|
||||
SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER = 238,
|
||||
SPELL_AURA_MOD_SCALE_2 = 239,
|
||||
SPELL_AURA_MOD_EXPERTISE = 240,
|
||||
SPELL_AURA_FORCE_MOVE_FORWARD = 241,
|
||||
SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING = 242,
|
||||
SPELL_AURA_MOD_FACTION = 243,
|
||||
SPELL_AURA_COMPREHEND_LANGUAGE = 244,
|
||||
SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL = 245,
|
||||
SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK = 246,
|
||||
SPELL_AURA_CLONE_CASTER = 247,
|
||||
SPELL_AURA_MOD_COMBAT_RESULT_CHANCE = 248,
|
||||
SPELL_AURA_CONVERT_RUNE = 249,
|
||||
SPELL_AURA_MOD_INCREASE_HEALTH_2 = 250,
|
||||
SPELL_AURA_MOD_ENEMY_DODGE = 251,
|
||||
SPELL_AURA_MOD_SPEED_SLOW_ALL = 252,
|
||||
SPELL_AURA_MOD_BLOCK_CRIT_CHANCE = 253,
|
||||
SPELL_AURA_MOD_DISARM_OFFHAND = 254,
|
||||
SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT = 255,
|
||||
SPELL_AURA_NO_REAGENT_USE = 256,
|
||||
SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS = 257,
|
||||
SPELL_AURA_258 = 258,
|
||||
SPELL_AURA_MOD_HOT_PCT = 259,
|
||||
SPELL_AURA_SCREEN_EFFECT = 260,
|
||||
SPELL_AURA_PHASE = 261,
|
||||
SPELL_AURA_ABILITY_IGNORE_AURASTATE = 262,
|
||||
SPELL_AURA_ALLOW_ONLY_ABILITY = 263,
|
||||
SPELL_AURA_264 = 264,
|
||||
SPELL_AURA_265 = 265,
|
||||
SPELL_AURA_266 = 266,
|
||||
SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL = 267,
|
||||
SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT = 268,
|
||||
SPELL_AURA_MOD_IGNORE_TARGET_RESIST = 269,
|
||||
SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST = 270, // Possibly need swap vs 195 aura used only in 1 spell Chaos Bolt Passive
|
||||
SPELL_AURA_MOD_DAMAGE_FROM_CASTER = 271,
|
||||
SPELL_AURA_IGNORE_MELEE_RESET = 272,
|
||||
SPELL_AURA_X_RAY = 273,
|
||||
SPELL_AURA_ABILITY_CONSUME_NO_AMMO = 274,
|
||||
SPELL_AURA_MOD_IGNORE_SHAPESHIFT = 275,
|
||||
SPELL_AURA_MOD_DAMAGE_DONE_FOR_MECHANIC = 276, // NYI
|
||||
SPELL_AURA_MOD_MAX_AFFECTED_TARGETS = 277,
|
||||
SPELL_AURA_MOD_DISARM_RANGED = 278,
|
||||
SPELL_AURA_INITIALIZE_IMAGES = 279,
|
||||
SPELL_AURA_MOD_ARMOR_PENETRATION_PCT = 280,
|
||||
SPELL_AURA_MOD_HONOR_GAIN_PCT = 281,
|
||||
SPELL_AURA_MOD_BASE_HEALTH_PCT = 282,
|
||||
SPELL_AURA_MOD_HEALING_RECEIVED = 283, // Possibly only for some spell family class spells
|
||||
SPELL_AURA_LINKED = 284,
|
||||
SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR = 285,
|
||||
SPELL_AURA_ABILITY_PERIODIC_CRIT = 286,
|
||||
SPELL_AURA_DEFLECT_SPELLS = 287,
|
||||
SPELL_AURA_IGNORE_HIT_DIRECTION = 288,
|
||||
SPELL_AURA_PREVENT_DURABILITY_LOSS = 289,
|
||||
SPELL_AURA_MOD_CRIT_PCT = 290,
|
||||
SPELL_AURA_MOD_XP_QUEST_PCT = 291,
|
||||
SPELL_AURA_OPEN_STABLE = 292,
|
||||
SPELL_AURA_OVERRIDE_SPELLS = 293,
|
||||
SPELL_AURA_PREVENT_REGENERATE_POWER = 294,
|
||||
SPELL_AURA_295 = 295,
|
||||
SPELL_AURA_SET_VEHICLE_ID = 296,
|
||||
SPELL_AURA_BLOCK_SPELL_FAMILY = 297,
|
||||
SPELL_AURA_STRANGULATE = 298,
|
||||
SPELL_AURA_299 = 299,
|
||||
SPELL_AURA_SHARE_DAMAGE_PCT = 300,
|
||||
SPELL_AURA_SCHOOL_HEAL_ABSORB = 301,
|
||||
SPELL_AURA_302 = 302,
|
||||
SPELL_AURA_MOD_DAMAGE_DONE_VERSUS_AURASTATE = 303,
|
||||
SPELL_AURA_MOD_FAKE_INEBRIATE = 304,
|
||||
SPELL_AURA_MOD_MINIMUM_SPEED = 305,
|
||||
SPELL_AURA_306 = 306,
|
||||
SPELL_AURA_HEAL_ABSORB_TEST = 307,
|
||||
SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER = 308,
|
||||
SPELL_AURA_309 = 309,
|
||||
SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE = 310,
|
||||
SPELL_AURA_311 = 311,
|
||||
SPELL_AURA_312 = 312,
|
||||
SPELL_AURA_313 = 313,
|
||||
SPELL_AURA_PREVENT_RESURRECTION = 314,
|
||||
SPELL_AURA_UNDERWATER_WALKING = 315,
|
||||
SPELL_AURA_PERIODIC_HASTE = 316,
|
||||
TOTAL_AURAS = 317
|
||||
};
|
||||
|
||||
enum AuraObjectType
|
||||
@@ -388,11 +388,11 @@ enum AuraObjectType
|
||||
|
||||
enum AuraRemoveMode
|
||||
{
|
||||
AURA_REMOVE_NONE = 0,
|
||||
AURA_REMOVE_BY_DEFAULT = 1, // scripted remove, remove by stack with aura with different ids and sc aura remove
|
||||
AURA_REMOVE_NONE = 0,
|
||||
AURA_REMOVE_BY_DEFAULT = 1, // scripted remove, remove by stack with aura with different ids and sc aura remove
|
||||
AURA_REMOVE_BY_CANCEL,
|
||||
AURA_REMOVE_BY_ENEMY_SPELL, // dispel and absorb aura destroy
|
||||
AURA_REMOVE_BY_EXPIRE, // aura duration has ended
|
||||
AURA_REMOVE_BY_ENEMY_SPELL, // dispel and absorb aura destroy
|
||||
AURA_REMOVE_BY_EXPIRE, // aura duration has ended
|
||||
AURA_REMOVE_BY_DEATH
|
||||
};
|
||||
|
||||
|
||||
@@ -3555,9 +3555,13 @@ SpellCastResult Spell::prepare(SpellCastTargets const* targets, AuraEffect const
|
||||
// (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
|
||||
if ((m_spellInfo->IsChanneled() || m_casttime) && m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->isMoving() && m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT && !IsTriggered())
|
||||
{
|
||||
SendCastResult(SPELL_FAILED_MOVING);
|
||||
finish(false);
|
||||
return SPELL_FAILED_MOVING;
|
||||
// 1. Has casttime, 2. Or doesn't have flag to allow action during channel
|
||||
if (m_casttime || !m_spellInfo->IsActionAllowedChannel())
|
||||
{
|
||||
SendCastResult(SPELL_FAILED_MOVING);
|
||||
finish(false);
|
||||
return SPELL_FAILED_MOVING;
|
||||
}
|
||||
}
|
||||
|
||||
// xinef: if spell have nearby target entry only, do not allow to cast if no targets are found
|
||||
|
||||
@@ -4401,6 +4401,23 @@ void Spell::EffectApplyGlyph(SpellEffIndex effIndex)
|
||||
if (GlyphPropertiesEntry const* oldGlyphEntry = sGlyphPropertiesStore.LookupEntry(oldGlyph))
|
||||
{
|
||||
player->RemoveAurasDueToSpell(oldGlyphEntry->SpellId);
|
||||
|
||||
// Removed any triggered auras
|
||||
Unit::AuraMap& ownedAuras = player->GetOwnedAuras();
|
||||
for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
|
||||
{
|
||||
Aura* aura = iter->second;
|
||||
if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
|
||||
{
|
||||
if (triggeredByAuraSpellInfo->Id == oldGlyphEntry->SpellId)
|
||||
{
|
||||
player->RemoveOwnedAura(iter);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
|
||||
player->SendLearnPacket(oldGlyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
|
||||
}
|
||||
|
||||
|
||||
@@ -1241,7 +1241,7 @@ bool SpellInfo::IsChanneled() const
|
||||
return (AttributesEx & (SPELL_ATTR1_IS_CHANNELED | SPELL_ATTR1_IS_SELF_CHANNELED));
|
||||
}
|
||||
|
||||
bool SpellInfo::IsMoveAllowedChannel() const
|
||||
bool SpellInfo::IsActionAllowedChannel() const
|
||||
{
|
||||
return IsChanneled() && HasAttribute(SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL);
|
||||
}
|
||||
|
||||
@@ -457,7 +457,7 @@ public:
|
||||
bool IsPositive() const;
|
||||
bool IsPositiveEffect(uint8 effIndex) const;
|
||||
bool IsChanneled() const;
|
||||
[[nodiscard]] bool IsMoveAllowedChannel() const;
|
||||
[[nodiscard]] bool IsActionAllowedChannel() const;
|
||||
bool NeedsComboPoints() const;
|
||||
bool IsBreakingStealth() const;
|
||||
bool IsRangedWeaponSpell() const;
|
||||
|
||||
@@ -4295,6 +4295,34 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
spellInfo->Dispel = DISPEL_NONE;
|
||||
});
|
||||
|
||||
// Summon Nightmare Illusions
|
||||
ApplySpellFix({ 24681, 24728, 24729 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->Effects[EFFECT_0].MiscValueB = 64;
|
||||
});
|
||||
|
||||
// Blood Siphon
|
||||
ApplySpellFix({ 24322, 24323 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_MOD_STUN;
|
||||
spellInfo->Effects[EFFECT_2].Effect = 0;
|
||||
spellInfo->Attributes |= SPELL_ATTR0_NO_AURA_CANCEL;
|
||||
spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL;
|
||||
spellInfo->ChannelInterruptFlags &= ~AURA_INTERRUPT_FLAG_MOVE;
|
||||
});
|
||||
|
||||
// Place Fake Fur
|
||||
ApplySpellFix({ 46085 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->Effects[EFFECT_0].MiscValue = 8;
|
||||
});
|
||||
|
||||
// Smash Mammoth Trap
|
||||
ApplySpellFix({ 46201 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->Effects[EFFECT_0].MiscValue = 8;
|
||||
});
|
||||
|
||||
for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
|
||||
{
|
||||
SpellInfo* spellInfo = mSpellInfoMap[i];
|
||||
|
||||
@@ -27,8 +27,8 @@ class ChatHandler;
|
||||
// from blizzard lua
|
||||
enum GMTicketSystemStatus
|
||||
{
|
||||
GMTICKET_QUEUE_STATUS_DISABLED = 0,
|
||||
GMTICKET_QUEUE_STATUS_ENABLED = 1
|
||||
GMTICKET_QUEUE_STATUS_DISABLED = 0,
|
||||
GMTICKET_QUEUE_STATUS_ENABLED = 1
|
||||
};
|
||||
|
||||
enum GMTicketStatus
|
||||
@@ -48,9 +48,9 @@ enum GMTicketResponse
|
||||
};
|
||||
|
||||
// from Blizzard LUA:
|
||||
// GMTICKET_ASSIGNEDTOGM_STATUS_NOT_ASSIGNED = 0; -- ticket is not currently assigned to a gm
|
||||
// GMTICKET_ASSIGNEDTOGM_STATUS_ASSIGNED = 1; -- ticket is assigned to a normal gm
|
||||
// GMTICKET_ASSIGNEDTOGM_STATUS_ESCALATED = 2; -- ticket is in the escalation queue
|
||||
// GMTICKET_ASSIGNEDTOGM_STATUS_NOT_ASSIGNED = 0; -- ticket is not currently assigned to a gm
|
||||
// GMTICKET_ASSIGNEDTOGM_STATUS_ASSIGNED = 1; -- ticket is assigned to a normal gm
|
||||
// GMTICKET_ASSIGNEDTOGM_STATUS_ESCALATED = 2; -- ticket is in the escalation queue
|
||||
// 3 is a custom value and should never actually be sent
|
||||
enum GMTicketEscalationStatus
|
||||
{
|
||||
@@ -63,25 +63,25 @@ enum GMTicketEscalationStatus
|
||||
// from blizzard lua
|
||||
enum GMTicketOpenedByGMStatus
|
||||
{
|
||||
GMTICKET_OPENEDBYGM_STATUS_NOT_OPENED = 0, // ticket has never been opened by a gm
|
||||
GMTICKET_OPENEDBYGM_STATUS_OPENED = 1 // ticket has been opened by a gm
|
||||
GMTICKET_OPENEDBYGM_STATUS_NOT_OPENED = 0, // ticket has never been opened by a gm
|
||||
GMTICKET_OPENEDBYGM_STATUS_OPENED = 1 // ticket has been opened by a gm
|
||||
};
|
||||
|
||||
enum LagReportType
|
||||
{
|
||||
LAG_REPORT_TYPE_LOOT = 1,
|
||||
LAG_REPORT_TYPE_AUCTION_HOUSE = 2,
|
||||
LAG_REPORT_TYPE_MAIL = 3,
|
||||
LAG_REPORT_TYPE_CHAT = 4,
|
||||
LAG_REPORT_TYPE_MOVEMENT = 5,
|
||||
LAG_REPORT_TYPE_SPELL = 6
|
||||
LAG_REPORT_TYPE_LOOT = 1,
|
||||
LAG_REPORT_TYPE_AUCTION_HOUSE = 2,
|
||||
LAG_REPORT_TYPE_MAIL = 3,
|
||||
LAG_REPORT_TYPE_CHAT = 4,
|
||||
LAG_REPORT_TYPE_MOVEMENT = 5,
|
||||
LAG_REPORT_TYPE_SPELL = 6
|
||||
};
|
||||
|
||||
enum TicketType
|
||||
{
|
||||
TICKET_TYPE_OPEN = 0,
|
||||
TICKET_TYPE_CLOSED = 1,
|
||||
TICKET_TYPE_CHARACTER_DELETED = 2,
|
||||
TICKET_TYPE_OPEN = 0,
|
||||
TICKET_TYPE_CLOSED = 1,
|
||||
TICKET_TYPE_CHARACTER_DELETED = 2,
|
||||
};
|
||||
|
||||
class GmTicket
|
||||
|
||||
@@ -402,6 +402,7 @@ enum WorldIntConfigs
|
||||
CONFIG_LFG_MAX_KICK_COUNT,
|
||||
CONFIG_LFG_KICK_PREVENTION_TIMER,
|
||||
CONFIG_CHANGE_FACTION_MAX_MONEY,
|
||||
CONFIG_WATER_BREATH_TIMER,
|
||||
INT_CONFIG_VALUE_COUNT
|
||||
};
|
||||
|
||||
|
||||
@@ -1185,11 +1185,11 @@ void World::LoadConfigSettings(bool reload)
|
||||
m_bool_configs[CONFIG_OFFHAND_CHECK_AT_SPELL_UNLEARN] = sConfigMgr->GetOption<bool>("OffhandCheckAtSpellUnlearn", true);
|
||||
m_int_configs[CONFIG_CREATURE_STOP_FOR_PLAYER] = sConfigMgr->GetOption<uint32>("Creature.MovingStopTimeForPlayer", 3 * MINUTE * IN_MILLISECONDS);
|
||||
|
||||
m_float_configs[CONFIG_WATER_BREATH_TIMER] = sConfigMgr->GetOption<float>("WaterBreath.Timer", 3.0f);
|
||||
if (m_float_configs[CONFIG_WATER_BREATH_TIMER] <= 0)
|
||||
m_int_configs[CONFIG_WATER_BREATH_TIMER] = sConfigMgr->GetOption<uint32>("WaterBreath.Timer", 180000);
|
||||
if (m_int_configs[CONFIG_WATER_BREATH_TIMER] <= 0)
|
||||
{
|
||||
LOG_ERROR("server.loading", "WaterBreath.Timer ({}) must be > 0. Using 3 instead.", m_float_configs[CONFIG_WATER_BREATH_TIMER]);
|
||||
m_float_configs[CONFIG_WATER_BREATH_TIMER] = 3;
|
||||
LOG_ERROR("server.loading", "WaterBreath.Timer ({}) must be > 0. Using 180000 instead.", m_int_configs[CONFIG_WATER_BREATH_TIMER]);
|
||||
m_int_configs[CONFIG_WATER_BREATH_TIMER] = 180000;
|
||||
}
|
||||
|
||||
if (int32 clientCacheId = sConfigMgr->GetOption<int32>("ClientCacheVersion", 0))
|
||||
@@ -2655,13 +2655,17 @@ void World::SendGMText(uint32 string_id, ...)
|
||||
Acore::LocalizedPacketListDo<Acore::WorldWorldTextBuilder> wt_do(wt_builder);
|
||||
for (SessionMap::iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
|
||||
{
|
||||
if (!itr->second || !itr->second->GetPlayer() || !itr->second->GetPlayer()->IsInWorld())
|
||||
// Session should have permissions to receive global gm messages
|
||||
WorldSession* session = itr->second;
|
||||
if (!session || AccountMgr::IsPlayerAccount(session->GetSecurity()))
|
||||
continue;
|
||||
|
||||
if (AccountMgr::IsPlayerAccount(itr->second->GetSecurity()))
|
||||
// Player should be in world
|
||||
Player* player = session->GetPlayer();
|
||||
if (!player || !player->IsInWorld())
|
||||
continue;
|
||||
|
||||
wt_do(itr->second->GetPlayer());
|
||||
wt_do(session->GetPlayer());
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
|
||||
@@ -58,7 +58,8 @@ public:
|
||||
{ "cinematic", HandleDebugPlayCinematicCommand, SEC_ADMINISTRATOR, Console::No },
|
||||
{ "movie", HandleDebugPlayMovieCommand, SEC_ADMINISTRATOR, Console::No },
|
||||
{ "sound", HandleDebugPlaySoundCommand, SEC_ADMINISTRATOR, Console::No },
|
||||
{ "music", HandleDebugPlayMusicCommand, SEC_ADMINISTRATOR, Console::No }
|
||||
{ "music", HandleDebugPlayMusicCommand, SEC_ADMINISTRATOR, Console::No },
|
||||
{ "visual", HandleDebugVisualCommand, SEC_ADMINISTRATOR, Console::No }
|
||||
};
|
||||
static ChatCommandTable debugSendCommandTable =
|
||||
{
|
||||
@@ -203,6 +204,28 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleDebugVisualCommand(ChatHandler* handler, uint32 visualId)
|
||||
{
|
||||
if (!visualId)
|
||||
{
|
||||
handler->SendSysMessage(LANG_BAD_VALUE);
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
Player* player = handler->GetPlayer();
|
||||
Unit* target = handler->getSelectedUnit();
|
||||
|
||||
if (!target)
|
||||
{
|
||||
player->SendPlaySpellVisual(visualId);
|
||||
return true;
|
||||
}
|
||||
|
||||
player->SendPlaySpellImpact(target->GetGUID(), visualId);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleDebugSendSpellFailCommand(ChatHandler* handler, SpellCastResult result, Optional<uint32> failArg1, Optional<uint32> failArg2)
|
||||
{
|
||||
WorldPacket data(SMSG_CAST_FAILED, 5);
|
||||
|
||||
@@ -88,9 +88,11 @@ public:
|
||||
*
|
||||
* Example Usage:
|
||||
* @code
|
||||
* .deserter instance add 1h30m
|
||||
* .deserter instance add 1h30m (using player target or self)
|
||||
* -or-
|
||||
* .deserter bg add 1h30m
|
||||
* .deserter bg add 1h30m (using player target or self)
|
||||
* -or-
|
||||
* .deserter bg add Tester 1h30m (using player of name 'Tester')
|
||||
* @endcode
|
||||
*/
|
||||
static bool HandleDeserterAdd(ChatHandler* handler, Optional<std::string> playerName, Optional<std::string> time, bool isInstance)
|
||||
@@ -156,16 +158,18 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 deserterSpell = isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER;
|
||||
|
||||
if (target)
|
||||
{
|
||||
Aura* aura = target->GetAura(isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER);
|
||||
Aura* aura = target->GetAura(deserterSpell);
|
||||
if (aura && aura->GetDuration() >= duration * IN_MILLISECONDS)
|
||||
{
|
||||
handler->PSendSysMessage("Player %s already has a longer %s Deserter active.", handler->playerLink(*playerName), isInstance ? "Instance" : "Battleground");
|
||||
return true;
|
||||
}
|
||||
|
||||
aura = target->AddAura(isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER, target);
|
||||
aura = target->AddAura(deserterSpell, target);
|
||||
if (!aura)
|
||||
{
|
||||
handler->SendSysMessage(LANG_BAD_VALUE);
|
||||
@@ -173,44 +177,45 @@ public:
|
||||
return false;
|
||||
}
|
||||
aura->SetDuration(duration * IN_MILLISECONDS);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int32 remainTime = 0;
|
||||
if (QueryResult result = CharacterDatabase.Query("SELECT remainTime FROM character_aura WHERE guid = {} AND spell = {}", guid.GetCounter(), isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER))
|
||||
else
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
remainTime = fields[0].Get<int32>();
|
||||
|
||||
if (remainTime < 0 || remainTime >= duration * IN_MILLISECONDS)
|
||||
int32 remainTime = 0;
|
||||
if (QueryResult result = CharacterDatabase.Query("SELECT remainTime FROM character_aura WHERE guid = {} AND spell = {}", guid.GetCounter(), deserterSpell))
|
||||
{
|
||||
handler->PSendSysMessage("Player %s already has a longer %s Deserter active.", handler->playerLink(*playerName), isInstance ? "Instance" : "Battleground");
|
||||
return true;
|
||||
Field* fields = result->Fetch();
|
||||
remainTime = fields[0].Get<int32>();
|
||||
|
||||
if (remainTime < 0 || remainTime >= duration * IN_MILLISECONDS)
|
||||
{
|
||||
handler->PSendSysMessage("Player %s already has a longer %s Deserter active.", handler->playerLink(*playerName), isInstance ? "Instance" : "Battleground");
|
||||
return true;
|
||||
}
|
||||
CharacterDatabase.Query("DELETE FROM character_aura WHERE guid = {} AND spell = {}", guid.GetCounter(), deserterSpell);
|
||||
}
|
||||
CharacterDatabase.Query("DELETE FROM character_aura WHERE guid = {} AND spell = {}", guid.GetCounter(), isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER);
|
||||
|
||||
uint8 index = 0;
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_AURA);
|
||||
stmt->SetData(index++, guid.GetCounter());
|
||||
stmt->SetData(index++, guid.GetCounter());
|
||||
stmt->SetData(index++, 0);
|
||||
stmt->SetData(index++, deserterSpell);
|
||||
stmt->SetData(index++, 1);
|
||||
stmt->SetData(index++, 1);
|
||||
stmt->SetData(index++, 1);
|
||||
stmt->SetData(index++, 0);
|
||||
stmt->SetData(index++, 0);
|
||||
stmt->SetData(index++, 0);
|
||||
stmt->SetData(index++, 0);
|
||||
stmt->SetData(index++, 0);
|
||||
stmt->SetData(index++, 0);
|
||||
stmt->SetData(index++, isInstance ? 1800000 : 900000);
|
||||
stmt->SetData(index++, duration * IN_MILLISECONDS);
|
||||
stmt->SetData(index, 0);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
|
||||
uint8 index = 0;
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_AURA);
|
||||
stmt->SetData(index++, guid.GetCounter());
|
||||
stmt->SetData(index++, guid.GetCounter());
|
||||
stmt->SetData(index++, 0);
|
||||
stmt->SetData(index++, isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER);
|
||||
stmt->SetData(index++, 1);
|
||||
stmt->SetData(index++, 1);
|
||||
stmt->SetData(index++, 1);
|
||||
stmt->SetData(index++, 0);
|
||||
stmt->SetData(index++, 0);
|
||||
stmt->SetData(index++, 0);
|
||||
stmt->SetData(index++, 0);
|
||||
stmt->SetData(index++, 0);
|
||||
stmt->SetData(index++, 0);
|
||||
stmt->SetData(index++, isInstance ? 1800000 : 900000);
|
||||
stmt->SetData(index++, duration * 1000);
|
||||
stmt->SetData(index, 0);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
|
||||
handler->PSendSysMessage("%s of %s Deserter has been added to player %s.", secsToTimeString(duration), isInstance ? "Instance" : "Battleground", handler->playerLink(*playerName));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -221,6 +226,7 @@ public:
|
||||
* selected player.
|
||||
*
|
||||
* @param handler The ChatHandler, passed by the system.
|
||||
* @param player The target player, either by name, the target or self
|
||||
* @param isInstance provided by the relaying functions, so we don't have
|
||||
* to write that much code :)
|
||||
*
|
||||
@@ -228,9 +234,11 @@ public:
|
||||
*
|
||||
* Example Usage:
|
||||
* @code
|
||||
* .deserter instance remove
|
||||
* .deserter instance remove (using player target or self)
|
||||
* -or-
|
||||
* .deserter bg remove
|
||||
* .deserter bg remove (using player target or self)
|
||||
* -or-
|
||||
* .deserter bg remove Tester (using player of name 'Tester')
|
||||
* @endcode
|
||||
*/
|
||||
static bool HandleDeserterRemove(ChatHandler* handler, Optional<PlayerIdentifier> player, bool isInstance)
|
||||
@@ -248,21 +256,75 @@ public:
|
||||
}
|
||||
|
||||
Player* target = player->GetConnectedPlayer();
|
||||
uint32 deserterSpell = isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER;
|
||||
int32 duration = 0;
|
||||
|
||||
if (target)
|
||||
{
|
||||
target->RemoveAura(isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER);
|
||||
if (Aura* aura = target->GetAura(deserterSpell))
|
||||
{
|
||||
duration = aura->GetDuration();
|
||||
target->RemoveAura(deserterSpell);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (QueryResult result = CharacterDatabase.Query("SELECT remainTime FROM character_aura WHERE guid = {} AND spell = {}", player->GetGUID().GetCounter(), deserterSpell))
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
duration = fields[0].Get<int32>();
|
||||
CharacterDatabase.Execute("DELETE FROM character_aura WHERE guid = {} AND spell = {}", player->GetGUID().GetCounter(), deserterSpell);
|
||||
}
|
||||
}
|
||||
|
||||
if (duration == 0)
|
||||
{
|
||||
handler->PSendSysMessage("Player %s does not have %s Deserter.", handler->playerLink(player->GetName()), isInstance ? "Instance" : "Battleground");
|
||||
handler->SetSentErrorMessage(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
CharacterDatabase.Query("DELETE FROM character_aura WHERE guid = {} AND spell = {}", player->GetGUID().GetCounter(), isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER);
|
||||
if (duration < 0)
|
||||
{
|
||||
handler->PSendSysMessage("Permanent %s Deserter has been removed from player %s (GUID %u).", isInstance ? "Instance" : "Battleground", handler->playerLink(player->GetName()), player->GetGUID().GetCounter());
|
||||
handler->SetSentErrorMessage(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
handler->PSendSysMessage("%s of %s Deserter has been removed from player %s (GUID %u).", secsToTimeString(duration / IN_MILLISECONDS), isInstance ? "Instance" : "Battleground", handler->playerLink(player->GetName()), player->GetGUID().GetCounter());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Removes the Deserter Debuff from all players
|
||||
*
|
||||
* This function removes a Deserter Debuff of the given type (Instance or BG) from
|
||||
* all players, online or offline.
|
||||
*
|
||||
* @param handler The ChatHandler, passed by the system.
|
||||
* @param isInstance provided by the relaying functions, so we don't have
|
||||
* to write that much code :)
|
||||
* @param maxTime Optional: The maximum remaining time of the Debuff on players to be removed.
|
||||
* Any Player with a Deserter Debuff of this time or less will get their Debuff removed. Use -1 for any.
|
||||
* Default: 15m for BG, 30m for Instance.
|
||||
*
|
||||
* @return true if everything was correct, false if an error occured.
|
||||
*
|
||||
* Example Usage:
|
||||
* @code
|
||||
* .deserter bg remove all
|
||||
* -or-
|
||||
* .deserter bg remove all 30m
|
||||
* -or-
|
||||
* .deserter bg remove all -1
|
||||
* @endcode
|
||||
*/
|
||||
static bool HandleDeserterRemoveAll(ChatHandler* handler, bool isInstance, Optional<std::string> maxTime)
|
||||
{
|
||||
uint32 deserterSpell = isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER;
|
||||
int32 remainTime = isInstance ? 1800 : 900;
|
||||
uint64 deserterCount = 0;
|
||||
bool countOnline = true;
|
||||
|
||||
if (maxTime)
|
||||
{
|
||||
@@ -273,6 +335,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Optimization. Do not execute any further functions or Queries if remainTime is 0.
|
||||
if (remainTime == 0)
|
||||
{
|
||||
handler->SendSysMessage(LANG_BAD_VALUE);
|
||||
@@ -280,13 +343,33 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (remainTime < 0)
|
||||
QueryResult result;
|
||||
if (remainTime > 0)
|
||||
{
|
||||
CharacterDatabase.Execute("DELETE FROM character_aura WHERE spell = {}", isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER);
|
||||
result = CharacterDatabase.Query("SELECT COUNT(guid) FROM character_aura WHERE spell = {} AND remainTime <= {}", deserterSpell, remainTime * IN_MILLISECONDS);
|
||||
}
|
||||
else
|
||||
{
|
||||
CharacterDatabase.Execute("DELETE FROM character_aura WHERE spell = {} AND remainTime <= {}", isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER, remainTime * IN_MILLISECONDS);
|
||||
result = CharacterDatabase.Query("SELECT COUNT(guid) FROM character_aura WHERE spell = {}", deserterSpell);
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
deserterCount = (*result)[0].Get<uint64>();
|
||||
}
|
||||
|
||||
// Optimization. Only execute these if there even is a result.
|
||||
if (deserterCount > 0)
|
||||
{
|
||||
countOnline = false;
|
||||
if (remainTime > 0)
|
||||
{
|
||||
CharacterDatabase.Execute("DELETE FROM character_aura WHERE spell = {} AND remainTime <= {}", deserterSpell, remainTime * IN_MILLISECONDS);
|
||||
}
|
||||
else
|
||||
{
|
||||
CharacterDatabase.Execute("DELETE FROM character_aura WHERE spell = {}", deserterSpell);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_lock<std::shared_mutex> lock(*HashMapHolder<Player>::GetLock());
|
||||
@@ -294,14 +377,28 @@ public:
|
||||
for (HashMapHolder<Player>::MapType::const_iterator itr = onlinePlayerList.begin(); itr != onlinePlayerList.end(); ++itr)
|
||||
{
|
||||
Player* player = itr->second;
|
||||
Aura* aura = player->GetAura(isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER);
|
||||
Aura* aura = player->GetAura(deserterSpell);
|
||||
if (aura && (remainTime < 0 || aura->GetDuration() <= remainTime * IN_MILLISECONDS))
|
||||
{
|
||||
player->RemoveAura(isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER);
|
||||
if (countOnline)
|
||||
deserterCount++;
|
||||
player->RemoveAura(deserterSpell);
|
||||
}
|
||||
}
|
||||
|
||||
handler->PSendSysMessage("%s Deserter has been removed from all players", isInstance ? "Instance" : "Battleground");
|
||||
std::string remainTimeStr = secsToTimeString(remainTime);
|
||||
if (remainTime < 0)
|
||||
{
|
||||
remainTimeStr = "infinity";
|
||||
}
|
||||
|
||||
if (deserterCount == 0)
|
||||
{
|
||||
handler->PSendSysMessage("No player on this realm has %s Deserter with a duration of %s or less.", isInstance ? "Instance" : "Battleground", remainTimeStr);
|
||||
return true;
|
||||
}
|
||||
|
||||
handler->PSendSysMessage("%s Deserter has been removed from %u player(s) with a duration of %s or less.", isInstance ? "Instance" : "Battleground", deserterCount, remainTimeStr);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -143,9 +143,9 @@ public:
|
||||
return commandTable;
|
||||
}
|
||||
|
||||
static bool HandleSkirmishCommand(ChatHandler* handler, std::string_view args)
|
||||
static bool HandleSkirmishCommand(ChatHandler* handler, std::vector<std::string_view> args)
|
||||
{
|
||||
auto tokens = Acore::Tokenize(args, ' ', true);
|
||||
auto tokens = args;
|
||||
|
||||
if (args.empty() || !tokens.size())
|
||||
{
|
||||
|
||||
@@ -148,6 +148,7 @@ public:
|
||||
_hasSubmergedOnce = false;
|
||||
_isKnockbackEmoteAllowed = true;
|
||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
|
||||
me->SetControlled(true, UNIT_STATE_ROOT);
|
||||
_lavaBurstGUIDS.clear();
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@ enum Spells
|
||||
{
|
||||
SPELL_AVATAR = 24646, // Enrage Spell
|
||||
SPELL_GROUND_TREMOR = 6524,
|
||||
SPELL_ENTANGLING_ROOTS = 24648
|
||||
SPELL_ENTANGLING_ROOTS = 24648,
|
||||
SPELL_SWEEPING_STRIKES = 18765
|
||||
};
|
||||
|
||||
enum Events
|
||||
@@ -39,7 +40,8 @@ enum Events
|
||||
EVENT_GROUND_TREMOR = 2,
|
||||
EVENT_START_PURSUIT = 3,
|
||||
EVENT_STOP_PURSUIT = 4,
|
||||
EVENT_ENTANGLING_ROOTS = 5
|
||||
EVENT_ENTANGLING_ROOTS = 5,
|
||||
EVENT_SWEEPING_STRIKES = 6
|
||||
};
|
||||
|
||||
class boss_grilek : public CreatureScript // grilek
|
||||
@@ -65,6 +67,7 @@ public:
|
||||
events.ScheduleEvent(EVENT_AVATAR, 20s, 30s);
|
||||
events.ScheduleEvent(EVENT_GROUND_TREMOR, 15s, 25s);
|
||||
events.ScheduleEvent(EVENT_ENTANGLING_ROOTS, 5s, 15s);
|
||||
events.ScheduleEvent(EVENT_SWEEPING_STRIKES, 30s);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
@@ -115,6 +118,10 @@ public:
|
||||
DoCastVictim(SPELL_ENTANGLING_ROOTS);
|
||||
events.ScheduleEvent(EVENT_ENTANGLING_ROOTS, 10s, 20s);
|
||||
break;
|
||||
case EVENT_SWEEPING_STRIKES:
|
||||
DoCastSelf(SPELL_SWEEPING_STRIKES, true);
|
||||
events.ScheduleEvent(EVENT_SWEEPING_STRIKES, 30s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -34,15 +34,17 @@ enum Says
|
||||
SAY_FLEEING = 1,
|
||||
SAY_MINION_DESTROY = 2,
|
||||
SAY_PROTECT_ALTAR = 3,
|
||||
SAY_PROTECT_GURUBASHI_EMPIRE = 4
|
||||
SAY_PROTECT_GURUBASHI_EMPIRE = 4,
|
||||
SAY_PLEDGE_ALLEGIANCE = 5,
|
||||
SAY_WORLD_WILL_SUFFER = 6,
|
||||
SAY_EVADE = 7
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_POISONOUS_BLOOD = 24321,
|
||||
SPELL_BLOOD_SIPHON_HEAL = 24322,
|
||||
SPELL_BLOOD_SIPHON_DMG = 24323,
|
||||
SPELL_BLOOD_SIPHON = 24324,
|
||||
SPELL_BLOOD_SIPHON_HEAL = 24322,
|
||||
SPELL_BLOOD_SIPHON_DAMAGE = 24323,
|
||||
SPELL_CORRUPTED_BLOOD = 24328,
|
||||
SPELL_CAUSE_INSANITY = 24327,
|
||||
SPELL_ENRAGE = 24318,
|
||||
@@ -51,7 +53,8 @@ enum Spells
|
||||
SPELL_ASPECT_OF_VENOXIS = 24688,
|
||||
SPELL_ASPECT_OF_MARLI = 24686,
|
||||
SPELL_ASPECT_OF_THEKAL = 24689,
|
||||
SPELL_ASPECT_OF_ARLOKK = 24690
|
||||
SPELL_ASPECT_OF_ARLOKK = 24690,
|
||||
SPELL_POISONOUS_BLOOD = 24321
|
||||
};
|
||||
|
||||
enum Events
|
||||
@@ -87,9 +90,19 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
void ApplyHakkarPowerStacks()
|
||||
{
|
||||
me->RemoveAurasDueToSpell(SPELL_HAKKAR_POWER);
|
||||
for (int i = DATA_JEKLIK; i < DATA_HAKKAR; i++)
|
||||
if (instance->GetBossState(i) != DONE)
|
||||
DoCastSelf(SPELL_HAKKAR_POWER, true);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
|
||||
ApplyHakkarPowerStacks();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
@@ -105,18 +118,25 @@ public:
|
||||
events.ScheduleEvent(EVENT_CAUSE_INSANITY, 17000);
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 600000);
|
||||
if (instance->GetBossState(DATA_JEKLIK) != DONE)
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_JEKLIK, 4000);
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_JEKLIK, 21000);
|
||||
if (instance->GetBossState(DATA_VENOXIS) != DONE)
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_VENOXIS, 7000);
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_VENOXIS, 14000);
|
||||
if (instance->GetBossState(DATA_MARLI) != DONE)
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 12000);
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 15000);
|
||||
if (instance->GetBossState(DATA_THEKAL) != DONE)
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_THEKAL, 8000);
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_THEKAL, 10000);
|
||||
if (instance->GetBossState(DATA_ARLOKK) != DONE)
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_ARLOKK, 18000);
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason evadeReason) override
|
||||
{
|
||||
BossAI::EnterEvadeMode(evadeReason);
|
||||
|
||||
Talk(SAY_EVADE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim() || !CheckInRoom())
|
||||
@@ -140,9 +160,12 @@ public:
|
||||
events.ScheduleEvent(EVENT_CORRUPTED_BLOOD, urand(30000, 45000));
|
||||
break;
|
||||
case EVENT_CAUSE_INSANITY:
|
||||
if (Unit* victim = SelectTarget(SelectTargetMethod::MaxThreat, 0, 30.f, true))
|
||||
if (me->GetThreatMgr().getThreatList().size() > 1)
|
||||
{
|
||||
DoCast(victim, SPELL_CAUSE_INSANITY);
|
||||
if (Unit* victim = SelectTarget(SelectTargetMethod::MaxThreat, 0, 30.f, true))
|
||||
{
|
||||
DoCast(victim, SPELL_CAUSE_INSANITY);
|
||||
}
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CAUSE_INSANITY, urand(35000, 45000));
|
||||
break;
|
||||
@@ -153,11 +176,11 @@ public:
|
||||
break;
|
||||
case EVENT_ASPECT_OF_JEKLIK:
|
||||
DoCastVictim(SPELL_ASPECT_OF_JEKLIK, true);
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_JEKLIK, urand(10000, 14000));
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_JEKLIK, 24000);
|
||||
break;
|
||||
case EVENT_ASPECT_OF_VENOXIS:
|
||||
DoCastVictim(SPELL_ASPECT_OF_VENOXIS, true);
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_VENOXIS, 8000);
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_VENOXIS, urand(16000, 18000));
|
||||
break;
|
||||
case EVENT_ASPECT_OF_MARLI:
|
||||
if (Unit* victim = SelectTarget(SelectTargetMethod::MaxThreat, 0, 5.f, true))
|
||||
@@ -165,7 +188,7 @@ public:
|
||||
DoCast(victim, SPELL_ASPECT_OF_MARLI, true);
|
||||
me->GetThreatMgr().modifyThreatPercent(victim, -100.f);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 10000);
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 45000);
|
||||
break;
|
||||
case EVENT_ASPECT_OF_THEKAL:
|
||||
DoCastVictim(SPELL_ASPECT_OF_THEKAL, true);
|
||||
@@ -215,8 +238,8 @@ public:
|
||||
hakkar->AI()->Talk(SAY_PROTECT_GURUBASHI_EMPIRE);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -230,6 +253,10 @@ public:
|
||||
{
|
||||
if (InstanceScript* instance = player->GetInstanceScript())
|
||||
{
|
||||
// Instance map's enormous, Hakkar's GRID is not loaded by the time players enter.
|
||||
// Without this, the creature never says anything, because it doesn't load in time.
|
||||
player->GetMap()->LoadGrid(-11783.99f, -1655.27f);
|
||||
|
||||
if (Creature* hakkar = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_HAKKAR)))
|
||||
{
|
||||
if (hakkar->GetAI())
|
||||
@@ -237,8 +264,8 @@ public:
|
||||
hakkar->AI()->Talk(SAY_PROTECT_ALTAR);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -252,6 +279,10 @@ public:
|
||||
{
|
||||
if (InstanceScript* instance = player->GetInstanceScript())
|
||||
{
|
||||
// Instance map's enormous, Hakkar's GRID is not loaded by the time players enter.
|
||||
// Without this, the creature never says anything, because it doesn't load in time.
|
||||
player->GetMap()->LoadGrid(-11783.99f, -1655.27f);
|
||||
|
||||
if (Creature* hakkar = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_HAKKAR)))
|
||||
{
|
||||
if (hakkar->GetAI())
|
||||
@@ -259,37 +290,114 @@ public:
|
||||
hakkar->AI()->Talk(SAY_MINION_DESTROY);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class spell_hakkar_blood_siphon : public SpellScript
|
||||
class at_zulgurub_bloodfire_pit_speech : public OnlyOnceAreaTriggerScript
|
||||
{
|
||||
PrepareSpellScript(spell_hakkar_blood_siphon);
|
||||
public:
|
||||
at_zulgurub_bloodfire_pit_speech() : OnlyOnceAreaTriggerScript("at_zulgurub_bloodfire_pit_speech") {}
|
||||
|
||||
bool _OnTrigger(Player* player, const AreaTrigger* /*at*/) override
|
||||
{
|
||||
if (InstanceScript* instance = player->GetInstanceScript())
|
||||
{
|
||||
// Instance map's enormous, Hakkar's GRID is not loaded by the time players enter.
|
||||
// Without this, the creature never says anything, because it doesn't load in time.
|
||||
player->GetMap()->LoadGrid(-11783.99f, -1655.27f);
|
||||
|
||||
if (Creature* hakkar = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_HAKKAR)))
|
||||
{
|
||||
if (hakkar->GetAI())
|
||||
{
|
||||
hakkar->AI()->Talk(SAY_PLEDGE_ALLEGIANCE, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class at_zulgurub_edge_of_madness_speech : public OnlyOnceAreaTriggerScript
|
||||
{
|
||||
public:
|
||||
at_zulgurub_edge_of_madness_speech() : OnlyOnceAreaTriggerScript("at_zulgurub_edge_of_madness_speech") {}
|
||||
|
||||
bool _OnTrigger(Player* player, const AreaTrigger* /*at*/) override
|
||||
{
|
||||
if (InstanceScript* instance = player->GetInstanceScript())
|
||||
{
|
||||
// Instance map's enormous, Hakkar's GRID is not loaded by the time players enter.
|
||||
// Without this, the creature never says anything, because it doesn't load in time.
|
||||
player->GetMap()->LoadGrid(-11783.99f, -1655.27f);
|
||||
|
||||
if (Creature* hakkar = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_HAKKAR)))
|
||||
{
|
||||
if (hakkar->GetAI())
|
||||
{
|
||||
hakkar->AI()->Talk(SAY_WORLD_WILL_SUFFER, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class spell_blood_siphon : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_blood_siphon);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_BLOOD_SIPHON_HEAL, SPELL_BLOOD_SIPHON_DMG });
|
||||
return ValidateSpellInfo({ SPELL_BLOOD_SIPHON_DAMAGE, SPELL_BLOOD_SIPHON_HEAL });
|
||||
}
|
||||
|
||||
void OnSpellHit()
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
Unit* target = GetHitUnit();
|
||||
if (!caster || !target)
|
||||
return;
|
||||
// Max. 20 targets
|
||||
if (!targets.empty())
|
||||
{
|
||||
Acore::Containers::RandomResize(targets, 20);
|
||||
}
|
||||
}
|
||||
|
||||
if (target->HasAura(SPELL_POISONOUS_BLOOD))
|
||||
target->CastSpell(caster, SPELL_BLOOD_SIPHON_DMG, true);
|
||||
else
|
||||
target->CastSpell(caster, SPELL_BLOOD_SIPHON_HEAL, true);
|
||||
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
{
|
||||
if (Player* player = GetHitPlayer())
|
||||
{
|
||||
player->CastSpell(caster, player->HasAura(SPELL_POISONOUS_BLOOD) ? SPELL_BLOOD_SIPHON_DAMAGE : SPELL_BLOOD_SIPHON_HEAL, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnHit += SpellHitFn(spell_hakkar_blood_siphon::OnSpellHit);
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_blood_siphon::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_blood_siphon::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_hakkar_power_down : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_hakkar_power_down);
|
||||
|
||||
void HandleOnHit()
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
if (caster->HasAura(SPELL_HAKKAR_POWER))
|
||||
caster->RemoveAuraFromStack(SPELL_HAKKAR_POWER);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnHit += SpellHitFn(spell_hakkar_power_down::HandleOnHit);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -299,5 +407,8 @@ void AddSC_boss_hakkar()
|
||||
new at_zulgurub_entrance_speech();
|
||||
new at_zulgurub_bridge_speech();
|
||||
new at_zulgurub_temple_speech();
|
||||
RegisterSpellScript(spell_hakkar_blood_siphon);
|
||||
new at_zulgurub_bloodfire_pit_speech();
|
||||
new at_zulgurub_edge_of_madness_speech();
|
||||
RegisterSpellScript(spell_blood_siphon);
|
||||
RegisterSpellScript(spell_hakkar_power_down);
|
||||
}
|
||||
|
||||
@@ -15,13 +15,6 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Hazzarah
|
||||
SD%Complete: 100
|
||||
SDComment:
|
||||
SDCategory: Zul'Gurub
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellScript.h"
|
||||
@@ -45,100 +38,98 @@ enum Events
|
||||
EVENT_ILLUSIONS = 4
|
||||
};
|
||||
|
||||
class boss_hazzarah : public CreatureScript
|
||||
struct boss_hazzarah : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_hazzarah() : CreatureScript("boss_hazzarah") { }
|
||||
boss_hazzarah(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { }
|
||||
|
||||
struct boss_hazzarahAI : public BossAI
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
boss_hazzarahAI(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { }
|
||||
summons.Summon(summon);
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summons.Summon(summon);
|
||||
|
||||
summon->SetCorpseDelay(10);
|
||||
summon->SetReactState(REACT_PASSIVE);
|
||||
summon->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE);
|
||||
summon->SetVisible(false);
|
||||
summon->m_Events.AddEventAtOffset([summon]()
|
||||
summon->SetCorpseDelay(10);
|
||||
summon->SetReactState(REACT_PASSIVE);
|
||||
summon->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE);
|
||||
summon->SetVisible(false);
|
||||
summon->m_Events.AddEventAtOffset([summon]()
|
||||
{
|
||||
summon->SetVisible(true);
|
||||
}, 2s);
|
||||
|
||||
summon->m_Events.AddEventAtOffset([summon]()
|
||||
summon->m_Events.AddEventAtOffset([summon]()
|
||||
{
|
||||
summon->RemoveUnitFlag(UNIT_FLAG_DISABLE_MOVE);
|
||||
summon->SetReactState(REACT_AGGRESSIVE);
|
||||
summon->SetInCombatWithZone();
|
||||
}, 3500ms);
|
||||
}
|
||||
}, 5s);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
|
||||
{
|
||||
summons.Despawn(summon);
|
||||
summon->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_EnterCombat();
|
||||
events.ScheduleEvent(EVENT_SLEEP, 12s, 15s);
|
||||
events.ScheduleEvent(EVENT_EARTH_SHOCK, 8s, 18s);
|
||||
events.ScheduleEvent(EVENT_CHAIN_BURN, 12s, 28s);
|
||||
events.ScheduleEvent(EVENT_ILLUSIONS, 16s, 24s);
|
||||
}
|
||||
|
||||
bool CanAIAttack(Unit const* target) const override
|
||||
{
|
||||
if (me->GetThreatMgr().getThreatList().size() > 1 && me->GetThreatMgr().getOnlineContainer().getMostHated()->getTarget() == target)
|
||||
return !target->HasAura(SPELL_SLEEP);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
_EnterCombat();
|
||||
events.ScheduleEvent(EVENT_SLEEP, 12s, 15s);
|
||||
events.ScheduleEvent(EVENT_EARTH_SHOCK, 8s, 18s);
|
||||
events.ScheduleEvent(EVENT_CHAIN_BURN, 12s, 28s);
|
||||
events.ScheduleEvent(EVENT_ILLUSIONS, 16s, 24s);
|
||||
}
|
||||
|
||||
bool CanAIAttack(Unit const* target) const override
|
||||
{
|
||||
if (me->GetThreatMgr().getThreatList().size() > 1 && me->GetThreatMgr().getOnlineContainer().getMostHated()->getTarget() == target)
|
||||
return !target->HasAura(SPELL_SLEEP);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
switch (eventId)
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_SLEEP:
|
||||
DoCastVictim(SPELL_SLEEP, true);
|
||||
events.ScheduleEvent(EVENT_SLEEP, 24s, 32s);
|
||||
return;
|
||||
case EVENT_EARTH_SHOCK:
|
||||
DoCastVictim(SPELL_EARTH_SHOCK);
|
||||
events.ScheduleEvent(EVENT_EARTH_SHOCK, 8s, 18s);
|
||||
break;
|
||||
case EVENT_CHAIN_BURN:
|
||||
case EVENT_SLEEP:
|
||||
DoCastVictim(SPELL_SLEEP, true);
|
||||
events.ScheduleEvent(EVENT_SLEEP, 24s, 32s);
|
||||
return;
|
||||
case EVENT_EARTH_SHOCK:
|
||||
DoCastVictim(SPELL_EARTH_SHOCK);
|
||||
events.ScheduleEvent(EVENT_EARTH_SHOCK, 8s, 18s);
|
||||
break;
|
||||
case EVENT_CHAIN_BURN:
|
||||
if (me->GetPowerPct(POWER_MANA) > 5.f) // totally guessed
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, [&](Unit* u) { return u && !u->IsPet() && u->getPowerType() == POWER_MANA; }))
|
||||
{
|
||||
DoCast(target, SPELL_CHAIN_BURN, false);
|
||||
DoCast(target, SPELL_CHAIN_BURN);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHAIN_BURN, 12s, 28s);
|
||||
break;
|
||||
case EVENT_ILLUSIONS:
|
||||
DoCastSelf(SPELL_SUMMON_NIGHTMARE_ILLUSION_LEFT, true);
|
||||
DoCastSelf(SPELL_SUMMON_NIGHTMARE_ILLUSION_BACK, true);
|
||||
DoCastSelf(SPELL_SUMMON_NIGHTMARE_ILLUSION_RIGHT, true);
|
||||
events.ScheduleEvent(EVENT_ILLUSIONS, 16s, 24s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHAIN_BURN, 12s, 28s);
|
||||
break;
|
||||
case EVENT_ILLUSIONS:
|
||||
DoCastSelf(SPELL_SUMMON_NIGHTMARE_ILLUSION_LEFT, true);
|
||||
DoCastSelf(SPELL_SUMMON_NIGHTMARE_ILLUSION_BACK, true);
|
||||
DoCastSelf(SPELL_SUMMON_NIGHTMARE_ILLUSION_RIGHT, true);
|
||||
events.ScheduleEvent(EVENT_ILLUSIONS, 15s, 25s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetZulGurubAI<boss_hazzarahAI>(creature);
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -164,6 +155,6 @@ class spell_chain_burn : public SpellScript
|
||||
|
||||
void AddSC_boss_hazzarah()
|
||||
{
|
||||
new boss_hazzarah();
|
||||
RegisterZulGurubCreatureAI(boss_hazzarah);
|
||||
RegisterSpellScript(spell_chain_burn);
|
||||
}
|
||||
|
||||
@@ -15,15 +15,10 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Jin'do the Hexxer
|
||||
SD%Complete: 85
|
||||
SDComment: Mind Control not working because of core bug. Shades visible for all.
|
||||
SDCategory: Zul'Gurub
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellScript.h"
|
||||
#include "TaskScheduler.h"
|
||||
#include "zulgurub.h"
|
||||
|
||||
enum Say
|
||||
@@ -33,269 +28,265 @@ enum Say
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_BRAINWASHTOTEM = 24262,
|
||||
SPELL_POWERFULLHEALINGWARD = 24309,
|
||||
SPELL_BRAIN_WASH_TOTEM = 24262,
|
||||
SPELL_POWERFULL_HEALING_WARD = 24309,
|
||||
SPELL_HEX = 24053,
|
||||
SPELL_DELUSIONSOFJINDO = 24306,
|
||||
SPELL_DELUSIONS_OF_JINDO = 24306,
|
||||
SPELL_SUMMON_SHADE_OF_JINDO = 24308,
|
||||
SPELL_BANISH = 24466,
|
||||
|
||||
//Healing Ward Spell
|
||||
SPELL_HEAL = 24311,
|
||||
|
||||
//Shade of Jindo Spell
|
||||
SPELL_SHADEOFJINDO_PASSIVE = 24307,
|
||||
SPELL_SHADEOFJINDO_VISUAL = 24313,
|
||||
SPELL_SHADOWSHOCK = 19460
|
||||
SPELL_SHADE_OF_JINDO_PASSIVE = 24307,
|
||||
SPELL_SHADE_OF_JINDO_VISUAL = 24313,
|
||||
SPELL_SHADOW_SHOCK = 19460,
|
||||
SPELL_RANDOM_AGGRO = 23878
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_BRAINWASHTOTEM = 1,
|
||||
EVENT_POWERFULLHEALINGWARD = 2,
|
||||
EVENT_BRAIN_WASH_TOTEM = 1,
|
||||
EVENT_POWERFULL_HEALING_WARD = 2,
|
||||
EVENT_HEX = 3,
|
||||
EVENT_DELUSIONSOFJINDO = 4,
|
||||
EVENT_DELUSIONS_OF_JINDO = 4,
|
||||
EVENT_TELEPORT = 5
|
||||
};
|
||||
|
||||
Position const TeleportLoc = {-11583.7783f, -1249.4278f, 77.5471f, 4.745f};
|
||||
|
||||
class boss_jindo : public CreatureScript
|
||||
struct boss_jindo : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_jindo() : CreatureScript("boss_jindo") { }
|
||||
boss_jindo(Creature* creature) : BossAI(creature, DATA_JINDO) { }
|
||||
|
||||
struct boss_jindoAI : public BossAI
|
||||
void EnterCombat(Unit* who) override
|
||||
{
|
||||
boss_jindoAI(Creature* creature) : BossAI(creature, DATA_JINDO) { }
|
||||
BossAI::EnterCombat(who);
|
||||
events.ScheduleEvent(EVENT_BRAIN_WASH_TOTEM, 20000);
|
||||
events.ScheduleEvent(EVENT_POWERFULL_HEALING_WARD, 16000);
|
||||
events.ScheduleEvent(EVENT_HEX, 8000);
|
||||
events.ScheduleEvent(EVENT_DELUSIONS_OF_JINDO, 10000);
|
||||
events.ScheduleEvent(EVENT_TELEPORT, 5000);
|
||||
|
||||
void Reset() override
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
BossAI::JustSummoned(summon);
|
||||
|
||||
switch (summon->GetEntry())
|
||||
{
|
||||
_Reset();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_EnterCombat();
|
||||
events.ScheduleEvent(EVENT_BRAINWASHTOTEM, 20000);
|
||||
events.ScheduleEvent(EVENT_POWERFULLHEALINGWARD, 16000);
|
||||
events.ScheduleEvent(EVENT_HEX, 8000);
|
||||
events.ScheduleEvent(EVENT_DELUSIONSOFJINDO, 10000);
|
||||
events.ScheduleEvent(EVENT_TELEPORT, 5000);
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
BossAI::JustSummoned(summon);
|
||||
|
||||
switch (summon->GetEntry())
|
||||
case NPC_BRAIN_WASH_TOTEM:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1))
|
||||
{
|
||||
case NPC_BRAIN_WASH_TOTEM:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1))
|
||||
{
|
||||
summon->CastSpell(target, summon->m_spells[0], true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
summon->CastSpell(target, summon->m_spells[0], true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason evadeReason) override
|
||||
{
|
||||
if (_EnterEvadeMode(evadeReason))
|
||||
{
|
||||
me->AddUnitState(UNIT_STATE_EVADE);
|
||||
Reset();
|
||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_DANCE);
|
||||
|
||||
me->m_Events.AddEventAtOffset([&]()
|
||||
{
|
||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
|
||||
me->GetMotionMaster()->MoveTargetedHome();
|
||||
}, 4s);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_BRAIN_WASH_TOTEM:
|
||||
DoCastSelf(SPELL_BRAIN_WASH_TOTEM);
|
||||
events.ScheduleEvent(EVENT_BRAIN_WASH_TOTEM, urand(18000, 26000));
|
||||
break;
|
||||
case EVENT_POWERFULL_HEALING_WARD:
|
||||
DoCastSelf(SPELL_POWERFULL_HEALING_WARD, true);
|
||||
events.ScheduleEvent(EVENT_POWERFULL_HEALING_WARD, urand(14000, 20000));
|
||||
break;
|
||||
case EVENT_HEX:
|
||||
if (me->GetThreatMgr().getThreatList().size() > 1)
|
||||
DoCastVictim(SPELL_HEX, true);
|
||||
events.ScheduleEvent(EVENT_HEX, urand(12000, 20000));
|
||||
break;
|
||||
case EVENT_DELUSIONS_OF_JINDO:
|
||||
DoCastRandomTarget(SPELL_DELUSIONS_OF_JINDO);
|
||||
events.ScheduleEvent(EVENT_DELUSIONS_OF_JINDO, urand(4000, 12000));
|
||||
break;
|
||||
case EVENT_TELEPORT:
|
||||
DoCastRandomTarget(SPELL_BANISH);
|
||||
events.ScheduleEvent(EVENT_TELEPORT, urand(15000, 23000));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_BRAINWASHTOTEM:
|
||||
DoCast(me, SPELL_BRAINWASHTOTEM);
|
||||
events.ScheduleEvent(EVENT_BRAINWASHTOTEM, urand(18000, 26000));
|
||||
break;
|
||||
case EVENT_POWERFULLHEALINGWARD:
|
||||
DoCastSelf(SPELL_POWERFULLHEALINGWARD, true);
|
||||
events.ScheduleEvent(EVENT_POWERFULLHEALINGWARD, urand(14000, 20000));
|
||||
break;
|
||||
case EVENT_HEX:
|
||||
DoCastVictim(SPELL_HEX, true);
|
||||
events.ScheduleEvent(EVENT_HEX, urand(12000, 20000));
|
||||
break;
|
||||
case EVENT_DELUSIONSOFJINDO: // HACK
|
||||
// Casting the delusion curse with a shade so shade will attack the same target with the curse.
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
{
|
||||
DoCast(target, SPELL_DELUSIONSOFJINDO);
|
||||
Creature* Shade = me->SummonCreature(NPC_SHADE_OF_JINDO, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Shade)
|
||||
Shade->AI()->AttackStart(target);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_DELUSIONSOFJINDO, urand(4000, 12000));
|
||||
break;
|
||||
case EVENT_TELEPORT: // Possible HACK
|
||||
// Teleports a random player and spawns 9 Sacrificed Trolls to attack player
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
{
|
||||
DoTeleportPlayer(target, TeleportLoc.m_positionX, TeleportLoc.m_positionY, TeleportLoc.m_positionZ, TeleportLoc.GetOrientation());
|
||||
if (DoGetThreat(me->GetVictim()))
|
||||
DoModifyThreatPercent(target, -100);
|
||||
Creature* SacrificedTroll;
|
||||
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, TeleportLoc.m_positionX + 2, TeleportLoc.m_positionY, TeleportLoc.m_positionZ, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (SacrificedTroll)
|
||||
SacrificedTroll->AI()->AttackStart(target);
|
||||
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, TeleportLoc.m_positionX - 2, TeleportLoc.m_positionY, TeleportLoc.m_positionZ, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (SacrificedTroll)
|
||||
SacrificedTroll->AI()->AttackStart(target);
|
||||
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, TeleportLoc.m_positionX + 4, TeleportLoc.m_positionY, TeleportLoc.m_positionZ, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (SacrificedTroll)
|
||||
SacrificedTroll->AI()->AttackStart(target);
|
||||
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, TeleportLoc.m_positionX - 4, TeleportLoc.m_positionY, TeleportLoc.m_positionZ, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (SacrificedTroll)
|
||||
SacrificedTroll->AI()->AttackStart(target);
|
||||
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, TeleportLoc.m_positionX, TeleportLoc.m_positionY + 2, TeleportLoc.m_positionZ, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (SacrificedTroll)
|
||||
SacrificedTroll->AI()->AttackStart(target);
|
||||
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, TeleportLoc.m_positionX, TeleportLoc.m_positionY - 2, TeleportLoc.m_positionZ, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (SacrificedTroll)
|
||||
SacrificedTroll->AI()->AttackStart(target);
|
||||
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, TeleportLoc.m_positionX, TeleportLoc.m_positionY + 4, TeleportLoc.m_positionZ, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (SacrificedTroll)
|
||||
SacrificedTroll->AI()->AttackStart(target);
|
||||
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, TeleportLoc.m_positionX, TeleportLoc.m_positionY - 4, TeleportLoc.m_positionZ, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (SacrificedTroll)
|
||||
SacrificedTroll->AI()->AttackStart(target);
|
||||
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, TeleportLoc.m_positionX + 3, TeleportLoc.m_positionY, TeleportLoc.m_positionZ, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (SacrificedTroll)
|
||||
SacrificedTroll->AI()->AttackStart(target);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_TELEPORT, urand(15000, 23000));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
bool CanAIAttack(Unit const* target) const override
|
||||
{
|
||||
bool CanAIAttack(Unit const* target) const override
|
||||
{
|
||||
if (me->GetThreatMgr().getThreatList().size() > 1 && me->GetThreatMgr().getOnlineContainer().getMostHated()->getTarget() == target)
|
||||
return !target->HasAura(SPELL_HEX);
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetZulGurubAI<boss_jindoAI>(creature);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
//Healing Ward
|
||||
class npc_healing_ward : public CreatureScript
|
||||
struct npc_healing_ward : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
npc_healing_ward()
|
||||
: CreatureScript("npc_healing_ward")
|
||||
npc_healing_ward(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
_instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
struct npc_healing_wardAI : public ScriptedAI
|
||||
void Reset() override
|
||||
{
|
||||
npc_healing_wardAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
_scheduler.CancelAll();
|
||||
}
|
||||
|
||||
uint32 Heal_Timer;
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Heal_Timer = 2000;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//Heal_Timer
|
||||
if (Heal_Timer <= diff)
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_scheduler.
|
||||
Schedule(2s, [this](TaskContext context)
|
||||
{
|
||||
Unit* pJindo = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_JINDO));
|
||||
Unit* pJindo = ObjectAccessor::GetUnit(*me, _instance->GetGuidData(DATA_JINDO));
|
||||
if (pJindo)
|
||||
DoCast(pJindo, SPELL_HEAL);
|
||||
Heal_Timer = 3000;
|
||||
}
|
||||
else Heal_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetZulGurubAI<npc_healing_wardAI>(creature);
|
||||
context.Repeat(3s);
|
||||
});
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
_scheduler.Update(diff, [this]
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
InstanceScript* _instance;
|
||||
TaskScheduler _scheduler;
|
||||
};
|
||||
|
||||
//Shade of Jindo
|
||||
class npc_shade_of_jindo : public CreatureScript
|
||||
struct npc_shade_of_jindo : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
npc_shade_of_jindo()
|
||||
: CreatureScript("npc_shade_of_jindo")
|
||||
npc_shade_of_jindo(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void IsSummonedBy(Unit* /*summoner*/) override
|
||||
{
|
||||
DoZoneInCombat();
|
||||
DoCastSelf(SPELL_SHADE_OF_JINDO_PASSIVE, true);
|
||||
DoCastSelf(SPELL_SHADE_OF_JINDO_VISUAL, true);
|
||||
DoCastAOE(SPELL_RANDOM_AGGRO, true);
|
||||
}
|
||||
|
||||
struct npc_shade_of_jindoAI : public ScriptedAI
|
||||
void Reset() override
|
||||
{
|
||||
npc_shade_of_jindoAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
_scheduler.CancelAll();
|
||||
|
||||
uint32 ShadowShock_Timer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
ShadowShock_Timer = 1000;
|
||||
DoCastSelf(SPELL_SHADEOFJINDO_PASSIVE, true);
|
||||
DoCastSelf(SPELL_SHADEOFJINDO_VISUAL, true);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override { }
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//ShadowShock_Timer
|
||||
if (ShadowShock_Timer <= diff)
|
||||
_scheduler.
|
||||
Schedule(1s, [this](TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_SHADOWSHOCK);
|
||||
ShadowShock_Timer = 2000;
|
||||
}
|
||||
else ShadowShock_Timer -= diff;
|
||||
DoCastAOE(SPELL_RANDOM_AGGRO, true);
|
||||
context.Repeat();
|
||||
});
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
return GetZulGurubAI<npc_shade_of_jindoAI>(creature);
|
||||
_scheduler.
|
||||
Schedule(1s, [this](TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_SHADOW_SHOCK);
|
||||
context.Repeat(2s);
|
||||
});
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
_scheduler.Update(diff, [this]
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
TaskScheduler _scheduler;
|
||||
};
|
||||
|
||||
class spell_random_aggro : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_random_aggro);
|
||||
|
||||
void HandleOnHit()
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
Unit* target = GetHitUnit();
|
||||
if (!caster || !target || !caster->GetAI())
|
||||
return;
|
||||
|
||||
caster->GetAI()->AttackStart(target);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnHit += SpellHitFn(spell_random_aggro::HandleOnHit);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_delusions_of_jindo : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_delusions_of_jindo);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_SUMMON_SHADE_OF_JINDO });
|
||||
}
|
||||
|
||||
void HandleOnHit()
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
if (caster)
|
||||
caster->CastSpell(caster, SPELL_SUMMON_SHADE_OF_JINDO, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnHit += SpellHitFn(spell_delusions_of_jindo::HandleOnHit);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_jindo()
|
||||
{
|
||||
new boss_jindo();
|
||||
new npc_healing_ward();
|
||||
new npc_shade_of_jindo();
|
||||
RegisterZulGurubCreatureAI(boss_jindo);
|
||||
RegisterZulGurubCreatureAI(npc_healing_ward);
|
||||
RegisterZulGurubCreatureAI(npc_shade_of_jindo);
|
||||
RegisterSpellScript(spell_random_aggro);
|
||||
RegisterSpellScript(spell_delusions_of_jindo);
|
||||
}
|
||||
|
||||
@@ -71,9 +71,6 @@ public:
|
||||
Initialize();
|
||||
}
|
||||
|
||||
bool Enraged;
|
||||
bool WasDead;
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
Enraged = false;
|
||||
@@ -90,17 +87,16 @@ public:
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->LoadEquipment(1, true);
|
||||
|
||||
if (Creature* zealot = instance->GetCreature(DATA_LORKHAN))
|
||||
{
|
||||
zealot->AI()->Reset();
|
||||
zealot->ResetFaction();
|
||||
}
|
||||
|
||||
if (Creature* zealot = instance->GetCreature(DATA_ZATH))
|
||||
{
|
||||
zealot->AI()->Reset();
|
||||
zealot->ResetFaction();
|
||||
}
|
||||
|
||||
_scheduler.SetValidator([this]
|
||||
@@ -148,7 +144,7 @@ public:
|
||||
CheckPhaseTransition();
|
||||
|
||||
_scheduler.Schedule(10s, [this, data](TaskContext /*context*/) {
|
||||
if ((!_lorkhanDied || !_zathDied) && !WasDead)
|
||||
if (!_lorkhanDied || !_zathDied || !WasDead)
|
||||
{
|
||||
ReviveZealot(data);
|
||||
}
|
||||
@@ -157,19 +153,24 @@ public:
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (!WasDead && damage >= me->GetHealth())
|
||||
if (!me->HasAura(SPELL_TIGER_FORM) && damage >= me->GetHealth())
|
||||
{
|
||||
damage = me->GetHealth() - 1;
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetStandState(UNIT_STAND_STATE_SLEEP);
|
||||
me->AttackStop();
|
||||
WasDead = true;
|
||||
CheckPhaseTransition();
|
||||
Talk(EMOTE_THEKAL_DIES);
|
||||
|
||||
if (!WasDead)
|
||||
{
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetStandState(UNIT_STAND_STATE_SLEEP);
|
||||
me->AttackStop();
|
||||
DoResetThreat();
|
||||
WasDead = true;
|
||||
CheckPhaseTransition();
|
||||
Talk(EMOTE_THEKAL_DIES);
|
||||
}
|
||||
}
|
||||
|
||||
if (!Enraged && me->HealthBelowPctDamaged(20, damage) && me->GetEntry() != NPC_HIGH_PRIEST_THEKAL)
|
||||
if (!Enraged && me->HealthBelowPctDamaged(20, damage) && me->HasAura(SPELL_TIGER_FORM))
|
||||
{
|
||||
DoCastSelf(SPELL_ENRAGE);
|
||||
Enraged = true;
|
||||
@@ -182,7 +183,7 @@ public:
|
||||
{
|
||||
me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->ResetFaction();
|
||||
me->RestoreFaction();
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->SetFullHealth();
|
||||
WasDead = false;
|
||||
@@ -202,11 +203,8 @@ public:
|
||||
{
|
||||
if (Creature* zealot = instance->GetCreature(zealotData))
|
||||
{
|
||||
zealot->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
zealot->ResetFaction();
|
||||
zealot->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
zealot->SetReactState(REACT_AGGRESSIVE);
|
||||
zealot->SetFullHealth();
|
||||
zealot->Respawn(true);
|
||||
zealot->SetInCombatWithZone();
|
||||
UpdateZealotStatus(zealotData, false);
|
||||
}
|
||||
}
|
||||
@@ -231,10 +229,10 @@ public:
|
||||
Talk(SAY_AGGRO);
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
DoResetThreat();
|
||||
|
||||
_scheduler.Schedule(6s, [this](TaskContext /*context*/) {
|
||||
DoCastSelf(SPELL_TIGER_FORM);
|
||||
me->LoadEquipment(0, true);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
_scheduler.Schedule(30s, [this](TaskContext context) {
|
||||
@@ -261,7 +259,10 @@ public:
|
||||
else
|
||||
{
|
||||
_scheduler.Schedule(10s, [this](TaskContext /*context*/) {
|
||||
DoAction(ACTION_RESSURRECT);
|
||||
if (!(WasDead && _lorkhanDied && _zathDied))
|
||||
{
|
||||
DoAction(ACTION_RESSURRECT);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -271,6 +272,8 @@ public:
|
||||
GuidVector _catGuids;
|
||||
bool _lorkhanDied;
|
||||
bool _zathDied;
|
||||
bool Enraged;
|
||||
bool WasDead;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
@@ -295,10 +298,6 @@ public:
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
_scheduler.CancelAll();
|
||||
|
||||
_scheduler.SetValidator([this]
|
||||
@@ -339,24 +338,13 @@ public:
|
||||
});
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (damage >= me->GetHealth() && me->HasReactState(REACT_AGGRESSIVE))
|
||||
Talk(EMOTE_ZEALOT_DIES);
|
||||
|
||||
if (Creature* thekal = instance->GetCreature(DATA_THEKAL))
|
||||
{
|
||||
Talk(EMOTE_ZEALOT_DIES);
|
||||
me->RemoveAllAuras();
|
||||
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetStandState(UNIT_STAND_STATE_SLEEP);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
me->AttackStop();
|
||||
|
||||
damage = 0;
|
||||
|
||||
if (Creature* thekal = instance->GetCreature(DATA_THEKAL))
|
||||
{
|
||||
thekal->AI()->SetData(ACTION_RESSURRECT, DATA_LORKHAN);
|
||||
}
|
||||
thekal->AI()->SetData(ACTION_RESSURRECT, DATA_LORKHAN);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,10 +383,6 @@ public:
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
_scheduler.CancelAll();
|
||||
|
||||
_scheduler.SetValidator([this]
|
||||
@@ -436,23 +420,13 @@ public:
|
||||
});
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (damage >= me->GetHealth() && me->HasReactState(REACT_AGGRESSIVE))
|
||||
Talk(EMOTE_ZEALOT_DIES);
|
||||
|
||||
if (Creature* thekal = instance->GetCreature(DATA_THEKAL))
|
||||
{
|
||||
Talk(EMOTE_ZEALOT_DIES);
|
||||
me->RemoveAllAuras();
|
||||
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetStandState(UNIT_STAND_STATE_SLEEP);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->AttackStop();
|
||||
|
||||
damage = 0;
|
||||
|
||||
if (Creature* thekal = instance->GetCreature(DATA_THEKAL))
|
||||
{
|
||||
thekal->AI()->SetData(ACTION_RESSURRECT, DATA_ZATH);
|
||||
}
|
||||
thekal->AI()->SetData(ACTION_RESSURRECT, DATA_ZATH);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,6 @@ public:
|
||||
instance_zulgurub_InstanceMapScript(Map* map) : InstanceScript(map)
|
||||
{
|
||||
SetBossNumber(EncounterCount);
|
||||
LoadObjectData(creatureData, nullptr);
|
||||
LoadDoorData(doorData);
|
||||
LoadObjectData(creatureData, nullptr);
|
||||
}
|
||||
@@ -83,6 +82,12 @@ public:
|
||||
case NPC_GAHZRANKA:
|
||||
_gahzrankaGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_GRILEK:
|
||||
case NPC_HAZZARAH:
|
||||
case NPC_RENATAKI:
|
||||
case NPC_WUSHOOLAY:
|
||||
_edgeOfMadnessGUID = creature->GetGUID();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -120,6 +125,8 @@ public:
|
||||
return _goGongOfBethekkGUID;
|
||||
case DATA_HAKKAR:
|
||||
return _hakkarGUID;
|
||||
case DATA_EDGE_OF_MADNESS:
|
||||
return _edgeOfMadnessGUID;
|
||||
}
|
||||
|
||||
return ObjectGuid::Empty;
|
||||
@@ -135,6 +142,36 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RemoveHakkarPowerStack()
|
||||
{
|
||||
if (Creature* hakkar = instance->GetCreature(_hakkarGUID))
|
||||
{
|
||||
hakkar->CastSpell(hakkar, SPELL_HAKKAR_POWER_DOWN, true);
|
||||
}
|
||||
}
|
||||
|
||||
bool SetBossState(uint32 type, EncounterState state) override
|
||||
{
|
||||
if (!InstanceScript::SetBossState(type, state))
|
||||
return false;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DATA_JEKLIK:
|
||||
case DATA_VENOXIS:
|
||||
case DATA_MARLI:
|
||||
case DATA_ARLOKK:
|
||||
case DATA_THEKAL:
|
||||
if (state == DONE)
|
||||
RemoveHakkarPowerStack();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string GetSaveData() override
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
@@ -187,6 +224,7 @@ public:
|
||||
ObjectGuid _goGongOfBethekkGUID;
|
||||
ObjectGuid _hakkarGUID;
|
||||
ObjectGuid _gahzrankaGUID;
|
||||
ObjectGuid _edgeOfMadnessGUID;
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
||||
@@ -224,6 +262,14 @@ struct go_brazier_of_madness : public GameObjectAI
|
||||
return true;
|
||||
}
|
||||
|
||||
if (InstanceScript* instanceScript = me->GetInstanceScript())
|
||||
{
|
||||
if (instanceScript->GetGuidData(DATA_EDGE_OF_MADNESS))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 bossEntry = 0;
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
{
|
||||
|
||||
@@ -76,6 +76,12 @@ enum GameobjectIds
|
||||
GO_GONG_OF_BETHEKK = 180526 // Arlokk Event
|
||||
};
|
||||
|
||||
enum SpellIds
|
||||
{
|
||||
SPELL_HAKKAR_POWER = 24692,
|
||||
SPELL_HAKKAR_POWER_DOWN = 24693
|
||||
};
|
||||
|
||||
template <class AI, class T>
|
||||
inline AI* GetZulGurubAI(T* obj)
|
||||
{
|
||||
|
||||
@@ -453,7 +453,8 @@ enum eJuggle
|
||||
|
||||
SPELL_TORCH_CHECK = 45644,
|
||||
SPELL_GIVE_TORCH = 45280,
|
||||
QUEST_CHECK = 11937,
|
||||
QUEST_TORCH_CATCHING_A = 11657,
|
||||
QUEST_TORCH_CATCHING_H = 11923
|
||||
};
|
||||
|
||||
class spell_midsummer_juggling_torch : public SpellScript
|
||||
@@ -507,6 +508,36 @@ class spell_midsummer_juggling_torch : public SpellScript
|
||||
}
|
||||
};
|
||||
|
||||
// 45644 - Juggle Torch (Catch)
|
||||
class spell_midsummer_torch_catch : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_midsummer_torch_catch);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_GIVE_TORCH });
|
||||
}
|
||||
|
||||
void HandleDummy(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Player* player = GetHitPlayer();
|
||||
if (!player)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->GetQuestStatus(QUEST_TORCH_CATCHING_A) == QUEST_STATUS_REWARDED || player->GetQuestStatus(QUEST_TORCH_CATCHING_H) == QUEST_STATUS_REWARDED)
|
||||
{
|
||||
player->CastSpell(player, SPELL_GIVE_TORCH);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_midsummer_torch_catch::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_event_midsummer_scripts()
|
||||
{
|
||||
// NPCs
|
||||
@@ -520,4 +551,5 @@ void AddSC_event_midsummer_scripts()
|
||||
RegisterSpellScript(spell_midsummer_torch_quest);
|
||||
RegisterSpellScript(spell_midsummer_fling_torch);
|
||||
RegisterSpellScript(spell_midsummer_juggling_torch);
|
||||
RegisterSpellScript(spell_midsummer_torch_catch);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "AreaBoundary.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "azjol_nerub.h"
|
||||
@@ -34,6 +35,13 @@ ObjectData const creatureData[] =
|
||||
{ NPC_HADRONOX, DATA_HADRONOX_EVENT }
|
||||
};
|
||||
|
||||
BossBoundaryData const boundaries =
|
||||
{
|
||||
{ DATA_KRIKTHIR_THE_GATEWATCHER_EVENT, new RectangleBoundary(400.0f, 580.0f, 623.5f, 810.0f) },
|
||||
{ DATA_HADRONOX_EVENT, new ZRangeBoundary(666.0f, 776.0f) },
|
||||
{ DATA_ANUBARAK_EVENT, new CircleBoundary(Position(550.6178f, 253.5917f), 26.0f) }
|
||||
};
|
||||
|
||||
class instance_azjol_nerub : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
@@ -44,6 +52,7 @@ public:
|
||||
instance_azjol_nerub_InstanceScript(Map* map) : InstanceScript(map)
|
||||
{
|
||||
SetBossNumber(MAX_ENCOUNTERS);
|
||||
LoadBossBoundaries(boundaries);
|
||||
LoadDoorData(doorData);
|
||||
LoadObjectData(creatureData, nullptr);
|
||||
};
|
||||
|
||||
@@ -125,20 +125,27 @@ public:
|
||||
{
|
||||
if (HealthBelowPct(50) && !health50)
|
||||
{
|
||||
WorldObject* summoner = nullptr;
|
||||
if (TempSummon const* tempSummon = me->ToTempSummon())
|
||||
{
|
||||
summoner = tempSummon->GetSummonerUnit();
|
||||
if (WorldObject* summoner = tempSummon->GetSummonerUnit())
|
||||
{
|
||||
Talk(SAY_TURMOIL_HALF_HP, summoner);
|
||||
}
|
||||
}
|
||||
|
||||
Talk(SAY_TURMOIL_HALF_HP, summoner);
|
||||
health50 = true;
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_TURMOIL_DEATH, me->ToTempSummon()->GetSummonerUnit()->ToPlayer());
|
||||
if (TempSummon const* tempSummon = me->ToTempSummon())
|
||||
{
|
||||
if (WorldObject* summoner = tempSummon->GetSummonerUnit())
|
||||
{
|
||||
Talk(SAY_TURMOIL_DEATH, summoner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setphase(short newPhase)
|
||||
|
||||
@@ -268,7 +268,19 @@ public:
|
||||
{
|
||||
Talk(SAY_YSONDRE_SUMMON_DRUIDS);
|
||||
|
||||
for (uint8 i = 0; i < 10; ++i)
|
||||
auto const& attackers = me->GetThreatMgr().getThreatList();
|
||||
uint8 attackersCount = 0;
|
||||
|
||||
for (const auto attacker : attackers)
|
||||
{
|
||||
if ((*attacker)->ToPlayer() && (*attacker)->IsAlive())
|
||||
++attackersCount;
|
||||
}
|
||||
|
||||
uint8 amount = attackersCount < 30 ? attackersCount * 0.5f : 15;
|
||||
amount = amount < 1 ? 1 : amount;
|
||||
|
||||
for (uint8 i = 0; i < amount; ++i)
|
||||
DoCast(me, SPELL_SUMMON_DRUID_SPIRITS, true);
|
||||
++_stage;
|
||||
}
|
||||
@@ -643,6 +655,12 @@ public:
|
||||
emerald_dragonAI::UpdateAI(diff);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
_JustDied();
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
|
||||
}
|
||||
|
||||
private:
|
||||
bool _banished; // used for shades activation testing
|
||||
uint32 _banishedTimer; // counter for banishment timeout
|
||||
|
||||
@@ -821,19 +821,19 @@ public:
|
||||
if (!IsHolidayActive(HOLIDAY_FIRE_FESTIVAL))
|
||||
break;
|
||||
|
||||
Map::PlayerList const& players = me->GetMap()->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
std::list<Player*> targets;
|
||||
Acore::AnyPlayerInObjectRangeCheck check(me, me->GetVisibilityRange(), false);
|
||||
Acore::PlayerListSearcherWithSharedVision<Acore::AnyPlayerInObjectRangeCheck> searcher(me, targets, check);
|
||||
Cell::VisitWorldObjects(me, searcher, me->GetVisibilityRange());
|
||||
for (Player* player : targets)
|
||||
{
|
||||
if (Player* player = itr->GetSource())
|
||||
if (player->GetTeamId() == TEAM_HORDE)
|
||||
{
|
||||
if (player->GetTeamId() == TEAM_HORDE)
|
||||
{
|
||||
me->PlayDirectMusic(EVENTMIDSUMMERFIREFESTIVAL_H, player);
|
||||
}
|
||||
else
|
||||
{
|
||||
me->PlayDirectMusic(EVENTMIDSUMMERFIREFESTIVAL_A, player);
|
||||
}
|
||||
me->PlayDirectMusic(EVENTMIDSUMMERFIREFESTIVAL_H, player);
|
||||
}
|
||||
else
|
||||
{
|
||||
me->PlayDirectMusic(EVENTMIDSUMMERFIREFESTIVAL_A, player);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -769,13 +769,12 @@ public:
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Active = true;
|
||||
CanIteract = 3500;
|
||||
Active = false;
|
||||
CanIteract = 0;
|
||||
DoCast(me, SPELL_BRAZIER, true);
|
||||
DoCast(me, SPELL_FIERY_AURA, false);
|
||||
me->UpdateHeight(me->GetPositionZ() + 0.94f);
|
||||
me->SetDisableGravity(true);
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_DANCE);
|
||||
me->SendMovementFlagUpdate();
|
||||
}
|
||||
|
||||
|
||||
@@ -536,7 +536,7 @@ enum SpellAttr4 : uint32
|
||||
// EnumUtils: DESCRIBE THIS
|
||||
enum SpellAttr5 : uint32
|
||||
{
|
||||
SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL = 0x00000001, // TITLE Can be channeled while moving
|
||||
SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL = 0x00000001, // TITLE Can be channeled while moving/casting
|
||||
SPELL_ATTR5_NO_REAGENT_COST_WITH_AURA = 0x00000002, // TITLE No reagents during arena preparation
|
||||
SPELL_ATTR5_REMOVE_ENTERING_ARENA = 0x00000004, // TITLE Remove when entering arena DESCRIPTION Force this aura to be removed on entering arena, regardless of other properties
|
||||
SPELL_ATTR5_ALLOW_WHILE_STUNNED = 0x00000008, // TITLE Usable while stunned
|
||||
|
||||
@@ -802,7 +802,7 @@ AC_API_EXPORT EnumText EnumUtils<SpellAttr5>::ToString(SpellAttr5 value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL: return { "SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL", "Can be channeled while moving", "" };
|
||||
case SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL: return { "SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL", "Can be channeled while moving/casting", "" };
|
||||
case SPELL_ATTR5_NO_REAGENT_COST_WITH_AURA: return { "SPELL_ATTR5_NO_REAGENT_COST_WITH_AURA", "No reagents during arena preparation", "" };
|
||||
case SPELL_ATTR5_REMOVE_ENTERING_ARENA: return { "SPELL_ATTR5_REMOVE_ENTERING_ARENA", "Remove when entering arena", "Force this aura to be removed on entering arena, regardless of other properties" };
|
||||
case SPELL_ATTR5_ALLOW_WHILE_STUNNED: return { "SPELL_ATTR5_ALLOW_WHILE_STUNNED", "Usable while stunned", "" };
|
||||
|
||||
Reference in New Issue
Block a user