aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Chat/Chat.cpp18
-rw-r--r--src/server/game/Chat/Chat.h2
-rw-r--r--src/server/game/Chat/ChatLink.cpp3
-rw-r--r--src/server/game/DataStores/DBCStores.cpp2
-rw-r--r--src/server/game/DataStores/DBCStores.h1
-rw-r--r--src/server/game/DataStores/DBCStructure.h31
-rw-r--r--src/server/game/DataStores/DBCfmt.h7
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp11
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h2
-rw-r--r--src/server/game/Entities/Object/Object.cpp117
-rw-r--r--src/server/game/Entities/Player/Player.cpp3
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp36
-rw-r--r--src/server/game/Handlers/ChatHandler.cpp16
-rw-r--r--src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp5
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp2
-rw-r--r--src/server/game/Spells/SpellEffects.cpp3
-rw-r--r--src/server/game/Spells/SpellMgr.cpp6
-rw-r--r--src/server/game/World/World.cpp11
-rw-r--r--src/server/game/World/World.h9
-rw-r--r--src/server/scripts/Commands/cs_gobject.cpp11
-rw-r--r--src/server/scripts/Commands/cs_mmaps.cpp4
-rw-r--r--src/server/scripts/Commands/cs_modify.cpp10
-rw-r--r--src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp13
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp4
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp7
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp2
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp194
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp45
-rw-r--r--src/server/scripts/Spells/spell_quest.cpp41
-rw-r--r--src/server/scripts/Spells/spell_warrior.cpp23
-rw-r--r--src/server/scripts/World/chat_log.cpp225
-rw-r--r--src/server/shared/Debugging/WheatyExceptionReport.cpp146
-rw-r--r--src/server/shared/Debugging/WheatyExceptionReport.h5
-rw-r--r--src/server/shared/Logging/Log.cpp12
-rw-r--r--src/server/shared/Logging/Log.h6
-rw-r--r--src/server/worldserver/worldserver.conf.dist72
36 files changed, 590 insertions, 515 deletions
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index 2d2266a865d..d77ee5b7f61 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -782,6 +782,24 @@ Creature* ChatHandler::getSelectedCreature()
return ObjectAccessor::GetCreatureOrPetOrVehicle(*m_session->GetPlayer(), m_session->GetPlayer()->GetTarget());
}
+Player* ChatHandler::getSelectedPlayerOrSelf()
+{
+ if (!m_session)
+ return NULL;
+
+ uint64 selected = m_session->GetPlayer()->GetTarget();
+ if (!selected)
+ return m_session->GetPlayer();
+
+ // first try with selected target
+ Player* targetPlayer = ObjectAccessor::FindPlayer(selected);
+ // if the target is not a player, then return self
+ if (!targetPlayer)
+ targetPlayer = m_session->GetPlayer();
+
+ return targetPlayer;
+}
+
char* ChatHandler::extractKeyFromLink(char* text, char const* linkType, char** something1)
{
// skip empty
diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h
index f9000f636c5..a56b79077d7 100644
--- a/src/server/game/Chat/Chat.h
+++ b/src/server/game/Chat/Chat.h
@@ -97,6 +97,8 @@ class ChatHandler
Creature* getSelectedCreature();
Unit* getSelectedUnit();
WorldObject* getSelectedObject();
+ // Returns either the selected player or self if there is no selected player
+ Player* getSelectedPlayerOrSelf();
char* extractKeyFromLink(char* text, char const* linkType, char** something1 = NULL);
char* extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1 = NULL);
diff --git a/src/server/game/Chat/ChatLink.cpp b/src/server/game/Chat/ChatLink.cpp
index 66758930f7f..12f4b082a9c 100644
--- a/src/server/game/Chat/ChatLink.cpp
+++ b/src/server/game/Chat/ChatLink.cpp
@@ -314,7 +314,8 @@ bool SpellChatLink::ValidateName(char* buffer, const char* context)
// found the prefix, remove it to perform spellname validation below
// -2 = strlen(": ")
uint32 spellNameLength = strlen(buffer) - skillLineNameLength - 2;
- memcpy(buffer, buffer + skillLineNameLength + 2, spellNameLength + 1);
+ memmove(buffer, buffer + skillLineNameLength + 2, spellNameLength + 1);
+ break;
}
}
}
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp
index 37f4f4c1930..9b0465a4536 100644
--- a/src/server/game/DataStores/DBCStores.cpp
+++ b/src/server/game/DataStores/DBCStores.cpp
@@ -73,6 +73,7 @@ DBCStorage <ChrClassesEntry> sChrClassesStore(ChrClassesEntryfmt);
DBCStorage <ChrRacesEntry> sChrRacesStore(ChrRacesEntryfmt);
DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore(CinematicSequencesEntryfmt);
DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore(CreatureDisplayInfofmt);
+DBCStorage <CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore(CreatureDisplayInfoExtrafmt);
DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore(CreatureFamilyfmt);
DBCStorage <CreatureModelDataEntry> sCreatureModelDataStore(CreatureModelDatafmt);
DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore(CreatureSpellDatafmt);
@@ -306,6 +307,7 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales, bad_dbc_files, sChrRacesStore, dbcPath, "ChrRaces.dbc");
LoadDBC(availableDbcLocales, bad_dbc_files, sCinematicSequencesStore, dbcPath, "CinematicSequences.dbc");
LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoStore, dbcPath, "CreatureDisplayInfo.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoExtraStore, dbcPath, "CreatureDisplayInfoExtra.dbc");
LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureFamilyStore, dbcPath, "CreatureFamily.dbc");
LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureModelDataStore, dbcPath, "CreatureModelData.dbc");
LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureSpellDataStore, dbcPath, "CreatureSpellData.dbc");
diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h
index 39747141322..b77db950541 100644
--- a/src/server/game/DataStores/DBCStores.h
+++ b/src/server/game/DataStores/DBCStores.h
@@ -92,6 +92,7 @@ extern DBCStorage <ChrClassesEntry> sChrClassesStore;
extern DBCStorage <ChrRacesEntry> sChrRacesStore;
extern DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore;
extern DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore;
+extern DBCStorage <CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore;
extern DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore;
extern DBCStorage <CreatureModelDataEntry> sCreatureModelDataStore;
extern DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore;
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index 976b4355957..abe7bde4bf5 100644
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -690,7 +690,7 @@ struct ChrClassesEntry
struct ChrRacesEntry
{
uint32 RaceID; // 0
- // 1 unused
+ uint32 Flags; // 1
uint32 FactionID; // 2 facton template id
// 3 unused
uint32 model_m; // 4
@@ -736,7 +736,7 @@ struct CreatureDisplayInfoEntry
uint32 Displayid; // 0 m_ID
uint32 ModelId; // 1 m_modelID
// 2 m_soundID
- // 3 m_extendedDisplayInfoID
+ uint32 ExtraId; // 3 m_extendedDisplayInfoID
float scale; // 4 m_creatureModelScale
// 5 m_creatureModelAlpha
// 6-8 m_textureVariation[3]
@@ -749,6 +749,31 @@ struct CreatureDisplayInfoEntry
// 15 m_objectEffectPackageID
};
+struct CreatureDisplayInfoExtraEntry
+{
+ //uint32 Id; // 0
+ uint32 Race; // 1
+ uint32 Gender; // 2
+ //uint32 SkinColor; // 3
+ //uint32 FaceType; // 4
+ //uint32 HairType; // 5
+ //uint32 HairStyle; // 6
+ //uint32 FacialHair; // 7
+ //uint32 HelmDisplayId; // 8
+ //uint32 ShoulderDisplayId; // 9
+ //uint32 ShirtDisplayId; // 10
+ //uint32 ChestDisplayId; // 11
+ //uint32 BeltDisplayId; // 12
+ //uint32 LegsDisplayId; // 13
+ //uint32 BootsDisplayId; // 14
+ //uint32 WristDisplayId; // 15
+ //uint32 GlovesDisplayId; // 16
+ //uint32 TabardDisplayId; // 17
+ //uint32 CloakDisplayId; // 18
+ //uint32 CanEquip; // 19
+ //char const* Texture; // 20
+};
+
struct CreatureFamilyEntry
{
uint32 ID; // 0 m_ID
@@ -768,7 +793,7 @@ struct CreatureFamilyEntry
struct CreatureModelDataEntry
{
uint32 Id;
- //uint32 Flags;
+ uint32 Flags;
//char* ModelPath[16]
//uint32 Unk1;
float Scale; // Used in calculation of unit collision data
diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h
index 448a8066434..35a8eecb708 100644
--- a/src/server/game/DataStores/DBCfmt.h
+++ b/src/server/game/DataStores/DBCfmt.h
@@ -36,11 +36,12 @@ char const CharStartOutfitEntryfmt[] = "dbbbXiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxx
char const CharTitlesEntryfmt[] = "nxssssssssssssssssxssssssssssssssssxi";
char const ChatChannelsEntryfmt[] = "nixssssssssssssssssxxxxxxxxxxxxxxxxxx";
char const ChrClassesEntryfmt[] = "nxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii";
-char const ChrRacesEntryfmt[] = "nxixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi";
+char const ChrRacesEntryfmt[] = "niixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi";
char const CinematicSequencesEntryfmt[] = "nxxxxxxxxx";
-char const CreatureDisplayInfofmt[] = "nixxfxxxxxxxxxxx";
+char const CreatureDisplayInfofmt[] = "nixifxxxxxxxxxxx";
+char const CreatureDisplayInfoExtrafmt[] = "diixxxxxxxxxxxxxxxxxx";
char const CreatureFamilyfmt[] = "nfifiiiiixssssssssssssssssxx";
-char const CreatureModelDatafmt[] = "nxxxfxxxxxxxxxxffxxxxxxxxxxx";
+char const CreatureModelDatafmt[] = "nixxfxxxxxxxxxxffxxxxxxxxxxx";
char const CreatureSpellDatafmt[] = "niiiixxxx";
char const CreatureTypefmt[] = "nxxxxxxxxxxxxxxxxxx";
char const CurrencyTypesfmt[] = "xnxi";
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 67f7b1a46b2..cdd9e1441e7 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -52,7 +52,7 @@ GameObject::GameObject() : WorldObject(false), MapObject(),
m_spellId = 0;
m_cooldownTime = 0;
m_goInfo = NULL;
- m_ritualOwner = NULL;
+ m_ritualOwnerGUID = 0;
m_goData = NULL;
m_DBTableGuid = 0;
@@ -1444,9 +1444,16 @@ void GameObject::Use(Unit* user)
GameObjectTemplate const* info = GetGOInfo();
+ Player* m_ritualOwner = NULL;
+ if (m_ritualOwnerGUID)
+ m_ritualOwner = ObjectAccessor::FindPlayer(m_ritualOwnerGUID);
+
// ritual owner is set for GO's without owner (not summoned)
if (!m_ritualOwner && !owner)
+ {
+ m_ritualOwnerGUID = player->GetGUID();
m_ritualOwner = player;
+ }
if (owner)
{
@@ -1517,7 +1524,7 @@ void GameObject::Use(Unit* user)
else
{
// reset ritual for this GO
- m_ritualOwner = NULL;
+ m_ritualOwnerGUID = 0;
m_unique_users.clear();
m_usetimes = 0;
}
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index 48db64a3687..581208f1abd 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -846,7 +846,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map
// For traps this: spell casting cooldown, for doors/buttons: reset time.
std::list<uint32> m_SkillupList;
- Player* m_ritualOwner; // used for GAMEOBJECT_TYPE_SUMMONING_RITUAL where GO is not summoned (no owner)
+ uint64 m_ritualOwnerGUID; // used for GAMEOBJECT_TYPE_SUMMONING_RITUAL where GO is not summoned (no owner)
std::set<uint64> m_unique_users;
uint32 m_usetimes;
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 69f7073ce1b..c0a54060298 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -2489,125 +2489,36 @@ void WorldObject::GetNearPoint(WorldObject const* /*searcher*/, float &x, float
{
GetNearPoint2D(x, y, distance2d+searcher_size, absAngle);
z = GetPositionZ();
+ // Should "searcher" be used instead of "this" when updating z coordinate ?
UpdateAllowedPositionZ(x, y, z);
- /*
// if detection disabled, return first point
- if (!sWorld->getIntConfig(CONFIG_DETECT_POS_COLLISION))
- {
- UpdateGroundPositionZ(x, y, z); // update to LOS height if available
+ if (!sWorld->getBoolConfig(CONFIG_DETECT_POS_COLLISION))
return;
- }
- // or remember first point
- float first_x = x;
- float first_y = y;
- bool first_los_conflict = false; // first point LOS problems
-
- // prepare selector for work
- ObjectPosSelector selector(GetPositionX(), GetPositionY(), GetObjectSize(), distance2d+searcher_size);
-
- // adding used positions around object
- {
- CellCoord p(Trinity::ComputeCellCoord(GetPositionX(), GetPositionY()));
- Cell cell(p);
- cell.SetNoCreate();
-
- Trinity::NearUsedPosDo u_do(*this, searcher, absAngle, selector);
- Trinity::WorldObjectWorker<Trinity::NearUsedPosDo> worker(this, u_do);
-
- TypeContainerVisitor<Trinity::WorldObjectWorker<Trinity::NearUsedPosDo>, GridTypeMapContainer > grid_obj_worker(worker);
- TypeContainerVisitor<Trinity::WorldObjectWorker<Trinity::NearUsedPosDo>, WorldTypeMapContainer > world_obj_worker(worker);
-
- CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, grid_obj_worker, *GetMap(), *this, distance2d);
- cell_lock->Visit(cell_lock, world_obj_worker, *GetMap(), *this, distance2d);
- }
-
- // maybe can just place in primary position
- if (selector.CheckOriginal())
- {
- UpdateGroundPositionZ(x, y, z); // update to LOS height if available
-
- if (IsWithinLOS(x, y, z))
- return;
-
- first_los_conflict = true; // first point have LOS problems
- }
-
- float angle; // candidate of angle for free pos
-
- // special case when one from list empty and then empty side preferred
- if (selector.FirstAngle(angle))
- {
- GetNearPoint2D(x, y, distance2d, absAngle+angle);
- z = GetPositionZ();
- UpdateGroundPositionZ(x, y, z); // update to LOS height if available
-
- if (IsWithinLOS(x, y, z))
- return;
- }
-
- // set first used pos in lists
- selector.InitializeAngle();
-
- // select in positions after current nodes (selection one by one)
- while (selector.NextAngle(angle)) // angle for free pos
- {
- GetNearPoint2D(x, y, distance2d, absAngle+angle);
- z = GetPositionZ();
- UpdateGroundPositionZ(x, y, z); // update to LOS height if available
-
- if (IsWithinLOS(x, y, z))
- return;
- }
-
- // BAD NEWS: not free pos (or used or have LOS problems)
- // Attempt find _used_ pos without LOS problem
-
- if (!first_los_conflict)
- {
- x = first_x;
- y = first_y;
-
- UpdateGroundPositionZ(x, y, z); // update to LOS height if available
+ // return if the point is already in LoS
+ if (IsWithinLOS(x, y, z))
return;
- }
-
- // special case when one from list empty and then empty side preferred
- if (selector.IsNonBalanced())
- {
- if (!selector.FirstAngle(angle)) // _used_ pos
- {
- GetNearPoint2D(x, y, distance2d, absAngle+angle);
- z = GetPositionZ();
- UpdateGroundPositionZ(x, y, z); // update to LOS height if available
-
- if (IsWithinLOS(x, y, z))
- return;
- }
- }
- // set first used pos in lists
- selector.InitializeAngle();
+ // remember first point
+ float first_x = x;
+ float first_y = y;
+ float first_z = z;
- // select in positions after current nodes (selection one by one)
- while (selector.NextUsedAngle(angle)) // angle for used pos but maybe without LOS problem
+ // loop in a circle to look for a point in LoS using small steps
+ for (float angle = M_PI / 8; angle < M_PI * 2; angle += M_PI / 8)
{
- GetNearPoint2D(x, y, distance2d, absAngle+angle);
+ GetNearPoint2D(x, y, distance2d + searcher_size, absAngle + angle);
z = GetPositionZ();
- UpdateGroundPositionZ(x, y, z); // update to LOS height if available
-
+ UpdateAllowedPositionZ(x, y, z);
if (IsWithinLOS(x, y, z))
return;
}
- // BAD BAD NEWS: all found pos (free and used) have LOS problem :(
+ // still not in LoS, give up and return first position found
x = first_x;
y = first_y;
-
- UpdateGroundPositionZ(x, y, z); // update to LOS height if available
- */
+ z = first_z;
}
void WorldObject::GetClosePoint(float &x, float &y, float &z, float size, float distance2d /*= 0*/, float angle /*= 0*/) const
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index e8bb7981c79..2691a6870f2 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -25058,6 +25058,9 @@ void Player::HandleFall(MovementInfo const& movementInfo)
if (damageperc > 0)
{
uint32 damage = (uint32)(damageperc * GetMaxHealth()*sWorld->getRate(RATE_DAMAGE_FALL));
+
+ if (GetCommandStatus(CHEAT_GOD))
+ damage = 0;
float height = movementInfo.pos.m_positionZ;
UpdateGroundPositionZ(movementInfo.pos.m_positionX, movementInfo.pos.m_positionY, height);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 98072e11632..9cc214b7390 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -2515,7 +2515,7 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spellInfo
// Chance hit from victim SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE auras
modHitChance += victim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE, schoolMask);
// Reduce spell hit chance for Area of effect spells from victim SPELL_AURA_MOD_AOE_AVOIDANCE aura
- if (spellInfo->IsTargetingArea())
+ if (spellInfo->IsAffectingArea())
modHitChance -= victim->GetTotalAuraModifier(SPELL_AURA_MOD_AOE_AVOIDANCE);
// Decrease hit chance from victim rating bonus
@@ -10443,7 +10443,7 @@ bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMas
default:
return false;
}
- break;
+ // Do not add a break here, case fallthrough is intentional! Adding a break will make above spells unable to crit.
case SPELL_DAMAGE_CLASS_MAGIC:
{
if (schoolMask & SPELL_SCHOOL_MASK_NORMAL)
@@ -13051,9 +13051,35 @@ bool Unit::IsInFeralForm() const
bool Unit::IsInDisallowedMountForm() const
{
- ShapeshiftForm form = GetShapeshiftForm();
- return form != FORM_NONE && form != FORM_BATTLESTANCE && form != FORM_BERSERKERSTANCE && form != FORM_DEFENSIVESTANCE &&
- form != FORM_SHADOW && form != FORM_STEALTH && form != FORM_UNDEAD;
+ if (ShapeshiftForm form = GetShapeshiftForm())
+ {
+ SpellShapeshiftEntry const* shapeshift = sSpellShapeshiftStore.LookupEntry(form);
+ if (!shapeshift)
+ return true;
+
+ if (!(shapeshift->flags1 & 0x1))
+ return true;
+ }
+
+ if (GetDisplayId() == GetNativeDisplayId())
+ return false;
+
+ CreatureDisplayInfoEntry const* display = sCreatureDisplayInfoStore.LookupEntry(GetDisplayId());
+ if (!display)
+ return true;
+
+ CreatureDisplayInfoExtraEntry const* displayExtra = sCreatureDisplayInfoExtraStore.LookupEntry(display->ExtraId);
+ if (!displayExtra)
+ return true;
+
+ CreatureModelDataEntry const* model = sCreatureModelDataStore.LookupEntry(display->ModelId);
+ ChrRacesEntry const* race = sChrRacesStore.LookupEntry(displayExtra->Race);
+
+ if (model && !(model->Flags & 0x80))
+ if (race && !(race->Flags & 0x4))
+ return true;
+
+ return false;
}
/*#######################################
diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp
index fbc78564ea5..e0b29523a3a 100644
--- a/src/server/game/Handlers/ChatHandler.cpp
+++ b/src/server/game/Handlers/ChatHandler.cpp
@@ -107,20 +107,12 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
case CHAT_MSG_GUILD:
case CHAT_MSG_BATTLEGROUND:
case CHAT_MSG_WHISPER:
- if (sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON))
- {
- std::string msg = "";
- recvData >> msg;
-
- if (msg.empty())
- return;
-
- sScriptMgr->OnPlayerChat(sender, uint32(CHAT_MSG_ADDON), lang, msg);
- }
-
- // Disabled addon channel?
+ // check if addon messages are disabled
if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL))
+ {
+ recvData.rfinish();
return;
+ }
break;
default:
TC_LOG_ERROR("network", "Player %s (GUID: %u) sent a chatmessage with an invalid language/message type combination",
diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
index 28e58c87323..c59762066ae 100644
--- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
@@ -159,10 +159,15 @@ bool TargetedMovementGeneratorMedium<T, D>::DoUpdate(T* owner, uint32 time_diff)
if (TransportBase* transport = owner->GetDirectTransport())
transport->CalculatePassengerPosition(dest.x, dest.y, dest.z);
+ // First check distance
if (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->CanFly())
targetMoved = !i_target->IsWithinDist3d(dest.x, dest.y, dest.z, allowed_dist);
else
targetMoved = !i_target->IsWithinDist2d(dest.x, dest.y, allowed_dist);
+
+ // then, if the target is in range, check also Line of Sight.
+ if (!targetMoved)
+ targetMoved = !i_target->IsWithinLOSInMap(owner);
}
if (i_recalculateTravel || targetMoved)
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 4a0c14b4783..bd24038d88d 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -6095,7 +6095,7 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
caster->DealDamage(caster, funnelDamage, &cleanDamage, NODAMAGE, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), true);
}
- uint32 procAttacker = PROC_FLAG_DONE_PERIODIC | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS;
+ uint32 procAttacker = PROC_FLAG_DONE_PERIODIC;
uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC | PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS;
uint32 procEx = (crit ? PROC_EX_CRITICAL_HIT : PROC_EX_NORMAL_HIT) | PROC_EX_INTERNAL_HOT;
// ignore item heals
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 609c9ba05be..28bc659050a 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -3595,9 +3595,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
}
return;
}
- case 45204: // Clone Me!
- m_caster->CastSpell(unitTarget, damage, true);
- break;
case 55693: // Remove Collapsing Cave Aura
if (!unitTarget)
return;
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 0ae4b22b3e4..e8f20441605 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -2913,15 +2913,9 @@ void SpellMgr::LoadSpellInfoCorrections()
case 53096: // Quetz'lun's Judgment
spellInfo->MaxAffectedTargets = 1;
break;
- case 42730:
- spellInfo->Effects[EFFECT_1].TriggerSpell = 42739;
- break;
case 42436: // Drink! (Brewfest)
spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
break;
- case 59735:
- spellInfo->Effects[EFFECT_1].TriggerSpell = 59736;
- break;
case 52611: // Summon Skeletons
case 52612: // Summon Skeletons
spellInfo->Effects[EFFECT_0].MiscValueB = 64;
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 729dfac6497..8f2941865fa 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1177,17 +1177,6 @@ void World::LoadConfigSettings(bool reload)
m_int_configs[CONFIG_NUMTHREADS] = sConfigMgr->GetIntDefault("MapUpdate.Threads", 1);
m_int_configs[CONFIG_MAX_RESULTS_LOOKUP_COMMANDS] = sConfigMgr->GetIntDefault("Command.LookupMaxResults", 0);
- // chat logging
- m_bool_configs[CONFIG_CHATLOG_CHANNEL] = sConfigMgr->GetBoolDefault("ChatLogs.Channel", false);
- m_bool_configs[CONFIG_CHATLOG_WHISPER] = sConfigMgr->GetBoolDefault("ChatLogs.Whisper", false);
- m_bool_configs[CONFIG_CHATLOG_SYSCHAN] = sConfigMgr->GetBoolDefault("ChatLogs.SysChan", false);
- m_bool_configs[CONFIG_CHATLOG_PARTY] = sConfigMgr->GetBoolDefault("ChatLogs.Party", false);
- m_bool_configs[CONFIG_CHATLOG_RAID] = sConfigMgr->GetBoolDefault("ChatLogs.Raid", false);
- m_bool_configs[CONFIG_CHATLOG_GUILD] = sConfigMgr->GetBoolDefault("ChatLogs.Guild", false);
- m_bool_configs[CONFIG_CHATLOG_PUBLIC] = sConfigMgr->GetBoolDefault("ChatLogs.Public", false);
- m_bool_configs[CONFIG_CHATLOG_ADDON] = sConfigMgr->GetBoolDefault("ChatLogs.Addon", false);
- m_bool_configs[CONFIG_CHATLOG_BGROUND] = sConfigMgr->GetBoolDefault("ChatLogs.Battleground", false);
-
// Warden
m_bool_configs[CONFIG_WARDEN_ENABLED] = sConfigMgr->GetBoolDefault("Warden.Enabled", false);
m_int_configs[CONFIG_WARDEN_NUM_MEM_CHECKS] = sConfigMgr->GetIntDefault("Warden.NumMemChecks", 3);
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 4c43507d038..a58dcc82acc 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -139,15 +139,6 @@ enum WorldBoolConfigs
CONFIG_SHOW_KICK_IN_WORLD,
CONFIG_SHOW_MUTE_IN_WORLD,
CONFIG_SHOW_BAN_IN_WORLD,
- CONFIG_CHATLOG_CHANNEL,
- CONFIG_CHATLOG_WHISPER,
- CONFIG_CHATLOG_SYSCHAN,
- CONFIG_CHATLOG_PARTY,
- CONFIG_CHATLOG_RAID,
- CONFIG_CHATLOG_GUILD,
- CONFIG_CHATLOG_PUBLIC,
- CONFIG_CHATLOG_ADDON,
- CONFIG_CHATLOG_BGROUND,
CONFIG_AUTOBROADCAST,
CONFIG_ALLOW_TICKETS,
CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES,
diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp
index 423a47eb3c8..ce0bee0d8c5 100644
--- a/src/server/scripts/Commands/cs_gobject.cpp
+++ b/src/server/scripts/Commands/cs_gobject.cpp
@@ -166,7 +166,11 @@ public:
// fill the gameobject data and save to the db
object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMaskForSpawn());
+ // delete the old object and do a clean load from DB with a fresh new GameObject instance.
+ // this is required to avoid weird behavior and memory leaks
+ delete object;
+ object = new GameObject();
// this will generate a new guid if the object is in an instance
if (!object->LoadGameObjectFromDB(guidLow, map))
{
@@ -209,6 +213,13 @@ public:
uint32 objectId = atoi(id);
+ if (!sObjectMgr->GetGameObjectTemplate(objectId))
+ {
+ handler->PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST, objectId);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
player->SummonGameObject(objectId, x, y, z, ang, 0, 0, rot2, rot3, spawntm);
return true;
diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp
index 61598bf0945..47cb5636672 100644
--- a/src/server/scripts/Commands/cs_mmaps.cpp
+++ b/src/server/scripts/Commands/cs_mmaps.cpp
@@ -127,8 +127,8 @@ public:
int32 gx = 32 - player->GetPositionX() / SIZE_OF_GRIDS;
int32 gy = 32 - player->GetPositionY() / SIZE_OF_GRIDS;
- handler->PSendSysMessage("%03u%02i%02i.mmtile", player->GetMapId(), gy, gx);
- handler->PSendSysMessage("gridloc [%i, %i]", gx, gy);
+ handler->PSendSysMessage("%03u%02i%02i.mmtile", player->GetMapId(), gx, gy);
+ handler->PSendSysMessage("gridloc [%i, %i]", gy, gx);
// calculate navmesh tile location
dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId());
diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp
index c2d6bf47154..4cd7228a24a 100644
--- a/src/server/scripts/Commands/cs_modify.cpp
+++ b/src/server/scripts/Commands/cs_modify.cpp
@@ -476,7 +476,7 @@ public:
return false;
}
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
@@ -524,7 +524,7 @@ public:
return false;
}
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
@@ -569,7 +569,7 @@ public:
return false;
}
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
@@ -614,7 +614,7 @@ public:
return false;
}
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
@@ -659,7 +659,7 @@ public:
return false;
}
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
diff --git a/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp b/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp
index 925d0d73a70..e11e387ab0a 100644
--- a/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp
@@ -177,12 +177,13 @@ public:
if (player->GetQuestStatus(QUEST_ULAG) != QUEST_STATUS_INCOMPLETE)
return false;
- if (GameObject* pTrigger = player->FindNearestGameObject(GO_TRIGGER, 30.0f))
- {
- pTrigger->SetGoState(GO_STATE_READY);
- player->SummonCreature(NPC_ULAG, 2390.26f, 336.47f, 40.01f, 2.26f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000);
- return false;
- }
+ if (!player->FindNearestCreature(NPC_ULAG, 50.0f))
+ if (GameObject* pTrigger = player->FindNearestGameObject(GO_TRIGGER, 30.0f))
+ {
+ pTrigger->SetGoState(GO_STATE_READY);
+ player->SummonCreature(NPC_ULAG, 2390.26f, 336.47f, 40.01f, 2.26f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000);
+ return false;
+ }
return false;
}
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp
index d0b0db2e1ab..8ac095971bc 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp
@@ -229,14 +229,14 @@ class npc_onyx_flamecaller : public CreatureScript
void IsSummonedBy(Unit* /*summoner*/) OVERRIDE
{
- // Let Zarithrian count as summoner. _instance cant be null since we got GetRubySanctumAI
+ // Let Zarithrian count as summoner.
if (Creature* zarithrian = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_GENERAL_ZARITHRIAN)))
zarithrian->AI()->JustSummoned(me);
}
void WaypointReached(uint32 waypointId) OVERRIDE
{
- if (waypointId == MAX_PATH_FLAMECALLER_WAYPOINTS || waypointId == MAX_PATH_FLAMECALLER_WAYPOINTS*2)
+ if (waypointId == MAX_PATH_FLAMECALLER_WAYPOINTS - 1 || waypointId == MAX_PATH_FLAMECALLER_WAYPOINTS * 2 - 1)
{
DoZoneInCombat();
SetEscortPaused(true);
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
index c35c9ba2d11..47c876f2a52 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
@@ -394,6 +394,13 @@ class boss_halion : public CreatureScript
if (events.IsInPhase(PHASE_TWO))
return;
+ // Rough radius, it is not an exactly perfect circle
+ if (me->GetDistance2d(HalionControllerSpawnPos.GetPositionX(), HalionControllerSpawnPos.GetPositionY()) > 48.5f)
+ {
+ EnterEvadeMode();
+ return;
+ }
+
generic_halionAI::UpdateAI(diff);
}
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
index d0a25d2b216..c98a3db2334 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
@@ -116,6 +116,7 @@ class instance_ulduar : public InstanceMapScript
SetBossNumber(MAX_ENCOUNTER);
LoadDoorData(doorData);
LoadMinionData(minionData);
+ LeviathanGUID = 0;
IgnisGUID = 0;
RazorscaleGUID = 0;
RazorscaleController = 0;
@@ -154,6 +155,7 @@ class instance_ulduar : public InstanceMapScript
keepersCount = 0;
conSpeedAtory = false;
Unbroken = true;
+ IsDriveMeCrazyEligible = true;
_algalonSummoned = false;
_summonAlgalon = false;
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
index cc37dde57dd..fe29f4e9f7c 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
@@ -18,28 +18,25 @@
/* ScriptData
SDName: Boss_Ingvar_The_Plunderer
SD%Complete: 95
-SDComment: Some Problems with Annhylde Movement, Blizzlike Timers (just shadow axe summon needs a new timer)
-SDCategory: Udgarde Keep
+SDComment: Blizzlike Timers (just shadow axe summon needs a new timer)
+SDCategory: Utgarde Keep
EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
+#include "SpellScript.h"
+#include "SpellAuraEffects.h"
#include "utgarde_keep.h"
enum Yells
{
- // Ingvar (Human)
- SAY_AGGRO_1 = 0,
- SAY_SLAY_1 = 1,
- SAY_DEATH_1 = 2,
-
- // Ingvar (Undead)
- SAY_AGGRO_2 = 3,
- SAY_SLAY_2 = 4,
- SAY_DEATH_2 = 5,
+ // Ingvar (Human/Undead)
+ SAY_AGGRO = 0,
+ SAY_SLAY = 1,
+ SAY_DEATH = 2,
// Annhylde The Caller
- YELL_RESURRECT = 0
+ YELL_RESURRECT = 0
};
enum Events
@@ -83,8 +80,10 @@ enum Spells
SPELL_DARK_SMASH = 42723,
SPELL_DREADFUL_ROAR = 42729,
SPELL_WOE_STRIKE = 42730,
+ SPELL_WOE_STRIKE_EFFECT = 42739,
SPELL_SHADOW_AXE_SUMMON = 42748,
+ SPELL_SHADOW_AXE_PERIODIC_DAMAGE = 42750,
// Spells for Annhylde
SPELL_SCOURG_RESURRECTION_HEAL = 42704, // Heal Max + DummyAura
@@ -105,16 +104,14 @@ class boss_ingvar_the_plunderer : public CreatureScript
struct boss_ingvar_the_plundererAI : public BossAI
{
- boss_ingvar_the_plundererAI(Creature* creature) : BossAI(creature, DATA_INGVAR)
- {
- _isUndead = false;
- }
+ boss_ingvar_the_plundererAI(Creature* creature) : BossAI(creature, DATA_INGVAR) { }
void Reset() OVERRIDE
{
- _isUndead = false;
+ if (me->GetEntry() != NPC_INGVAR)
+ me->UpdateEntry(NPC_INGVAR);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
_Reset();
events.SetPhase(PHASE_HUMAN);
@@ -132,12 +129,12 @@ class boss_ingvar_the_plunderer : public CreatureScript
me->RemoveAllAuras();
DoCast(me, SPELL_INGVAR_FEIGN_DEATH, true);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
events.SetPhase(PHASE_EVENT);
events.ScheduleEvent(EVENT_SUMMON_BANSHEE, 3 * IN_MILLISECONDS, 0, PHASE_EVENT);
- Talk(SAY_DEATH_1);
+ Talk(SAY_DEATH);
}
if (events.IsInPhase(PHASE_EVENT))
@@ -152,26 +149,22 @@ class boss_ingvar_the_plunderer : public CreatureScript
void StartZombiePhase()
{
- _isUndead = true;
me->RemoveAura(SPELL_INGVAR_FEIGN_DEATH);
- DoCast(me, SPELL_INGVAR_TRANSFORM, true); /// @todo: should be death persistent
+ DoCast(me, SPELL_INGVAR_TRANSFORM, true);
+ me->UpdateEntry(NPC_INGVAR_UNDEAD);
events.ScheduleEvent(EVENT_JUST_TRANSFORMED, 2 * IN_MILLISECONDS, 0, PHASE_EVENT);
-
- Talk(SAY_AGGRO_2);
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
_EnterCombat();
-
- if (!_isUndead)
- Talk(SAY_AGGRO_1);
+ Talk(SAY_AGGRO);
}
void JustDied(Unit* /*killer*/) OVERRIDE
{
_JustDied();
- Talk(SAY_DEATH_2);
+ Talk(SAY_DEATH);
}
void ScheduleSecondPhase()
@@ -183,9 +176,10 @@ class boss_ingvar_the_plunderer : public CreatureScript
events.ScheduleEvent(EVENT_SHADOW_AXE, 30*IN_MILLISECONDS, 0, PHASE_UNDEAD);
}
- void KilledUnit(Unit* /*victim*/) OVERRIDE
+ void KilledUnit(Unit* who) OVERRIDE
{
- Talk(_isUndead ? SAY_SLAY_1 : SAY_SLAY_2);
+ if (who->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_SLAY);
}
void UpdateAI(uint32 diff) OVERRIDE
@@ -220,7 +214,7 @@ class boss_ingvar_the_plunderer : public CreatureScript
events.ScheduleEvent(EVENT_SMASH, urand(12, 16)*IN_MILLISECONDS, 0, PHASE_HUMAN);
break;
case EVENT_JUST_TRANSFORMED:
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
DoZoneInCombat();
ScheduleSecondPhase();
return;
@@ -241,20 +235,18 @@ class boss_ingvar_the_plunderer : public CreatureScript
events.ScheduleEvent(EVENT_WOE_STRIKE, urand(10, 14)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
break;
case EVENT_SHADOW_AXE:
- if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 1))
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
DoCast(target, SPELL_SHADOW_AXE_SUMMON);
-
events.ScheduleEvent(EVENT_SHADOW_AXE, 30*IN_MILLISECONDS, 0, PHASE_UNDEAD);
break;
+ default:
+ break;
}
}
if (!events.IsInPhase(PHASE_EVENT))
DoMeleeAttackIfReady();
}
-
- private:
- bool _isUndead;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
@@ -279,12 +271,8 @@ class npc_annhylde_the_caller : public CreatureScript
{
_events.Reset();
- //! HACK: Creature's can't have MOVEMENTFLAG_FLYING
- me->SetHover(true);
-
me->GetPosition(x, y, z);
- DoTeleportTo(x+1, y, z+30);
- me->GetMotionMaster()->MovePoint(1, x, y, z+15);
+ me->GetMotionMaster()->MovePoint(1, x, y, z - 15.0f);
}
void MovementInform(uint32 type, uint32 id) OVERRIDE
@@ -339,7 +327,7 @@ class npc_annhylde_the_caller : public CreatureScript
ingvar->AI()->DoAction(ACTION_START_PHASE_2);
}
- me->GetMotionMaster()->MovePoint(2, x+1, y, z+30);
+ me->GetMotionMaster()->MovePoint(2, x, y, z + 15.0f);
break;
default:
break;
@@ -359,52 +347,112 @@ class npc_annhylde_the_caller : public CreatureScript
}
};
-enum ShadowAxe
-{
- SPELL_SHADOW_AXE_DAMAGE = 42750,
- H_SPELL_SHADOW_AXE_DAMAGE = 59719,
- POINT_TARGET = 28
-};
-
class npc_ingvar_throw_dummy : public CreatureScript
{
-public:
- npc_ingvar_throw_dummy() : CreatureScript("npc_ingvar_throw_dummy") { }
+ public:
+ npc_ingvar_throw_dummy() : CreatureScript("npc_ingvar_throw_dummy") { }
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_ingvar_throw_dummyAI(creature);
- }
+ struct npc_ingvar_throw_dummyAI : public ScriptedAI
+ {
+ npc_ingvar_throw_dummyAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void Reset() OVERRIDE
+ {
+ me->SetReactState(REACT_PASSIVE);
+
+ if (Creature* target = me->FindNearestCreature(NPC_THROW_TARGET, 200.0f))
+ {
+ float x, y, z;
+ target->GetPosition(x, y, z);
+ me->GetMotionMaster()->MoveCharge(x, y, z);
+ target->DespawnOrUnsummon();
+ }
+ else
+ me->DespawnOrUnsummon();
+ }
+
+ void MovementInform(uint32 type, uint32 id) OVERRIDE
+ {
+ if (type == EFFECT_MOTION_TYPE && id == EVENT_CHARGE)
+ {
+ me->CastSpell(me, SPELL_SHADOW_AXE_PERIODIC_DAMAGE, true);
+ me->DespawnOrUnsummon(10000);
+ }
+ }
+ };
- struct npc_ingvar_throw_dummyAI : public ScriptedAI
- {
- npc_ingvar_throw_dummyAI(Creature* creature) : ScriptedAI(creature)
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
+ return new npc_ingvar_throw_dummyAI(creature);
}
+};
+
+// 42912 - Summon Banshee
+class spell_ingvar_summon_banshee : public SpellScriptLoader
+{
+ public:
+ spell_ingvar_summon_banshee() : SpellScriptLoader("spell_ingvar_summon_banshee") { }
- void Reset() OVERRIDE
+ class spell_ingvar_summon_banshee_SpellScript : public SpellScript
{
- if (Creature* target = me->FindNearestCreature(NPC_THROW_TARGET, 50.0f))
+ PrepareSpellScript(spell_ingvar_summon_banshee_SpellScript);
+
+ void SetDest(SpellDestination& dest)
{
- float x, y, z;
- target->GetPosition(x, y, z);
- me->GetMotionMaster()->MoveCharge(x, y, z, 42.0f, POINT_TARGET);
- target->DisappearAndDie();
+ dest.RelocateOffset({ 0.0f, 0.0f, 30.0f, 0.0f });
}
- else
- me->DisappearAndDie();
+
+ void Register() OVERRIDE
+ {
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_ingvar_summon_banshee_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER_BACK);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_ingvar_summon_banshee_SpellScript();
}
+};
- void MovementInform(uint32 type, uint32 id) OVERRIDE
+// 42730, 59735 - Woe Strike
+class spell_ingvar_woe_strike : public SpellScriptLoader
+{
+ public:
+ spell_ingvar_woe_strike() : SpellScriptLoader("spell_ingvar_woe_strike") { }
+
+ class spell_ingvar_woe_strike_AuraScript : public AuraScript
{
- if (type == EFFECT_MOTION_TYPE && id == POINT_TARGET)
+ PrepareAuraScript(spell_ingvar_woe_strike_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_WOE_STRIKE_EFFECT))
+ return false;
+ return true;
+ }
+
+ bool CheckProc(ProcEventInfo& eventInfo)
+ {
+ return eventInfo.GetHealInfo()->GetHeal();
+ }
+
+ void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ GetTarget()->CastSpell(eventInfo.GetActor(), SPELL_WOE_STRIKE_EFFECT, true, NULL, aurEff);
+ }
+
+ void Register() OVERRIDE
{
- DoCast(me, SPELL_SHADOW_AXE_DAMAGE);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
- me->DespawnOrUnsummon(10000);
+ DoCheckProc += AuraCheckProcFn(spell_ingvar_woe_strike_AuraScript::CheckProc);
+ OnEffectProc += AuraEffectProcFn(spell_ingvar_woe_strike_AuraScript::HandleProc, EFFECT_1, SPELL_AURA_PROC_TRIGGER_SPELL);
}
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_ingvar_woe_strike_AuraScript();
}
- };
};
void AddSC_boss_ingvar_the_plunderer()
@@ -412,4 +460,6 @@ void AddSC_boss_ingvar_the_plunderer()
new boss_ingvar_the_plunderer();
new npc_annhylde_the_caller();
new npc_ingvar_throw_dummy();
+ new spell_ingvar_summon_banshee();
+ new spell_ingvar_woe_strike();
}
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index 68c16a1b2d6..65aa22c776d 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -711,7 +711,7 @@ class spell_gen_clone : public SpellScriptLoader
void HandleScriptEffect(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
- GetHitUnit()->CastSpell(GetCaster(), GetEffectValue(), true);
+ GetHitUnit()->CastSpell(GetCaster(), uint32(GetEffectValue()), true);
}
void Register() OVERRIDE
@@ -751,10 +751,7 @@ class spell_gen_clone_weapon : public SpellScriptLoader
void HandleScriptEffect(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
- Unit* caster = GetCaster();
-
- if (Unit* target = GetHitUnit())
- caster->CastSpell(target, GetEffectValue(), true);
+ GetHitUnit()->CastSpell(GetCaster(), uint32(GetEffectValue()), true);
}
void Register() OVERRIDE
@@ -778,8 +775,6 @@ class spell_gen_clone_weapon_aura : public SpellScriptLoader
{
PrepareAuraScript(spell_gen_clone_weapon_auraScript);
- uint32 prevItem;
-
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
if (!sSpellMgr->GetSpellInfo(SPELL_COPY_WEAPON_AURA) ||
@@ -792,6 +787,12 @@ class spell_gen_clone_weapon_aura : public SpellScriptLoader
return true;
}
+ bool Load() OVERRIDE
+ {
+ prevItem = 0;
+ return true;
+ }
+
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* caster = GetCaster();
@@ -877,6 +878,8 @@ class spell_gen_clone_weapon_aura : public SpellScriptLoader
OnEffectRemove += AuraEffectRemoveFn(spell_gen_clone_weapon_auraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
+ private:
+ uint32 prevItem;
};
AuraScript* GetAuraScript() const OVERRIDE
@@ -3282,6 +3285,33 @@ class spell_gen_summon_tournament_mount : public SpellScriptLoader
}
};
+// 41213, 43416, 69222, 73076 - Throw Shield
+class spell_gen_throw_shield : public SpellScriptLoader
+{
+ public:
+ spell_gen_throw_shield() : SpellScriptLoader("spell_gen_throw_shield") { }
+
+ class spell_gen_throw_shield_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gen_throw_shield_SpellScript);
+
+ void HandleScriptEffect(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_gen_throw_shield_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_gen_throw_shield_SpellScript();
+ }
+};
enum MountedDuelSpells
{
@@ -3773,6 +3803,7 @@ void AddSC_generic_spell_scripts()
new spell_gen_summon_elemental("spell_gen_summon_fire_elemental", SPELL_SUMMON_FIRE_ELEMENTAL);
new spell_gen_summon_elemental("spell_gen_summon_earth_elemental", SPELL_SUMMON_EARTH_ELEMENTAL);
new spell_gen_summon_tournament_mount();
+ new spell_gen_throw_shield();
new spell_gen_tournament_duel();
new spell_gen_tournament_pennant();
new spell_pvp_trinket_wotf_shared_cd();
diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp
index d1b32570795..b9fd07293cd 100644
--- a/src/server/scripts/Spells/spell_quest.cpp
+++ b/src/server/scripts/Spells/spell_quest.cpp
@@ -2276,6 +2276,46 @@ class spell_q13400_illidan_kill_master : public SpellScriptLoader
}
};
+enum RelicOfTheEarthenRing
+{
+ SPELL_TOTEM_OF_THE_EARTHEN_RING = 66747
+};
+
+// 66744 - Make Player Destroy Totems
+class spell_q14100_q14111_make_player_destroy_totems : public SpellScriptLoader
+{
+ public:
+ spell_q14100_q14111_make_player_destroy_totems() : SpellScriptLoader("spell_q14100_q14111_make_player_destroy_totems") { }
+
+ class spell_q14100_q14111_make_player_destroy_totems_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q14100_q14111_make_player_destroy_totems_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_TOTEM_OF_THE_EARTHEN_RING))
+ return false;
+ return true;
+ }
+
+ void HandleScriptEffect(SpellEffIndex /*effIndex*/)
+ {
+ if (Player* player = GetHitPlayer())
+ player->CastSpell(player, SPELL_TOTEM_OF_THE_EARTHEN_RING, TRIGGERED_FULL_MASK); // ignore reagent cost, consumed by quest
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_q14100_q14111_make_player_destroy_totems_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_q14100_q14111_make_player_destroy_totems_SpellScript();
+ }
+};
+
void AddSC_quest_spell_scripts()
{
new spell_q55_sacred_cleansing();
@@ -2331,4 +2371,5 @@ void AddSC_quest_spell_scripts()
new spell_q12919_gymers_grab();
new spell_q12919_gymers_throw();
new spell_q13400_illidan_kill_master();
+ new spell_q14100_q14111_make_player_destroy_totems();
}
diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp
index d0ba39e8b09..e48f16d6558 100644
--- a/src/server/scripts/Spells/spell_warrior.cpp
+++ b/src/server/scripts/Spells/spell_warrior.cpp
@@ -28,6 +28,7 @@
enum WarriorSpells
{
+ SPELL_WARRIOR_BLADESTORM_PERIODIC_WHIRLWIND = 50622,
SPELL_WARRIOR_BLOODTHIRST = 23885,
SPELL_WARRIOR_BLOODTHIRST_DAMAGE = 23881,
SPELL_WARRIOR_CHARGE = 34846,
@@ -45,7 +46,8 @@ enum WarriorSpells
SPELL_WARRIOR_RETALIATION_DAMAGE = 22858,
SPELL_WARRIOR_SLAM = 50783,
SPELL_WARRIOR_SUNDER_ARMOR = 58567,
- SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK = 26654,
+ SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_1 = 12723,
+ SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_2 = 26654,
SPELL_WARRIOR_TAUNT = 355,
SPELL_WARRIOR_UNRELENTING_ASSAULT_RANK_1 = 46859,
SPELL_WARRIOR_UNRELENTING_ASSAULT_RANK_2 = 46860,
@@ -686,7 +688,7 @@ class spell_warr_sweeping_strikes : public SpellScriptLoader
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK))
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_1) || !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_2))
return false;
return true;
}
@@ -703,10 +705,23 @@ class spell_warr_sweeping_strikes : public SpellScriptLoader
return _procTarget;
}
- void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
+ void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
{
PreventDefaultAction();
- GetTarget()->CastSpell(_procTarget, SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK, true, NULL, aurEff);
+ if (eventInfo.GetDamageInfo())
+ {
+ SpellInfo const* spellInfo = eventInfo.GetDamageInfo()->GetSpellInfo();
+ if (spellInfo && (spellInfo->Id == SPELL_WARRIOR_BLADESTORM_PERIODIC_WHIRLWIND || (spellInfo->Id == SPELL_WARRIOR_EXECUTE && !_procTarget->HasAuraState(AURA_STATE_HEALTHLESS_20_PERCENT))))
+ {
+ // If triggered by Execute (while target is not under 20% hp) or Bladestorm deals normalized weapon damage
+ GetTarget()->CastSpell(_procTarget, SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_2, true, NULL, aurEff);
+ }
+ else
+ {
+ int32 damage = eventInfo.GetDamageInfo()->GetDamage();
+ GetTarget()->CastCustomSpell(SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_1, SPELLVALUE_BASE_POINT0, damage, _procTarget, true, NULL, aurEff);
+ }
+ }
}
void Register() OVERRIDE
diff --git a/src/server/scripts/World/chat_log.cpp b/src/server/scripts/World/chat_log.cpp
index ef854246d20..7074de3ed48 100644
--- a/src/server/scripts/World/chat_log.cpp
+++ b/src/server/scripts/World/chat_log.cpp
@@ -22,144 +22,133 @@
class ChatLogScript : public PlayerScript
{
-public:
- ChatLogScript() : PlayerScript("ChatLogScript") { }
+ public:
+ ChatLogScript() : PlayerScript("ChatLogScript") { }
- void OnChat(Player* player, uint32 type, uint32 lang, std::string& msg)
- {
- switch (type)
+ void OnChat(Player* player, uint32 type, uint32 lang, std::string& msg) OVERRIDE
{
- case CHAT_MSG_ADDON:
- if (sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON))
- TC_LOG_DEBUG("chat.log", "[ADDON] Player %s sends: %s",
- player->GetName().c_str(), msg.c_str());
- break;
-
- case CHAT_MSG_SAY:
- if (sWorld->getBoolConfig(CONFIG_CHATLOG_PUBLIC))
- TC_LOG_DEBUG("chat.log", "[SAY] Player %s says (language %u): %s",
+ switch (type)
+ {
+ case CHAT_MSG_SAY:
+ TC_LOG_DEBUG("chat.log.say", "Player %s says (language %u): %s",
player->GetName().c_str(), lang, msg.c_str());
- break;
+ break;
- case CHAT_MSG_EMOTE:
- if (sWorld->getBoolConfig(CONFIG_CHATLOG_PUBLIC))
- TC_LOG_DEBUG("chat.log", "[TEXTEMOTE] Player %s emotes: %s",
+ case CHAT_MSG_EMOTE:
+ TC_LOG_DEBUG("chat.log.emote", "Player %s emotes: %s",
player->GetName().c_str(), msg.c_str());
- break;
+ break;
- case CHAT_MSG_YELL:
- if (sWorld->getBoolConfig(CONFIG_CHATLOG_PUBLIC))
- TC_LOG_DEBUG("chat.log", "[YELL] Player %s yells (language %u): %s",
+ case CHAT_MSG_YELL:
+ TC_LOG_DEBUG("chat.log.yell", "Player %s yells (language %u): %s",
player->GetName().c_str(), lang, msg.c_str());
- break;
+ break;
+ }
+ }
+
+ void OnChat(Player* player, uint32 /*type*/, uint32 lang, std::string& msg, Player* receiver) OVERRIDE
+ {
+ if (lang != LANG_ADDON)
+ TC_LOG_DEBUG("chat.log.whisper", "Player %s tells %s: %s",
+ player->GetName().c_str(), receiver ? receiver->GetName().c_str() : "<unknown>", msg.c_str());
+ else
+ TC_LOG_DEBUG("chat.log.addon.whisper", "Player %s tells %s: %s",
+ player->GetName().c_str(), receiver ? receiver->GetName().c_str() : "<unknown>", msg.c_str());
}
- }
-
- void OnChat(Player* player, uint32 /*type*/, uint32 lang, std::string& msg, Player* receiver)
- {
- if (lang != LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHATLOG_WHISPER))
- TC_LOG_DEBUG("chat.log", "[WHISPER] Player %s tells %s: %s",
- player->GetName().c_str(), receiver ? receiver->GetName().c_str() : "<unknown>", msg.c_str());
- else if (lang == LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON))
- TC_LOG_DEBUG("chat.log", "[ADDON] Player %s tells %s: %s",
- player->GetName().c_str(), receiver ? receiver->GetName().c_str() : "<unknown>", msg.c_str());
- }
-
- void OnChat(Player* player, uint32 type, uint32 lang, std::string& msg, Group* group)
- {
- //! NOTE:
- //! LANG_ADDON can only be sent by client in "PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER"
- switch (type)
+
+ void OnChat(Player* player, uint32 type, uint32 lang, std::string& msg, Group* group) OVERRIDE
{
- case CHAT_MSG_PARTY:
- if (lang != LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHATLOG_PARTY))
- TC_LOG_DEBUG("chat.log", "[PARTY] Player %s tells group with leader %s: %s",
- player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str());
- else if (lang == LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON))
- TC_LOG_DEBUG("chat.log", "[ADDON] Player %s tells group with leader %s: %s",
- player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str());
- break;
-
- case CHAT_MSG_PARTY_LEADER:
- if (sWorld->getBoolConfig(CONFIG_CHATLOG_PARTY))
- TC_LOG_DEBUG("chat.log", "[PARTY] Leader %s tells group: %s",
+ //! NOTE:
+ //! LANG_ADDON can only be sent by client in "PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER"
+ switch (type)
+ {
+ case CHAT_MSG_PARTY:
+ if (lang != LANG_ADDON)
+ TC_LOG_DEBUG("chat.log.party", "Player %s tells group with leader %s: %s",
+ player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str());
+ else
+ TC_LOG_DEBUG("chat.log.addon.party", "Player %s tells group with leader %s: %s",
+ player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str());
+ break;
+
+ case CHAT_MSG_PARTY_LEADER:
+ TC_LOG_DEBUG("chat.log.party", "Leader %s tells group: %s",
player->GetName().c_str(), msg.c_str());
- break;
-
- case CHAT_MSG_RAID:
- if (lang != LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHATLOG_RAID))
- TC_LOG_DEBUG("chat.log", "[RAID] Player %s tells raid with leader %s: %s",
- player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str());
- else if (lang == LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON))
- TC_LOG_DEBUG("chat.log", "[ADDON] Player %s tells raid with leader %s: %s",
- player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str());
- break;
-
- case CHAT_MSG_RAID_LEADER:
- if (sWorld->getBoolConfig(CONFIG_CHATLOG_RAID))
- TC_LOG_DEBUG("chat.log", "[RAID] Leader player %s tells raid: %s",
+ break;
+
+ case CHAT_MSG_RAID:
+ if (lang != LANG_ADDON)
+ TC_LOG_DEBUG("chat.log.raid", "Player %s tells raid with leader %s: %s",
+ player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str());
+ else
+ TC_LOG_DEBUG("chat.log.addon.raid", "Player %s tells raid with leader %s: %s",
+ player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str());
+ break;
+
+ case CHAT_MSG_RAID_LEADER:
+ TC_LOG_DEBUG("chat.log.raid", "Leader player %s tells raid: %s",
player->GetName().c_str(), msg.c_str());
- break;
+ break;
- case CHAT_MSG_RAID_WARNING:
- if (sWorld->getBoolConfig(CONFIG_CHATLOG_RAID))
- TC_LOG_DEBUG("chat.log", "[RAID] Leader player %s warns raid with: %s",
+ case CHAT_MSG_RAID_WARNING:
+ TC_LOG_DEBUG("chat.log.raid", "Leader player %s warns raid with: %s",
player->GetName().c_str(), msg.c_str());
- break;
-
- case CHAT_MSG_BATTLEGROUND:
- if (lang != LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHATLOG_BGROUND))
- TC_LOG_DEBUG("chat.log", "[BATTLEGROUND] Player %s tells battleground with leader %s: %s",
- player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str());
- else if (lang == LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON))
- TC_LOG_DEBUG("chat.log", "[ADDON] Player %s tells battleground with leader %s: %s",
- player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str());
- break;
-
- case CHAT_MSG_BATTLEGROUND_LEADER:
- if (sWorld->getBoolConfig(CONFIG_CHATLOG_BGROUND))
- TC_LOG_DEBUG("chat.log", "[BATTLEGROUND] Leader player %s tells battleground: %s",
+ break;
+
+ case CHAT_MSG_BATTLEGROUND:
+ if (lang != LANG_ADDON)
+ TC_LOG_DEBUG("chat.log.bg", "Player %s tells battleground with leader %s: %s",
+ player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str());
+ else
+ TC_LOG_DEBUG("chat.log.addon.bg", "Player %s tells battleground with leader %s: %s",
+ player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str());
+ break;
+
+ case CHAT_MSG_BATTLEGROUND_LEADER:
+ TC_LOG_DEBUG("chat.log.bg", "Leader player %s tells battleground: %s",
player->GetName().c_str(), msg.c_str());
- break;
+ break;
+ }
}
- }
- void OnChat(Player* player, uint32 type, uint32 lang, std::string& msg, Guild* guild)
- {
- switch (type)
+ void OnChat(Player* player, uint32 type, uint32 lang, std::string& msg, Guild* guild) OVERRIDE
{
- case CHAT_MSG_GUILD:
- if (lang != LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHATLOG_GUILD))
- TC_LOG_DEBUG("chat.log", "[GUILD] Player %s tells guild %s: %s",
- player->GetName().c_str(), guild ? guild->GetName().c_str() : "<unknown>", msg.c_str());
- else if (lang == LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON))
- TC_LOG_DEBUG("chat.log", "[ADDON] Player %s sends to guild %s: %s",
+ switch (type)
+ {
+ case CHAT_MSG_GUILD:
+ if (lang != LANG_ADDON)
+ TC_LOG_DEBUG("chat.log.guild", "Player %s tells guild %s: %s",
+ player->GetName().c_str(), guild ? guild->GetName().c_str() : "<unknown>", msg.c_str());
+ else
+ TC_LOG_DEBUG("chat.log.addon.guild", "Player %s sends to guild %s: %s",
+ player->GetName().c_str(), guild ? guild->GetName().c_str() : "<unknown>", msg.c_str());
+ break;
+
+ case CHAT_MSG_OFFICER:
+ TC_LOG_DEBUG("chat.log.guild.officer", "Player %s tells guild %s officers: %s",
player->GetName().c_str(), guild ? guild->GetName().c_str() : "<unknown>", msg.c_str());
- break;
+ break;
+ }
+ }
- case CHAT_MSG_OFFICER:
- if (sWorld->getBoolConfig(CONFIG_CHATLOG_GUILD))
- TC_LOG_DEBUG("chat.log", "[OFFICER] Player %s tells guild %s officers: %s",
- player->GetName().c_str(), guild ? guild->GetName().c_str() : "<unknown>", msg.c_str());
- break;
+ void OnChat(Player* player, uint32 /*type*/, uint32 /*lang*/, std::string& msg, Channel* channel) OVERRIDE
+ {
+ bool isSystem = channel &&
+ (channel->HasFlag(CHANNEL_FLAG_TRADE) ||
+ channel->HasFlag(CHANNEL_FLAG_GENERAL) ||
+ channel->HasFlag(CHANNEL_FLAG_CITY) ||
+ channel->HasFlag(CHANNEL_FLAG_LFG));
+
+ if (isSystem)
+ TC_LOG_DEBUG("chat.log.system", "Player %s tells channel %s: %s",
+ player->GetName().c_str(), channel->GetName().c_str(), msg.c_str());
+ else
+ {
+ std::string channelName = channel ? channel->GetName() : "<unknown>";
+ TC_LOG_DEBUG("chat.log.channel." + channelName, "Player %s tells channel %s: %s",
+ player->GetName().c_str(), channelName.c_str(), msg.c_str());
+ }
}
- }
-
- void OnChat(Player* player, uint32 /*type*/, uint32 /*lang*/, std::string& msg, Channel* channel)
- {
- bool isSystem = channel &&
- (channel->HasFlag(CHANNEL_FLAG_TRADE) ||
- channel->HasFlag(CHANNEL_FLAG_GENERAL) ||
- channel->HasFlag(CHANNEL_FLAG_CITY) ||
- channel->HasFlag(CHANNEL_FLAG_LFG));
-
- if (sWorld->getBoolConfig(CONFIG_CHATLOG_SYSCHAN) && isSystem)
- TC_LOG_DEBUG("chat.log", "[SYSCHAN] Player %s tells channel %s: %s",
- player->GetName().c_str(), channel->GetName().c_str(), msg.c_str());
- else if (sWorld->getBoolConfig(CONFIG_CHATLOG_CHANNEL))
- TC_LOG_DEBUG("chat.log", "[CHANNEL] Player %s tells channel %s: %s",
- player->GetName().c_str(), channel ? channel->GetName().c_str() : "<unknown>", msg.c_str());
- }
};
void AddSC_chat_log()
diff --git a/src/server/shared/Debugging/WheatyExceptionReport.cpp b/src/server/shared/Debugging/WheatyExceptionReport.cpp
index e838c42d32d..3b6bd3d2cc8 100644
--- a/src/server/shared/Debugging/WheatyExceptionReport.cpp
+++ b/src/server/shared/Debugging/WheatyExceptionReport.cpp
@@ -29,15 +29,23 @@
inline LPTSTR ErrorMessage(DWORD dw)
{
LPVOID lpMsgBuf;
- FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- dw,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &lpMsgBuf,
- 0, NULL);
- return (LPTSTR)lpMsgBuf;
+ DWORD formatResult = FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ dw,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &lpMsgBuf,
+ 0, NULL);
+ if (formatResult != 0)
+ return (LPTSTR)lpMsgBuf;
+ else
+ {
+ LPTSTR msgBuf = (LPTSTR)LocalAlloc(LPTR, 30);
+ sprintf(msgBuf, "Unknown error: %u", dw);
+ return msgBuf;
+ }
+
}
//============================== Global Variables =============================
@@ -878,6 +886,17 @@ char* suffix)
if (SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_SYMNAME,
&pwszTypeName))
{
+ // handle special cases
+ if (wcscmp(pwszTypeName, L"std::basic_string<char,std::char_traits<char>,std::allocator<char> >") == 0)
+ {
+ LocalFree(pwszTypeName);
+ pszCurrBuffer += sprintf(pszCurrBuffer, " %s", "std::string");
+ pszCurrBuffer = FormatOutputValue(pszCurrBuffer, btStdString, 0, (PVOID)offset);
+ pszCurrBuffer += sprintf(pszCurrBuffer, "\r\n");
+ bHandled = true;
+ return pszCurrBuffer;
+ }
+
pszCurrBuffer += sprintf(pszCurrBuffer, " %ls", pwszTypeName);
LocalFree(pwszTypeName);
}
@@ -928,6 +947,19 @@ char* suffix)
FormatOutputValue(&addressStr[1], btVoid, sizeof(PVOID), (PVOID)offset);
pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, innerTypeID, nestingLevel + 1,
address, bHandled, "", addressStr);
+
+ if (!bHandled)
+ {
+ BasicType basicType = GetBasicType(dwTypeIndex, modBase);
+ pszCurrBuffer += sprintf(pszCurrBuffer, rgBaseType[basicType]);
+ // Get the size of the child member
+ ULONG64 length;
+ SymGetTypeInfo(m_hProcess, modBase, innerTypeID, TI_GET_LENGTH, &length);
+ pszCurrBuffer = FormatOutputValue(pszCurrBuffer, basicType, length, (PVOID)address);
+ pszCurrBuffer += sprintf(pszCurrBuffer, "\r\n");
+ bHandled = true;
+ return pszCurrBuffer;
+ }
}
}
break;
@@ -1027,13 +1059,6 @@ char* suffix)
ULONG64 length;
SymGetTypeInfo(m_hProcess, modBase, typeId, TI_GET_LENGTH, &length);
- // BasicType basicType = GetBasicType(children.ChildId[i], modBase);
- //
- // pszCurrBuffer += sprintf(pszCurrBuffer, rgBaseType[basicType]);
- //
- // Emit the variable name
- // pszCurrBuffer += sprintf(pszCurrBuffer, "\'%s\'", Name);
-
pszCurrBuffer = FormatOutputValue(pszCurrBuffer, basicType,
length, (PVOID)dwFinalOffset);
@@ -1052,49 +1077,60 @@ PVOID pAddress)
{
__try
{
- // Format appropriately (assuming it's a 1, 2, or 4 bytes (!!!)
- if (length == 1)
- pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PBYTE)pAddress);
- else if (length == 2)
- pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PWORD)pAddress);
- else if (length == 4)
+ switch (basicType)
{
- if (basicType == btFloat)
- {
- pszCurrBuffer += sprintf(pszCurrBuffer, " = %f", *(PFLOAT)pAddress);
- }
- else if (basicType == btChar)
- {
- if (!IsBadStringPtr(*(PSTR*)pAddress, 32))
+ case btChar:
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = \"%s\"", pAddress);
+ break;
+ case btStdString:
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = \"%s\"", static_cast<std::string*>(pAddress)->c_str());
+ break;
+ default:
+ // Format appropriately (assuming it's a 1, 2, or 4 bytes (!!!)
+ if (length == 1)
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PBYTE)pAddress);
+ else if (length == 2)
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PWORD)pAddress);
+ else if (length == 4)
{
- pszCurrBuffer += sprintf(pszCurrBuffer, " = \"%.31s\"",
- *(PSTR*)pAddress);
+ if (basicType == btFloat)
+ {
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = %f", *(PFLOAT)pAddress);
+ }
+ else if (basicType == btChar)
+ {
+ if (!IsBadStringPtr(*(PSTR*)pAddress, 32))
+ {
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = \"%.31s\"",
+ *(PSTR*)pAddress);
+ }
+ else
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = %X",
+ *(PDWORD)pAddress);
+ }
+ else
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PDWORD)pAddress);
+ }
+ else if (length == 8)
+ {
+ if (basicType == btFloat)
+ {
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = %lf",
+ *(double *)pAddress);
+ }
+ else
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = %I64X",
+ *(DWORD64*)pAddress);
}
else
- pszCurrBuffer += sprintf(pszCurrBuffer, " = %X",
- *(PDWORD)pAddress);
- }
- else
- pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PDWORD)pAddress);
- }
- else if (length == 8)
- {
- if (basicType == btFloat)
- {
- pszCurrBuffer += sprintf(pszCurrBuffer, " = %lf",
- *(double *)pAddress);
- }
- else
- pszCurrBuffer += sprintf(pszCurrBuffer, " = %I64X",
- *(DWORD64*)pAddress);
- }
- else
- {
-#if _WIN64
- pszCurrBuffer += sprintf(pszCurrBuffer, " = %I64X", (DWORD64*)pAddress);
-#else
- pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", (PDWORD)pAddress);
-#endif
+ {
+ #if _WIN64
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = %I64X", (DWORD64*)pAddress);
+ #else
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", (PDWORD)pAddress);
+ #endif
+ }
+ break;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
diff --git a/src/server/shared/Debugging/WheatyExceptionReport.h b/src/server/shared/Debugging/WheatyExceptionReport.h
index 74330370509..f6d6b7f4b9e 100644
--- a/src/server/shared/Debugging/WheatyExceptionReport.h
+++ b/src/server/shared/Debugging/WheatyExceptionReport.h
@@ -31,7 +31,10 @@ enum BasicType // Stolen from CVCON
btComplex = 28,
btBit = 29,
btBSTR = 30,
- btHresult = 31
+ btHresult = 31,
+
+ // Custom types
+ btStdString = 101
};
const char* const rgBaseType[] =
diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp
index d7d70e7d4ea..bc002668b3b 100644
--- a/src/server/shared/Logging/Log.cpp
+++ b/src/server/shared/Logging/Log.cpp
@@ -250,13 +250,13 @@ void Log::ReadLoggersFromConfig()
AppenderConsole* appender = new AppenderConsole(NextAppenderId(), "Console", LOG_LEVEL_DEBUG, APPENDER_FLAGS_NONE);
appenders[appender->getId()] = appender;
- Logger& logger = loggers[LOGGER_ROOT];
- logger.Create(LOGGER_ROOT, LOG_LEVEL_ERROR);
- logger.addAppender(appender->getId(), appender);
+ Logger& rootLogger = loggers[LOGGER_ROOT];
+ rootLogger.Create(LOGGER_ROOT, LOG_LEVEL_ERROR);
+ rootLogger.addAppender(appender->getId(), appender);
- logger = loggers["server"];
- logger.Create("server", LOG_LEVEL_ERROR);
- logger.addAppender(appender->getId(), appender);
+ Logger& serverLogger = loggers["server"];
+ serverLogger.Create("server", LOG_LEVEL_INFO);
+ serverLogger.addAppender(appender->getId(), appender);
}
}
diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h
index dcac93e5a60..73c5601b95b 100644
--- a/src/server/shared/Logging/Log.h
+++ b/src/server/shared/Logging/Log.h
@@ -103,16 +103,12 @@ inline Logger const* Log::GetLoggerByType(std::string const& originalType)
}
while (!logger);
- cachedLoggers[type] = logger;
+ cachedLoggers[originalType] = logger;
return logger;
}
inline bool Log::ShouldLog(std::string const& type, LogLevel level)
{
- // TODO: Use cache to store "Type.sub1.sub2": "Type" equivalence, should
- // Speed up in cases where requesting "Type.sub1.sub2" but only configured
- // Logger "Type"
-
Logger const* logger = GetLoggerByType(type);
if (!logger)
return false;
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 1762859afae..f71ef5d064b 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -410,78 +410,6 @@ PidFile = ""
PacketLogFile = ""
-#
-# ChatLogs.Channel
-# Description: Log custom channel chat.
-# Default: 0 - (Disabled)
-# 1 - (Enabled)
-
-ChatLogs.Channel = 0
-
-#
-# ChatLogs.Whisper
-# Description: Log whispers between players.
-# Default: 0 - (Disabled)
-# 1 - (Enabled)
-
-ChatLogs.Whisper = 0
-
-#
-# ChatLogs.SysChan
-# Description: Log system channel messages.
-# Default: 0 - (Disabled)
-# 1 - (Enabled)
-
-ChatLogs.SysChan = 0
-
-#
-# ChatLogs.Party
-# Description: Log party chat.
-# Default: 0 - (Disabled)
-# 1 - (Enabled)
-
-ChatLogs.Party = 0
-
-#
-# ChatLogs.Raid
-# Description: Log raid chat.
-# Default: 0 - (Disabled)
-# 1 - (Enabled)
-
-ChatLogs.Raid = 0
-
-#
-# ChatLogs.Guild
-# Description: Log guild chat.
-# Default: 0 - (Disabled)
-# 1 - (Enabled)
-
-ChatLogs.Guild = 0
-
-#
-# ChatLogs.Public
-# Description: Log public chat (say/yell/emote).
-# Default: 0 - (Disabled)
-# 1 - (Enabled)
-
-ChatLogs.Public = 0
-
-#
-# ChatLogs.Addon
-# Description: Log addon messages.
-# Default: 0 - (Disabled)
-# 1 - (Enabled)
-
-ChatLogs.Addon = 0
-
-#
-# ChatLogs.BattleGround
-# Description: Log battleground chat.
-# Default: 0 - (Disabled)
-# 1 - (Enabled)
-
-ChatLogs.BattleGround = 0
-
# Extended Logging system configuration moved to end of file (on purpose)
#
###################################################################################################