aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/CoreAI/GameObjectAI.h1
-rwxr-xr-xsrc/server/game/AI/CoreAI/UnitAI.h1
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp1
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp13
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.h2
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp24
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp10
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h15
-rwxr-xr-xsrc/server/game/Achievements/AchievementMgr.cpp41
-rwxr-xr-xsrc/server/game/Achievements/AchievementMgr.h2
-rwxr-xr-xsrc/server/game/Chat/Channels/Channel.cpp12
-rwxr-xr-xsrc/server/game/Chat/Chat.cpp36
-rwxr-xr-xsrc/server/game/Chat/Commands/Level0.cpp11
-rwxr-xr-xsrc/server/game/Chat/Commands/TicketCommands.cpp61
-rwxr-xr-xsrc/server/game/Conditions/ConditionMgr.cpp5
-rwxr-xr-xsrc/server/game/DataStores/DBCEnums.h4
-rwxr-xr-xsrc/server/game/DataStores/DBCStructure.h2
-rwxr-xr-xsrc/server/game/DungeonFinding/LFGMgr.cpp2
-rwxr-xr-xsrc/server/game/Entities/Creature/GossipDef.cpp2
-rwxr-xr-xsrc/server/game/Entities/Object/Object.cpp7
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp85
-rwxr-xr-xsrc/server/game/Entities/Player/Player.h3
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp83
-rwxr-xr-xsrc/server/game/Entities/Vehicle/Vehicle.cpp2
-rwxr-xr-xsrc/server/game/Events/GameEventMgr.cpp27
-rwxr-xr-xsrc/server/game/Events/GameEventMgr.h1
-rwxr-xr-xsrc/server/game/Globals/ObjectAccessor.cpp8
-rwxr-xr-xsrc/server/game/Globals/ObjectAccessor.h20
-rwxr-xr-xsrc/server/game/Globals/ObjectMgr.cpp43
-rw-r--r--src/server/game/Grids/GridDefines.h5
-rwxr-xr-xsrc/server/game/Grids/ObjectGridLoader.cpp30
-rwxr-xr-xsrc/server/game/Groups/Group.cpp1
-rwxr-xr-xsrc/server/game/Guilds/Guild.cpp1
-rwxr-xr-xsrc/server/game/Mails/Mail.cpp8
-rwxr-xr-xsrc/server/game/Maps/Map.cpp71
-rwxr-xr-xsrc/server/game/Maps/Map.h2
-rwxr-xr-xsrc/server/game/Miscellaneous/Language.h4
-rwxr-xr-xsrc/server/game/Miscellaneous/SharedDefines.h72
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp3
-rwxr-xr-xsrc/server/game/Quests/QuestDef.cpp4
-rwxr-xr-xsrc/server/game/Quests/QuestDef.h2
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp15
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/CharacterHandler.cpp8
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/CombatHandler.cpp23
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/NPCHandler.cpp5
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp12
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/QueryHandler.cpp3
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuraEffects.cpp15
-rwxr-xr-xsrc/server/game/Spells/Spell.cpp3
-rwxr-xr-xsrc/server/game/Spells/SpellEffects.cpp147
-rwxr-xr-xsrc/server/game/Spells/SpellMgr.cpp8
-rwxr-xr-xsrc/server/game/World/World.cpp2
-rwxr-xr-xsrc/server/game/World/World.h3
-rw-r--r--src/server/scripts/Commands/cs_modify.cpp7
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp2
-rw-r--r--src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp208
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp2
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp1
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp2
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp37
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/oculus.h3
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp4
-rw-r--r--src/server/scripts/Outland/BlackTemple/boss_illidan.cpp4
-rw-r--r--src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp4
-rw-r--r--src/server/scripts/Outland/nagrand.cpp2
-rw-r--r--src/server/scripts/World/go_scripts.cpp28
-rwxr-xr-xsrc/server/shared/Database/MySQLConnection.cpp7
-rwxr-xr-xsrc/server/shared/Debugging/Errors.h3
-rwxr-xr-xsrc/server/worldserver/CommandLine/CliRunnable.cpp2
-rwxr-xr-xsrc/server/worldserver/RemoteAccess/RASocket.cpp2
-rw-r--r--src/server/worldserver/worldserver.conf.dist3
71 files changed, 744 insertions, 548 deletions
diff --git a/src/server/game/AI/CoreAI/GameObjectAI.h b/src/server/game/AI/CoreAI/GameObjectAI.h
index 8d0e0508113..93cd3a6d237 100644
--- a/src/server/game/AI/CoreAI/GameObjectAI.h
+++ b/src/server/game/AI/CoreAI/GameObjectAI.h
@@ -49,6 +49,7 @@ class GameObjectAI
virtual uint32 GetDialogStatus(Player* /*player*/) {return 100;}
virtual void Destroyed(Player* /*player*/, uint32 /*eventId*/) {}
virtual void SetData(uint32 /*id*/, uint32 /*value*/) {}
+ virtual void OnGameEvent(bool /*start*/, uint16 /*eventId*/) {}
};
class NullGameObjectAI : public GameObjectAI
diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h
index 3c16fe493b4..444dce0339e 100755
--- a/src/server/game/AI/CoreAI/UnitAI.h
+++ b/src/server/game/AI/CoreAI/UnitAI.h
@@ -267,6 +267,7 @@ class UnitAI
virtual void sQuestComplete(Player* /*player*/, Quest const* /*quest*/) {}
virtual void sQuestReward(Player* /*player*/, Quest const* /*quest*/, uint32 /*opt*/) {}
virtual bool sOnDummyEffect(Unit* /*caster*/, uint32 /*spellId*/, SpellEffIndex /*effIndex*/) { return false; }
+ virtual void sOnGameEvent(bool /*start*/, uint16 /*eventId*/) {}
};
class PlayerAI : public UnitAI
diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
index 06c1570ccd9..c5f04d4ff5f 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
@@ -543,7 +543,6 @@ bool npc_escortAI::GetWaypointPosition(uint32 pointId, float& x, float& y, float
if (waypoints.empty())
return false;
- ScriptPointVector::const_iterator itrEnd = waypoints.end();
for (ScriptPointVector::const_iterator itr = waypoints.begin(); itr != waypoints.end(); ++itr)
{
if (itr->uiPointId == pointId)
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index afa7e9c2932..7dd793a302b 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -707,7 +707,7 @@ void SmartAI::SetRun(bool run)
me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
else
me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
- me->SendMovementFlagUpdate();
+
mRun = run;
}
@@ -811,6 +811,12 @@ void SmartAI::SetScript9(SmartScriptHolder& e, uint32 entry, Unit* invoker)
GetScript()->mLastInvoker = invoker->GetGUID();
GetScript()->SetScript9(e, entry);
}
+
+void SmartAI::sOnGameEvent(bool start, uint16 eventId)
+{
+ GetScript()->ProcessEventsFor(start ? SMART_EVENT_GAME_EVENT_START : SMART_EVENT_GAME_EVENT_END, NULL, eventId);
+}
+
/*
SMART_EVENT_UPDATE_OOC
SMART_EVENT_SPELLHIT
@@ -913,6 +919,11 @@ void SmartGameObjectAI::SetScript9(SmartScriptHolder& e, uint32 entry, Unit* inv
GetScript()->SetScript9(e, entry);
}
+void SmartGameObjectAI::OnGameEvent(bool start, uint16 eventId)
+{
+ GetScript()->ProcessEventsFor(start ? SMART_EVENT_GAME_EVENT_START : SMART_EVENT_GAME_EVENT_END, NULL, eventId);
+}
+
class SmartTrigger : public AreaTriggerScript
{
public:
diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h
index 8bb3bda8dd6..dc1f901d477 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.h
+++ b/src/server/game/AI/SmartScripts/SmartAI.h
@@ -183,6 +183,7 @@ class SmartAI : public CreatureAI
//void sQuestComplete(Player* player, Quest const* quest);
void sQuestReward(Player* player, Quest const* quest, uint32 opt);
bool sOnDummyEffect(Unit* caster, uint32 spellId, SpellEffIndex effIndex);
+ void sOnGameEvent(bool start, uint16 eventId);
uint32 mEscortQuestID;
@@ -249,6 +250,7 @@ public:
void Destroyed(Player* player, uint32 eventId);
void SetData(uint32 id, uint32 value);
void SetScript9(SmartScriptHolder& e, uint32 entry, Unit* invoker);
+ void OnGameEvent(bool start, uint16 eventId);
protected:
GameObject* const go;
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index ffe21536de4..dded086b584 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -1493,7 +1493,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
else if (GameObject* goTarget = (*itr)->ToGameObject())
{
if (IsSmartGO(goTarget))
- CAST_AI(SmartGameObjectAI, target->AI())->SetScript9(e, e.action.timedActionList.id, GetLastInvoker());
+ CAST_AI(SmartGameObjectAI, goTarget->AI())->SetScript9(e, e.action.timedActionList.id, GetLastInvoker());
}
}
@@ -1610,7 +1610,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
else if (GameObject* goTarget = (*itr)->ToGameObject())
{
if (IsSmartGO(goTarget))
- CAST_AI(SmartGameObjectAI, target->AI())->SetScript9(e, id, GetLastInvoker());
+ CAST_AI(SmartGameObjectAI, goTarget->AI())->SetScript9(e, id, GetLastInvoker());
}
}
@@ -1640,7 +1640,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
else if (GameObject* goTarget = (*itr)->ToGameObject())
{
if (IsSmartGO(goTarget))
- CAST_AI(SmartGameObjectAI, target->AI())->SetScript9(e, id, GetLastInvoker());
+ CAST_AI(SmartGameObjectAI, goTarget->AI())->SetScript9(e, id, GetLastInvoker());
}
}
@@ -1786,8 +1786,8 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!GetBaseObject())
return;
- sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SEND_GOSSIP_MENU: gossipMenuId %d, gossip_option_id %d",
- e.action.sendGossipMenu.gossipMenuId, e.action.sendGossipMenu.gossipOptionId);
+ sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SEND_GOSSIP_MENU: gossipMenuId %d, gossipNpcTextId %d",
+ e.action.sendGossipMenu.gossipMenuId, e.action.sendGossipMenu.gossipNpcTextId);
ObjectList* targets = GetTargets(e, unit);
if (!targets)
@@ -1801,7 +1801,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
else
player->PlayerTalkClass->ClearMenus();
- player->SEND_GOSSIP_MENU(e.action.sendGossipMenu.gossipOptionId, GetBaseObject()->GetGUID());
+ player->SEND_GOSSIP_MENU(e.action.sendGossipMenu.gossipNpcTextId, GetBaseObject()->GetGUID());
}
delete targets;
@@ -2595,6 +2595,14 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
ProcessAction(e, unit, var0, var1);
break;
}
+ case SMART_EVENT_GAME_EVENT_START:
+ case SMART_EVENT_GAME_EVENT_END:
+ {
+ if (e.event.gameEvent.gameEventId != var0)
+ return;
+ ProcessAction(e, NULL, var0);
+ break;
+ }
default:
sLog->outErrorDb("SmartScript::ProcessEvent: Unhandled Event type %u", e.GetEventType());
break;
@@ -2996,7 +3004,9 @@ void SmartScript::SetScript9(SmartScriptHolder& e, uint32 entry)
mResumeActionList = e.action.timedActionList.dontResume ? false : true;
InitTimer((*i));
}
-}Unit* SmartScript::GetLastInvoker()
+}
+
+Unit* SmartScript::GetLastInvoker()
{
return ObjectAccessor::FindUnit(mLastInvoker);
}
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
index 011ed75205d..1df5849ca75 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -26,6 +26,7 @@
#include "CellImpl.h"
#include "InstanceScript.h"
#include "ScriptedCreature.h"
+#include "GameEventMgr.h"
#include "SmartScriptMgr.h"
@@ -466,6 +467,14 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
if (!IsMinMaxValid(e, e.event.behindTarget.cooldownMin, e.event.behindTarget.cooldownMax))
return false;
break;
+ case SMART_EVENT_GAME_EVENT_START:
+ case SMART_EVENT_GAME_EVENT_END:
+ {
+ GameEventMgr::GameEventDataMap const& events = sGameEventMgr->GetEventMap();
+ if (e.event.gameEvent.gameEventId >= events.size() || !events[e.event.gameEvent.gameEventId].isValid())
+ return false;
+ break;
+ }
case SMART_EVENT_TIMED_EVENT_TRIGGERED:
case SMART_EVENT_INSTANCE_PLAYER_ENTER:
case SMART_EVENT_TRANSPORT_RELOCATE:
@@ -492,7 +501,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
case SMART_EVENT_WAYPOINT_RESUMED:
case SMART_EVENT_WAYPOINT_STOPPED:
case SMART_EVENT_WAYPOINT_ENDED:
- case SMART_ACTION_PLAYMOVIE:
case SMART_EVENT_GOSSIP_SELECT:
case SMART_EVENT_GOSSIP_HELLO:
case SMART_EVENT_JUST_CREATED:
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index ba986ae310d..ea15cb46375 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -152,8 +152,10 @@ enum SMART_EVENT
SMART_EVENT_FOLLOW_COMPLETED = 65, //1 // none
SMART_EVENT_DUMMY_EFFECT = 66, //1 // spellId, effectIndex
SMART_EVENT_IS_BEHIND_TARGET = 67, //1 // cooldownMin, CooldownMax
+ SMART_EVENT_GAME_EVENT_START = 68, //1 // game_event.Entry
+ SMART_EVENT_GAME_EVENT_END = 69, //1 // game_event.Entry
- SMART_EVENT_END = 68,
+ SMART_EVENT_END = 70,
};
struct SmartEvent
@@ -338,6 +340,11 @@ struct SmartEvent
uint32 cooldownMax;
} behindTarget;
+ struct
+ {
+ uint32 gameEventId;
+ } gameEvent;
+
struct
{
uint32 param1;
@@ -862,7 +869,7 @@ struct SmartAction
struct
{
uint32 gossipMenuId;
- uint32 gossipOptionId;
+ uint32 gossipNpcTextId;
} sendGossipMenu;
struct
@@ -1128,7 +1135,9 @@ const uint32 SmartAIEventMask[SMART_EVENT_END][2] =
{SMART_EVENT_GOSSIP_HELLO, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT },
{SMART_EVENT_FOLLOW_COMPLETED, SMART_SCRIPT_TYPE_MASK_CREATURE },
{SMART_EVENT_DUMMY_EFFECT, SMART_SCRIPT_TYPE_MASK_SPELL },
- {SMART_EVENT_IS_BEHIND_TARGET, SMART_SCRIPT_TYPE_MASK_CREATURE }
+ {SMART_EVENT_IS_BEHIND_TARGET, SMART_SCRIPT_TYPE_MASK_CREATURE },
+ {SMART_EVENT_GAME_EVENT_START, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT },
+ {SMART_EVENT_GAME_EVENT_END, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT },
};
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index 8967446f199..c43bfb2ca8b 100755
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -102,6 +102,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST: // only Children's Week achievements
case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: // only Children's Week achievements
case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
break;
default:
if (dataType != ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT)
@@ -135,13 +136,13 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
}
if (classRace.class_id && ((1 << (classRace.class_id-1)) & CLASSMASK_ALL_PLAYABLE) == 0)
{
- sLog->outErrorDb("Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE (%u) has non-existing class in value1 (%u), ignored.",
+ sLog->outErrorDb("Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_CLASS_RACE (%u) has non-existing class in value1 (%u), ignored.",
criteria->ID, criteria->requiredType, dataType, classRace.class_id);
return false;
}
if (classRace.race_id && ((1 << (classRace.race_id-1)) & RACEMASK_ALL_PLAYABLE) == 0)
{
- sLog->outErrorDb("Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE (%u) has non-existing race in value2 (%u), ignored.",
+ sLog->outErrorDb("Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_CLASS_RACE (%u) has non-existing race in value2 (%u), ignored.",
criteria->ID, criteria->requiredType, dataType, classRace.race_id);
return false;
}
@@ -450,7 +451,7 @@ void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, uin
continue;
// don't update already completed criteria if not forced or achievement already complete
- if ((IsCompletedCriteria(achievementCriteria, achievement) && !evenIfCriteriaComplete) || HasAchieved(achievement))
+ if ((IsCompletedCriteria(achievementCriteria, achievement) && !evenIfCriteriaComplete) || HasAchieved(achievement->ID))
continue;
for (uint8 j = 0; j < MAX_CRITERIA_REQUIREMENTS; ++j)
@@ -846,6 +847,9 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
+ if (AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria))
+ if (!data->Meets(GetPlayer(), unit))
+ continue;
SetCriteriaProgress(achievementCriteria, GetPlayer()->getLevel());
break;
case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL:
@@ -1597,9 +1601,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
}
}
-static const uint32 achievIdByClass[MAX_CLASSES] = { 0, 459, 465, 462, 458, 464, 461, 467, 460, 463, 0, 466 };
-static const uint32 achievIdByRace[MAX_RACES] = { 0, 1408, 1410, 1407, 1409, 1413, 1411, 1404, 1412, 0, 1405, 1406 };
-
bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement)
{
// counter can never complete
@@ -1624,20 +1625,7 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
return progress->counter >= achievementCriteria->kill_creature.creatureCount;
case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
- {
- // skip wrong class achievements
- for (int i = 1; i < MAX_CLASSES; ++i)
- if (achievIdByClass[i] == achievement->ID && i != GetPlayer()->getClass())
- return false;
-
- // skip wrong race achievements
- for (int i = 1; i < MAX_RACES; ++i)
- if (achievIdByRace[i] == achievement->ID && i != GetPlayer()->getRace())
- return false;
-
- // appropriate class/race or not class/race specific
return progress->counter >= achievementCriteria->reach_level.level;
- }
case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL:
return progress->counter >= achievementCriteria->reach_skill_level.skillLevel;
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT:
@@ -1778,7 +1766,7 @@ void AchievementMgr::CompletedCriteriaFor(AchievementEntry const* achievement)
return;
// already completed and stored
- if (HasAchieved(achievement))
+ if (HasAchieved(achievement->ID))
return;
if (IsCompletedAchievement(achievement))
@@ -2012,7 +2000,7 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
if (m_player->isGameMaster())
return;
- if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER || HasAchieved(achievement))
+ if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER || HasAchieved(achievement->ID))
return;
SendAchievementEarned(achievement);
@@ -2127,9 +2115,9 @@ void AchievementMgr::BuildAllDataPacket(WorldPacket* data) const
*data << int32(-1);
}
-bool AchievementMgr::HasAchieved(AchievementEntry const* achievement) const
+bool AchievementMgr::HasAchieved(uint32 achievementId) const
{
- return m_completedAchievements.find(achievement->ID) != m_completedAchievements.end();
+ return m_completedAchievements.find(achievementId) != m_completedAchievements.end();
}
bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement)
@@ -2393,15 +2381,16 @@ void AchievementGlobalMgr::LoadCompletedAchievements()
Field* fields = result->Fetch();
uint32 achievement_id = fields[0].GetUInt32();
- if (!sAchievementStore.LookupEntry(achievement_id))
+ const AchievementEntry* achievement = sAchievementStore.LookupEntry(achievement_id);
+ if (!achievement)
{
// we will remove not existed achievement for all characters
sLog->outError("Non-existing achievement %u data removed from table `character_achievement`.", achievement_id);
CharacterDatabase.PExecute("DELETE FROM character_achievement WHERE achievement = %u", achievement_id);
continue;
}
-
- m_allCompletedAchievements.insert(achievement_id);
+ else if (achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_REACH | ACHIEVEMENT_FLAG_REALM_FIRST_KILL))
+ m_allCompletedAchievements.insert(achievement_id);
} while (result->NextRow());
sLog->outString(">> Loaded %lu completed achievements in %u ms", (unsigned long)m_allCompletedAchievements.size(), GetMSTimeDiffToNow(oldMSTime));
diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h
index 7f66565622f..f88be974c9d 100755
--- a/src/server/game/Achievements/AchievementMgr.h
+++ b/src/server/game/Achievements/AchievementMgr.h
@@ -257,7 +257,7 @@ class AchievementMgr
void CheckAllAchievementCriteria();
void SendAllAchievementData() const;
void SendRespondInspectAchievements(Player* player) const;
- bool HasAchieved(AchievementEntry const* achievement) const;
+ bool HasAchieved(uint32 achievementId) const;
Player* GetPlayer() const { return m_player; }
void UpdateTimedAchievements(uint32 timeDiff);
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost = 0);
diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp
index 1968de70f46..244c05ec0ad 100755
--- a/src/server/game/Chat/Channels/Channel.cpp
+++ b/src/server/game/Chat/Channels/Channel.cpp
@@ -310,18 +310,22 @@ void Channel::KickOrBan(uint64 good, const char *badname, bool ban)
bool changeowner = (m_ownerGUID == bad->GetGUID());
WorldPacket data;
+ bool notify = !(AccountMgr::IsGMAccount(sec) && sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL));
if (ban && !IsBanned(bad->GetGUID()))
{
banned.insert(bad->GetGUID());
- MakePlayerBanned(&data, bad->GetGUID(), good);
-
UpdateChannelInDB();
+
+ if (notify)
+ MakePlayerBanned(&data, bad->GetGUID(), good);
}
- else
+ else if (notify)
MakePlayerKicked(&data, bad->GetGUID(), good);
- SendToAll(&data);
+ if (notify)
+ SendToAll(&data);
+
players.erase(bad->GetGUID());
bad->LeftChannel(this);
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index be43862eaea..185ac487481 100755
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -303,29 +303,29 @@ ChatCommand* ChatHandler::getCommandTable()
static ChatCommand ticketResponseCommandTable[] =
{
- { "append", SEC_MODERATOR, false, OldHandler<&ChatHandler::HandleGMTicketResponseAppendCommand>, "", NULL },
- { "appendln", SEC_MODERATOR, false, OldHandler<&ChatHandler::HandleGMTicketResponseAppendLnCommand>, "", NULL },
+ { "append", SEC_MODERATOR, true, OldHandler<&ChatHandler::HandleGMTicketResponseAppendCommand>, "", NULL },
+ { "appendln", SEC_MODERATOR, true, OldHandler<&ChatHandler::HandleGMTicketResponseAppendLnCommand>, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand ticketCommandTable[] =
{
- { "list", SEC_MODERATOR, false, OldHandler<&ChatHandler::HandleGMTicketListCommand>, "", NULL },
- { "onlinelist", SEC_MODERATOR, false, OldHandler<&ChatHandler::HandleGMTicketListOnlineCommand>, "", NULL },
- { "viewname", SEC_MODERATOR, false, OldHandler<&ChatHandler::HandleGMTicketGetByNameCommand>, "", NULL },
- { "viewid", SEC_MODERATOR, false, OldHandler<&ChatHandler::HandleGMTicketGetByIdCommand>, "", NULL },
- { "close", SEC_MODERATOR, false, OldHandler<&ChatHandler::HandleGMTicketCloseByIdCommand>, "", NULL },
- { "closedlist", SEC_MODERATOR, false, OldHandler<&ChatHandler::HandleGMTicketListClosedCommand>, "", NULL },
- { "escalatedlist", SEC_GAMEMASTER, false, OldHandler<&ChatHandler::HandleGMTicketListEscalatedCommand>, "", NULL },
- { "delete", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleGMTicketDeleteByIdCommand>, "", NULL },
- { "reset", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleGMTicketResetCommand>, "", NULL },
- { "assign", SEC_GAMEMASTER, false, OldHandler<&ChatHandler::HandleGMTicketAssignToCommand>, "", NULL },
- { "unassign", SEC_GAMEMASTER, false, OldHandler<&ChatHandler::HandleGMTicketUnAssignCommand>, "", NULL },
- { "comment", SEC_MODERATOR, false, OldHandler<&ChatHandler::HandleGMTicketCommentCommand>, "", NULL },
- { "togglesystem", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleToggleGMTicketSystem>, "", NULL },
- { "escalate", SEC_MODERATOR, false, OldHandler<&ChatHandler::HandleGMTicketEscalateCommand>, "", NULL },
- { "response", SEC_MODERATOR, false, NULL, "", ticketResponseCommandTable },
- { "complete", SEC_MODERATOR, false, OldHandler<&ChatHandler::HandleGMTicketCompleteCommand>, "", NULL },
+ { "list", SEC_MODERATOR, true, OldHandler<&ChatHandler::HandleGMTicketListCommand>, "", NULL },
+ { "onlinelist", SEC_MODERATOR, true, OldHandler<&ChatHandler::HandleGMTicketListOnlineCommand>, "", NULL },
+ { "viewname", SEC_MODERATOR, true, OldHandler<&ChatHandler::HandleGMTicketGetByNameCommand>, "", NULL },
+ { "viewid", SEC_MODERATOR, true, OldHandler<&ChatHandler::HandleGMTicketGetByIdCommand>, "", NULL },
+ { "close", SEC_MODERATOR, true, OldHandler<&ChatHandler::HandleGMTicketCloseByIdCommand>, "", NULL },
+ { "closedlist", SEC_MODERATOR, true, OldHandler<&ChatHandler::HandleGMTicketListClosedCommand>, "", NULL },
+ { "escalatedlist", SEC_GAMEMASTER, true, OldHandler<&ChatHandler::HandleGMTicketListEscalatedCommand>, "", NULL },
+ { "delete", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleGMTicketDeleteByIdCommand>, "", NULL },
+ { "reset", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleGMTicketResetCommand>, "", NULL },
+ { "assign", SEC_GAMEMASTER, true, OldHandler<&ChatHandler::HandleGMTicketAssignToCommand>, "", NULL },
+ { "unassign", SEC_GAMEMASTER, true, OldHandler<&ChatHandler::HandleGMTicketUnAssignCommand>, "", NULL },
+ { "comment", SEC_MODERATOR, true, OldHandler<&ChatHandler::HandleGMTicketCommentCommand>, "", NULL },
+ { "togglesystem", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleToggleGMTicketSystem>, "", NULL },
+ { "escalate", SEC_MODERATOR, true, OldHandler<&ChatHandler::HandleGMTicketEscalateCommand>, "", NULL },
+ { "response", SEC_MODERATOR, true, NULL, "", ticketResponseCommandTable },
+ { "complete", SEC_MODERATOR, true, OldHandler<&ChatHandler::HandleGMTicketCompleteCommand>, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
diff --git a/src/server/game/Chat/Commands/Level0.cpp b/src/server/game/Chat/Commands/Level0.cpp
index 338ad49463e..97173f75652 100755
--- a/src/server/game/Chat/Commands/Level0.cpp
+++ b/src/server/game/Chat/Commands/Level0.cpp
@@ -84,8 +84,8 @@ bool ChatHandler::HandleStartCommand(const char* /*args*/)
bool ChatHandler::HandleServerInfoCommand(const char* /*args*/)
{
- uint32 PlayersNum = sWorld->GetPlayerCount();
- uint32 MaxPlayersNum = sWorld->GetMaxPlayerCount();
+ uint32 playersNum = sWorld->GetPlayerCount();
+ uint32 maxPlayersNum = sWorld->GetMaxPlayerCount();
uint32 activeClientsNum = sWorld->GetActiveSessionCount();
uint32 queuedClientsNum = sWorld->GetQueuedSessionCount();
uint32 maxActiveClientsNum = sWorld->GetMaxActiveSessionCount();
@@ -94,10 +94,13 @@ bool ChatHandler::HandleServerInfoCommand(const char* /*args*/)
uint32 updateTime = sWorld->GetUpdateTime();
SendSysMessage(_FULLVERSION);
- PSendSysMessage(LANG_CONNECTED_PLAYERS, PlayersNum, MaxPlayersNum);
+ PSendSysMessage(LANG_CONNECTED_PLAYERS, playersNum, maxPlayersNum);
PSendSysMessage(LANG_CONNECTED_USERS, activeClientsNum, maxActiveClientsNum, queuedClientsNum, maxQueuedClientsNum);
PSendSysMessage(LANG_UPTIME, uptime.c_str());
- PSendSysMessage("Update time diff: %u.", updateTime);
+ PSendSysMessage(LANG_UPDATE_DIFF, updateTime);
+ //! Can't use sWorld->ShutdownMsg here in case of console command
+ if (sWorld->IsShuttingDown())
+ PSendSysMessage(LANG_SHUTDOWN_TIMELEFT, secsToTimeString(sWorld->GetShutDownTimeLeft()).c_str());
return true;
}
diff --git a/src/server/game/Chat/Commands/TicketCommands.cpp b/src/server/game/Chat/Commands/TicketCommands.cpp
index 7caf63aac2b..d38da9eb97c 100755
--- a/src/server/game/Chat/Commands/TicketCommands.cpp
+++ b/src/server/game/Chat/Commands/TicketCommands.cpp
@@ -85,12 +85,14 @@ bool ChatHandler::HandleGMTicketGetByNameCommand(const char* args)
guid = player->GetGUID();
else
guid = sObjectMgr->GetPlayerGUIDByName(name);
+
// Target must exist
if (!guid)
{
SendSysMessage(LANG_NO_PLAYERS_FOUND);
return true;
}
+
// Ticket must exist
GmTicket *ticket = sTicketMgr->GetTicketByPlayer(guid);
if (!ticket)
@@ -119,27 +121,32 @@ bool ChatHandler::HandleGMTicketCloseByIdCommand(const char* args)
SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
return true;
}
- // Ticket must be assigned to player, who tries to close it.
- uint64 guid = m_session->GetPlayer()->GetGUID();
- if (ticket->IsAssignedNotTo(guid))
+
+ // Ticket should be assigned to the player who tries to close it.
+ // Console can override though
+ Player* player = m_session ? m_session->GetPlayer() : NULL;
+ if (player && ticket->IsAssignedNotTo(player->GetGUID()))
{
PSendSysMessage(LANG_COMMAND_TICKETCANNOTCLOSE, ticket->GetId());
return true;
}
- sTicketMgr->CloseTicket(ticket->GetId(), guid);
+
+ sTicketMgr->CloseTicket(ticket->GetId(), player ? player->GetGUID() : -1);
sTicketMgr->UpdateLastChange();
- std::string msg = ticket->FormatMessageString(*this, m_session->GetPlayer()->GetName(), NULL, NULL, NULL);
+ std::string msg = ticket->FormatMessageString(*this, player ? player->GetName() : "Console", NULL, NULL, NULL);
SendGlobalGMSysMessage(msg.c_str());
// Inform player, who submitted this ticket, that it is closed
- if (Player* player = ticket->GetPlayer())
- if (player->IsInWorld())
+ if (Player* submitter = ticket->GetPlayer())
+ {
+ if (submitter->IsInWorld())
{
WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
data << uint32(GMTICKET_RESPONSE_TICKET_DELETED);
- player->GetSession()->SendPacket(&data);
+ submitter->GetSession()->SendPacket(&data);
}
+ }
return true;
}
@@ -170,25 +177,30 @@ bool ChatHandler::HandleGMTicketAssignToCommand(const char* args)
uint64 targetGuid = sObjectMgr->GetPlayerGUIDByName(target.c_str());
uint64 targetAccId = sObjectMgr->GetPlayerAccountIdByGUID(targetGuid);
uint32 targetGmLevel = AccountMgr::GetSecurity(targetAccId, realmID);
+
// Target must exist and have administrative rights
if (!targetGuid || AccountMgr::IsPlayerAccount(targetGmLevel))
{
SendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_A);
return true;
}
+
// If already assigned, leave
if (ticket->IsAssignedTo(targetGuid))
{
PSendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_B, ticket->GetId());
return true;
}
+
// If assigned to different player other than current, leave
- Player* player = m_session->GetPlayer();
- if (ticket->IsAssignedNotTo(player->GetGUID()))
+ //! Console can override though
+ Player* player = m_session ? m_session->GetPlayer() : NULL;
+ if (player && ticket->IsAssignedNotTo(player->GetGUID()))
{
PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->GetId(), target.c_str());
return true;
}
+
// Assign ticket
SQLTransaction trans = SQLTransaction(NULL);
ticket->SetAssignedTo(targetGuid, AccountMgr::IsAdminAccount(targetGmLevel));
@@ -218,6 +230,7 @@ bool ChatHandler::HandleGMTicketUnAssignCommand(const char* args)
PSendSysMessage(LANG_COMMAND_TICKETNOTASSIGNED, ticket->GetId());
return true;
}
+
// Get security level of player, whom this ticket is assigned to
uint32 security = SEC_PLAYER;
Player* assignedPlayer = ticket->GetAssignedPlayer();
@@ -229,9 +242,11 @@ bool ChatHandler::HandleGMTicketUnAssignCommand(const char* args)
uint32 accountId = sObjectMgr->GetPlayerAccountIdByGUID(guid);
security = AccountMgr::GetSecurity(accountId, realmID);
}
+
// Check security
- Player* player = m_session->GetPlayer();
- if (security > uint32(player->GetSession()->GetSecurity()))
+ //! If no m_session present it means we're issuing this command from the console
+ uint32 mySecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE;
+ if (security > mySecurity)
{
SendSysMessage(LANG_COMMAND_TICKETUNASSIGNSECURITY);
return true;
@@ -242,7 +257,8 @@ bool ChatHandler::HandleGMTicketUnAssignCommand(const char* args)
ticket->SaveToDB(trans);
sTicketMgr->UpdateLastChange();
- std::string msg = ticket->FormatMessageString(*this, NULL, ticket->GetAssignedToName().c_str(), player->GetName(), NULL);
+ std::string msg = ticket->FormatMessageString(*this, NULL, ticket->GetAssignedToName().c_str(),
+ m_session ? m_session->GetPlayer()->GetName() : "Console", NULL);
SendGlobalGMSysMessage(msg.c_str());
return true;
}
@@ -265,9 +281,11 @@ bool ChatHandler::HandleGMTicketCommentCommand(const char* args)
PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
return true;
}
+
// Cannot comment ticket assigned to someone else
- Player* player = m_session->GetPlayer();
- if (ticket->IsAssignedNotTo(player->GetGUID()))
+ //! Console excluded
+ Player* player = m_session ? m_session->GetPlayer() : NULL;
+ if (player && ticket->IsAssignedNotTo(player->GetGUID()))
{
PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->GetId());
return true;
@@ -279,7 +297,7 @@ bool ChatHandler::HandleGMTicketCommentCommand(const char* args)
sTicketMgr->UpdateLastChange();
std::string msg = ticket->FormatMessageString(*this, NULL, ticket->GetAssignedToName().c_str(), NULL, NULL);
- msg += PGetParseString(LANG_COMMAND_TICKETLISTADDCOMMENT, player->GetName(), comment);
+ msg += PGetParseString(LANG_COMMAND_TICKETLISTADDCOMMENT, player ? player->GetName() : "Console", comment);
SendGlobalGMSysMessage(msg.c_str());
return true;
@@ -297,19 +315,21 @@ bool ChatHandler::HandleGMTicketDeleteByIdCommand(const char* args)
SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
return true;
}
+
if (!ticket->IsClosed())
{
SendSysMessage(LANG_COMMAND_TICKETCLOSEFIRST);
return true;
}
- std::string msg = ticket->FormatMessageString(*this, NULL, NULL, NULL, m_session->GetPlayer()->GetName());
+ std::string msg = ticket->FormatMessageString(*this, NULL, NULL, NULL, m_session ? m_session->GetPlayer()->GetName() : "Console");
SendGlobalGMSysMessage(msg.c_str());
sTicketMgr->RemoveTicket(ticket->GetId());
sTicketMgr->UpdateLastChange();
if (Player* player = ticket->GetPlayer())
+ {
if (player->IsInWorld())
{
// Force abandon ticket
@@ -317,6 +337,7 @@ bool ChatHandler::HandleGMTicketDeleteByIdCommand(const char* args)
data << uint32(GMTICKET_RESPONSE_TICKET_DELETED);
player->GetSession()->SendPacket(&data);
}
+ }
return true;
}
@@ -406,9 +427,11 @@ inline bool ChatHandler::_HandleGMTicketResponseAppendCommand(const char* args,
PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
return true;
}
+
// Cannot add response to ticket, assigned to someone else
- Player* player = m_session->GetPlayer();
- if (ticket->IsAssignedNotTo(player->GetGUID()))
+ //! Console excluded
+ Player* player = m_session ? m_session->GetPlayer() : NULL;
+ if (player && ticket->IsAssignedNotTo(player->GetGUID()))
{
PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->GetId());
return true;
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index bfefb3e4e76..cf349044042 100755
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -67,11 +67,8 @@ bool Condition::Meets(Player* player, Unit* invoker)
break;
}
case CONDITION_ACHIEVEMENT:
- {
- AchievementEntry const* achievement = GetAchievementStore()->LookupEntry(mConditionValue1);
- condMeets = player->GetAchievementMgr().HasAchieved(achievement);
+ condMeets = player->GetAchievementMgr().HasAchieved(mConditionValue1);
break;
- }
case CONDITION_TEAM:
condMeets = player->GetTeam() == mConditionValue1;
break;
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index dcdc2b2ea0a..a13761d121f 100755
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -417,7 +417,7 @@ enum SummonPropFlags
enum VehicleSeatFlags
{
VEHICLE_SEAT_FLAG_HIDE_PASSENGER = 0x00000200, // Passenger is hidden
- VEHICLE_SEAT_FLAG_UNK11 = 0x00000400, // needed for CGCamera__SyncFreeLookFacing
+ VEHICLE_SEAT_FLAG_UNK1 = 0x00000400, // needed for CGCamera__SyncFreeLookFacing
VEHICLE_SEAT_FLAG_CAN_CONTROL = 0x00000800, // Lua_UnitInVehicleControlSeat
VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL = 0x00001000, // Can cast spells with SPELL_AURA_MOUNTED from seat (possibly 4.x only, 0 seats on 3.3.5a)
VEHICLE_SEAT_FLAG_UNCONTROLLED = 0x00002000, // can override !& VEHICLE_SEAT_FLAG_CAN_ENTER_OR_EXIT
@@ -425,6 +425,7 @@ enum VehicleSeatFlags
VEHICLE_SEAT_FLAG_CAN_ENTER_OR_EXIT = 0x02000000, // Lua_CanExitVehicle - can enter and exit at free will
VEHICLE_SEAT_FLAG_CAN_SWITCH = 0x04000000, // Lua_CanSwitchVehicleSeats
VEHICLE_SEAT_FLAG_CAN_CAST = 0x20000000, // Lua_UnitHasVehicleUI
+ VEHICLE_SEAT_FLAG_UNK2 = 0x40000000, // checked in conjunction with 0x800 in CastSpell2
};
enum VehicleSeatFlagsB
@@ -435,7 +436,6 @@ enum VehicleSeatFlagsB
VEHICLE_SEAT_FLAG_B_EJECTABLE = 0x00000020, // ejectable
VEHICLE_SEAT_FLAG_B_USABLE_FORCED_2 = 0x00000040,
VEHICLE_SEAT_FLAG_B_USABLE_FORCED_3 = 0x00000100,
- VEHICLE_SEAT_FLAG_B_CANSWITCH = 0x04000000, // can switch seats
VEHICLE_SEAT_FLAG_B_VEHICLE_PLAYERFRAME_UI = 0x80000000, // Lua_UnitHasVehiclePlayerFrameUI - actually checked for flagsb &~ 0x80000000
};
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index ba7be495c77..f04f3368b0f 100755
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -1939,7 +1939,7 @@ struct VehicleSeatEntry
// 46-57 added in 3.1, floats mostly
bool CanEnterOrExit() const { return m_flags & VEHICLE_SEAT_FLAG_CAN_ENTER_OR_EXIT; }
- bool CanSwitchFromSeat() const { return m_flags & VEHICLE_SEAT_FLAG_B_CANSWITCH; }
+ bool CanSwitchFromSeat() const { return m_flags & VEHICLE_SEAT_FLAG_CAN_SWITCH; }
bool IsUsableByOverride() const { return (m_flags & VEHICLE_SEAT_FLAG_UNCONTROLLED)
|| (m_flagsB & (VEHICLE_SEAT_FLAG_B_USABLE_FORCED | VEHICLE_SEAT_FLAG_B_USABLE_FORCED_2 | VEHICLE_SEAT_FLAG_B_USABLE_FORCED_3)); }
bool IsEjectable() const { return m_flagsB & VEHICLE_SEAT_FLAG_B_EJECTABLE; }
diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp
index 55f798204db..21ff3c6e4e8 100755
--- a/src/server/game/DungeonFinding/LFGMgr.cpp
+++ b/src/server/game/DungeonFinding/LFGMgr.cpp
@@ -389,7 +389,7 @@ void LFGMgr::InitializeLockedDungeons(Player* player)
locktype = LFG_LOCKSTATUS_TOO_HIGH_LEVEL;
else if (locktype == LFG_LOCKSTATUS_OK && ar)
{
- if (ar->achievement && !player->GetAchievementMgr().HasAchieved(sAchievementStore.LookupEntry(ar->achievement)))
+ if (ar->achievement && !player->GetAchievementMgr().HasAchieved(ar->achievement))
locktype = LFG_LOCKSTATUS_RAID_LOCKED; // FIXME: Check the correct lock value
else if (player->GetTeam() == ALLIANCE && ar->quest_A && !player->GetQuestRewardStatus(ar->quest_A))
locktype = LFG_LOCKSTATUS_QUEST_NOT_COMPLETED;
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp
index 5bf7910466c..398deb04723 100755
--- a/src/server/game/Entities/Creature/GossipDef.cpp
+++ b/src/server/game/Entities/Creature/GossipDef.cpp
@@ -516,7 +516,7 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const
data << uint32(quest->RequiredNpcOrGo[i]);
data << uint32(quest->RequiredNpcOrGoCount[i]);
- data << uint32(quest->RequiredSourceItemid[i]);
+ data << uint32(quest->RequiredSourceItemId[i]);
data << uint32(0); // req source count?
}
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 978d9accb64..d4723cbec42 100755
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -1642,7 +1642,7 @@ bool WorldObject::canSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo
bool corpseVisibility = false;
if (distanceCheck)
{
- if (const Player* thisPlayer = ToPlayer())
+ if (Player const* thisPlayer = ToPlayer())
{
if (thisPlayer->isDead() && thisPlayer->GetHealth() > 0 && // Cheap way to check for ghost state
!(obj->m_serverSideVisibility.GetValue(SERVERSIDE_VISIBILITY_GHOST) & m_serverSideVisibility.GetValue(SERVERSIDE_VISIBILITY_GHOST) & GHOST_VISIBILITY_GHOST))
@@ -1675,9 +1675,9 @@ bool WorldObject::canSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo
if (!corpseVisibility && !(obj->m_serverSideVisibility.GetValue(SERVERSIDE_VISIBILITY_GHOST) & m_serverSideVisibilityDetect.GetValue(SERVERSIDE_VISIBILITY_GHOST)))
{
// Alive players can see dead players in some cases, but other objects can't do that
- if (const Player* thisPlayer = ToPlayer())
+ if (Player const* thisPlayer = ToPlayer())
{
- if (const Player* objPlayer = obj->ToPlayer())
+ if (Player const* objPlayer = obj->ToPlayer())
{
if (thisPlayer->GetTeam() != objPlayer->GetTeam() || !thisPlayer->IsGroupVisibleFor(objPlayer))
return false;
@@ -2018,7 +2018,6 @@ void WorldObject::SendMessageToSet(WorldPacket* data, bool self)
SendMessageToSetInRange(data, GetVisibilityRange(), self);
}
-
void WorldObject::SendMessageToSetInRange(WorldPacket* data, float dist, bool /*self*/)
{
Trinity::MessageDistDeliverer notifier(this, data, dist);
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 401e965f816..bd85968ca9a 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -2052,28 +2052,6 @@ void Player::SendTeleportAckPacket()
GetSession()->SendPacket(&data);
}
-// this is not used anywhere
-void Player::TeleportOutOfMap(Map* oldMap)
-{
- while (IsBeingTeleportedFar())
- GetSession()->HandleMoveWorldportAckOpcode();
-
- if (GetMap() != oldMap)
- return;
-
- TeleportTo(m_homebindMapId, m_homebindX, m_homebindY, m_homebindZ, GetOrientation());
-
- while (IsBeingTeleportedFar())
- GetSession()->HandleMoveWorldportAckOpcode();
-
- if (GetMap() == oldMap)
- {
- sLog->outCrash("Cannot teleport player out of map!");
- ResetMap();
- ASSERT(false);
- }
-}
-
bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options)
{
if (!MapManager::IsValidMapCoord(mapid, x, y, z, orientation))
@@ -5087,6 +5065,8 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
if (GetSession()->IsARecruiter() || (GetSession()->GetRecruiterId() != 0))
SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_REFER_A_FRIEND);
+ setDeathState(ALIVE);
+
SetMovement(MOVE_LAND_WALK);
SetMovement(MOVE_UNROOT);
@@ -5116,8 +5096,6 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
// update visibility
UpdateObjectVisibility();
- setDeathState(ALIVE);
-
if (!applySickness)
return;
@@ -13322,11 +13300,7 @@ void Player::UpdateSoulboundTradeItems()
// also checks for garbage data
for (ItemDurationList::iterator itr = m_itemSoulboundTradeable.begin(); itr != m_itemSoulboundTradeable.end();)
{
- if (!*itr)
- {
- m_itemSoulboundTradeable.erase(itr++);
- continue;
- }
+ ASSERT(*itr);
if ((*itr)->GetOwnerGUID() != GetGUID())
{
m_itemSoulboundTradeable.erase(itr++);
@@ -13341,16 +13315,10 @@ void Player::UpdateSoulboundTradeItems()
}
}
+//TODO: should never allow an item to be added to m_itemSoulboundTradeable twice
void Player::RemoveTradeableItem(Item* item)
{
- for (ItemDurationList::iterator itr = m_itemSoulboundTradeable.begin(); itr != m_itemSoulboundTradeable.end(); ++itr)
- {
- if ((*itr) == item)
- {
- m_itemSoulboundTradeable.erase(itr);
- break;
- }
- }
+ m_itemSoulboundTradeable.remove(item);
}
void Player::UpdateItemDuration(uint32 time, bool realtimeonly)
@@ -14855,10 +14823,10 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
for (uint8 i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
{
- if (quest->RequiredSourceItemid[i])
+ if (quest->RequiredSourceItemId[i])
{
- uint32 count = quest->RequiredSourceItemId[i];
- DestroyItemCount(quest->RequiredSourceItemid[i], count ? count : 9999, true);
+ uint32 count = quest->RequiredSourceItemCount[i];
+ DestroyItemCount(quest->RequiredSourceItemId[i], count ? count : 9999, true);
}
}
@@ -15052,12 +15020,12 @@ void Player::FailQuest(uint32 questId)
// Destroy quest items on quest failure.
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
if (quest->RequiredItemId[i] > 0 && quest->RequiredItemCount[i] > 0)
- // Destroy items recieved on starting the quest.
+ // Destroy items received on starting the quest.
DestroyItemCount(quest->RequiredItemId[i], quest->RequiredItemCount[i], true, true);
for (uint8 i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
- if (quest->RequiredSourceItemid[i] > 0 && quest->RequiredSourceItemId[i] > 0)
- // Destroy items recieved during the quest.
- DestroyItemCount(quest->RequiredSourceItemid[i], quest->RequiredSourceItemId[i], true, true);
+ if (quest->RequiredSourceItemId[i] > 0 && quest->RequiredSourceItemCount[i] > 0)
+ // Destroy items received during the quest.
+ DestroyItemCount(quest->RequiredSourceItemId[i], quest->RequiredSourceItemCount[i], true, true);
}
}
@@ -16108,7 +16076,7 @@ bool Player::HasQuestForItem(uint32 itemid) const
for (uint8 j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; ++j)
{
// examined item is a source item
- if (qinfo->RequiredSourceItemid[j] == itemid)
+ if (qinfo->RequiredSourceItemId[j] == itemid)
{
ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(itemid);
@@ -16117,9 +16085,9 @@ bool Player::HasQuestForItem(uint32 itemid) const
return true;
// allows custom amount drop when not 0
- if (qinfo->RequiredSourceItemId[j])
+ if (qinfo->RequiredSourceItemCount[j])
{
- if (GetItemCount(itemid, true) < qinfo->RequiredSourceItemId[j])
+ if (GetItemCount(itemid, true) < qinfo->RequiredSourceItemCount[j])
return true;
} else if (GetItemCount(itemid, true) < pProto->GetMaxStackSize())
return true;
@@ -18143,8 +18111,14 @@ bool Player::Satisfy(AccessRequirement const* ar, uint32 target_map, bool report
missingQuest = ar->quest_H;
uint32 missingAchievement = 0;
- if (ar->achievement && !GetAchievementMgr().HasAchieved(sAchievementStore.LookupEntry(ar->achievement)))
- missingAchievement = ar->achievement;
+ Player* leader = this;
+ uint64 leaderGuid = GetGroup() ? GetGroup()->GetLeaderGUID() : GetGUID();
+ if (leaderGuid != GetGUID())
+ leader = ObjectAccessor::FindPlayer(leaderGuid);
+
+ if (ar->achievement)
+ if (!leader || !leader->GetAchievementMgr().HasAchieved(ar->achievement))
+ missingAchievement = ar->achievement;
Difficulty target_difficulty = GetDifficulty(mapEntry->IsRaid());
MapDifficulty const* mapDiff = GetDownscaledMapDifficultyData(target_map, target_difficulty);
@@ -18300,7 +18274,7 @@ void Player::SaveToDB(bool create /*=false*/)
stmt->setFloat(index++, finiteAlways(GetPositionY()));
stmt->setFloat(index++, finiteAlways(GetPositionZ()));
stmt->setFloat(index++, finiteAlways(GetOrientation()));
-
+
std::ostringstream ss;
ss << m_taxi;
stmt->setString(index++, ss.str());
@@ -18322,7 +18296,7 @@ void Player::SaveToDB(bool create /*=false*/)
ss.str("");
ss << m_taxi.SaveTaxiDestinationsToString();
-
+
stmt->setString(index++, ss.str());
stmt->setUInt32(index++, GetArenaPoints());
stmt->setUInt32(index++, GetHonorPoints());
@@ -18919,7 +18893,7 @@ void Player::_SaveSkills(SQLTransaction& trans)
void Player::_SaveSpells(SQLTransaction& trans)
{
- for (PlayerSpellMap::iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end();)
+ for (PlayerSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end();)
{
if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->state == PLAYERSPELL_CHANGED)
trans->PAppend("DELETE FROM character_spell WHERE guid = '%u' and spell = '%u'", GetGUIDLow(), itr->first);
@@ -22478,12 +22452,9 @@ uint32 Player::GetBaseWeaponSkillValue (WeaponAttackType attType) const
void Player::ResurectUsingRequestData()
{
/// Teleport before resurrecting by player, otherwise the player might get attacked from creatures near his corpse
- if (IS_PLAYER_GUID(m_resurrectGUID))
- TeleportTo(m_resurrectMap, m_resurrectX, m_resurrectY, m_resurrectZ, GetOrientation());
+ TeleportTo(m_resurrectMap, m_resurrectX, m_resurrectY, m_resurrectZ, GetOrientation());
- //we cannot resurrect player when we triggered far teleport
- //player will be resurrected upon teleportation
- if (IsBeingTeleportedFar())
+ if (IsBeingTeleported())
{
ScheduleDelayedOperation(DELAYED_RESURRECT_PLAYER);
return;
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 651b99e7cb4..2b84a116ee8 100755
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1091,13 +1091,10 @@ class Player : public Unit, public GridObject<Player>
void RemoveFromWorld();
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0);
- void TeleportOutOfMap(Map* oldMap);
-
bool TeleportTo(WorldLocation const &loc, uint32 options = 0)
{
return TeleportTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetOrientation(), options);
}
-
bool TeleportToBGEntryPoint();
void SetSummonPoint(uint32 mapid, float x, float y, float z)
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 2e2f5591a5d..48b096e5a25 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -1478,9 +1478,13 @@ bool Unit::IsDamageReducedByArmor(SpellSchoolMask schoolMask, SpellInfo const* s
return false;
// bleeding effects are not reduced by armor
- if (effIndex != MAX_SPELL_EFFECTS && spellInfo->Effects[effIndex].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE)
- if (spellInfo->GetEffectMechanicMask(effIndex) & (1<<MECHANIC_BLEED))
- return false;
+ if (effIndex != MAX_SPELL_EFFECTS)
+ {
+ if (spellInfo->Effects[effIndex].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE ||
+ spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_SCHOOL_DAMAGE)
+ if (spellInfo->GetEffectMechanicMask(effIndex) & (1<<MECHANIC_BLEED))
+ return false;
+ }
}
return true;
}
@@ -1922,12 +1926,7 @@ void Unit::AttackerStateUpdate (Unit* victim, WeaponAttackType attType, bool ext
CombatStart(victim);
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MELEE_ATTACK);
- uint32 hitInfo;
- if (attType == BASE_ATTACK)
- hitInfo = HITINFO_NORMALSWING2;
- else if (attType == OFF_ATTACK)
- hitInfo = HITINFO_LEFTSWING;
- else
+ if (attType != BASE_ATTACK && attType != OFF_ATTACK)
return; // ignore ranged case
// melee attack spell casted at main hand attack only - no normal melee dmg dealt
@@ -5470,7 +5469,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
case CLASS_DRUID:
RandomSpells.push_back(71484);
RandomSpells.push_back(71485);
- RandomSpells.push_back(71486);
+ RandomSpells.push_back(71492);
break;
case CLASS_HUNTER:
RandomSpells.push_back(71486);
@@ -5516,7 +5515,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
case CLASS_DRUID:
RandomSpells.push_back(71561);
RandomSpells.push_back(71556);
- RandomSpells.push_back(71558);
+ RandomSpells.push_back(71560);
break;
case CLASS_HUNTER:
RandomSpells.push_back(71558);
@@ -6054,6 +6053,16 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
triggered_spell_id = 37378;
break;
}
+ // Glyph of Succubus
+ case 56250:
+ {
+ if (!target)
+ return false;
+ target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE, 0, target->GetAura(32409)); // SW:D shall not be removed.
+ target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT);
+ target->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH);
+ return true;
+ }
}
break;
}
@@ -6482,6 +6491,16 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
triggered_spell_id = 32747;
break;
}
+ case 57934: // Tricks of the Trade
+ {
+ Unit* redirectTarget = GetMisdirectionTarget();
+ RemoveAura(57934);
+ if (!redirectTarget)
+ break;
+ redirectTarget->CastSpell(this,59628,true);
+ CastSpell(redirectTarget,57933,true);
+ break;
+ }
}
switch (dummySpell->SpellIconID)
@@ -8900,6 +8919,20 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
}
break;
}
+ case 46916: // Slam! (Bloodsurge proc)
+ case 52437: // Sudden Death
+ {
+ // Item - Warrior T10 Melee 4P Bonus
+ if (AuraEffect const* aurEff = GetAuraEffect(70847, 0))
+ {
+ if (!roll_chance_i(aurEff->GetAmount()))
+ break;
+ CastSpell(this, 70849, true, castItem, triggeredByAura); // Extra Charge!
+ CastSpell(this, 71072, true, castItem, triggeredByAura); // Slam GCD Reduced
+ CastSpell(this, 71069, true, castItem, triggeredByAura); // Execute GCD Reduced
+ }
+ break;
+ }
// Sword and Board
case 50227:
{
@@ -15573,29 +15606,17 @@ void Unit::Kill(Unit* victim, bool durabilityLoss)
}
// Hook for OnPVPKill Event
- if (GetTypeId() == TYPEID_PLAYER)
+ if (Player* killerPlr = ToPlayer())
{
- if (victim->GetTypeId() == TYPEID_PLAYER)
- {
- Player* killer = ToPlayer();
- Player* killed = victim->ToPlayer();
- sScriptMgr->OnPVPKill(killer, killed);
- }
- else if (victim->GetTypeId() == TYPEID_UNIT)
- {
- Player* killer = ToPlayer();
- Creature* killed = victim->ToCreature();
- sScriptMgr->OnCreatureKill(killer, killed);
- }
+ if (Player* killedPlr = victim->ToPlayer())
+ sScriptMgr->OnPVPKill(killerPlr, killedPlr);
+ else if (Creature* killedCre = victim->ToCreature())
+ sScriptMgr->OnCreatureKill(killerPlr, killedCre);
}
- else if (GetTypeId() == TYPEID_UNIT)
+ else if (Creature* killerCre = ToCreature())
{
- if (victim->GetTypeId() == TYPEID_PLAYER)
- {
- Creature* killer = ToCreature();
- Player* killed = victim->ToPlayer();
- sScriptMgr->OnPlayerKilledByCreature(killer, killed);
- }
+ if (Player* killed = victim->ToPlayer())
+ sScriptMgr->OnPlayerKilledByCreature(killerCre, killed);
}
if (victim->GetVehicle())
diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp
index fe018ec78ce..d3c3268e9ce 100755
--- a/src/server/game/Entities/Vehicle/Vehicle.cpp
+++ b/src/server/game/Entities/Vehicle/Vehicle.cpp
@@ -341,7 +341,7 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
}
}
- if (seat->second.SeatInfo->m_flags && !(seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_UNK11))
+ if (seat->second.SeatInfo->m_flags && !(seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_UNK1))
unit->AddUnitState(UNIT_STAT_ONVEHICLE);
unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp
index d3cc27c9e6c..5cb130b93e4 100755
--- a/src/server/game/Events/GameEventMgr.cpp
+++ b/src/server/game/Events/GameEventMgr.cpp
@@ -27,6 +27,8 @@
#include "GossipDef.h"
#include "Player.h"
#include "BattlegroundMgr.h"
+#include "UnitAI.h"
+#include "GameObjectAI.h"
bool GameEventMgr::CheckOneGameEvent(uint16 entry) const
{
@@ -1059,6 +1061,8 @@ uint32 GameEventMgr::Update() // return the next e
void GameEventMgr::UnApplyEvent(uint16 event_id)
{
sLog->outDetail("GameEvent %u \"%s\" removed.", event_id, mGameEvent[event_id].description.c_str());
+ //! Run SAI scripts with SMART_EVENT_GAME_EVENT_END
+ RunSmartAIScripts(event_id, false);
// un-spawn positive event tagged objects
GameEventUnspawn(event_id);
// spawn negative event tagget objects
@@ -1090,6 +1094,9 @@ void GameEventMgr::ApplyNewEvent(uint16 event_id)
sLog->outDetail("GameEvent %u \"%s\" started.", event_id, mGameEvent[event_id].description.c_str());
+ //! Run SAI scripts with SMART_EVENT_GAME_EVENT_END
+ RunSmartAIScripts(event_id, true);
+
// spawn positive event tagget objects
GameEventSpawn(event_id);
// un-spawn negative event tagged objects
@@ -1601,6 +1608,26 @@ void GameEventMgr::SendWorldStateUpdate(Player* player, uint16 event_id)
}
}
+void GameEventMgr::RunSmartAIScripts(uint16 event_id, bool activate)
+{
+ //! Iterate over every supported source type (creature and gameobject)
+ //! Not entirely sure how this will affect units in non-loaded grids.
+ {
+ TRINITY_READ_GUARD(HashMapHolder<Creature>::LockType, *HashMapHolder<Creature>::GetLock());
+ HashMapHolder<Creature>::MapType const& m = ObjectAccessor::GetCreatures();
+ for (HashMapHolder<Creature>::MapType::const_iterator iter = m.begin(); iter != m.end(); ++iter)
+ if (iter->second->IsInWorld())
+ iter->second->AI()->sOnGameEvent(activate, event_id);
+ }
+ {
+ TRINITY_READ_GUARD(HashMapHolder<GameObject>::LockType, *HashMapHolder<GameObject>::GetLock());
+ HashMapHolder<GameObject>::MapType const& m = ObjectAccessor::GetGameObjects();
+ for (HashMapHolder<GameObject>::MapType::const_iterator iter = m.begin(); iter != m.end(); ++iter)
+ if (iter->second->IsInWorld())
+ iter->second->AI()->OnGameEvent(activate, event_id);
+ }
+}
+
bool IsHolidayActive(HolidayIds id)
{
if (id == HOLIDAY_NONE)
diff --git a/src/server/game/Events/GameEventMgr.h b/src/server/game/Events/GameEventMgr.h
index a2a35a85098..bba92b4d24c 100755
--- a/src/server/game/Events/GameEventMgr.h
+++ b/src/server/game/Events/GameEventMgr.h
@@ -132,6 +132,7 @@ class GameEventMgr
void UpdateEventNPCFlags(uint16 event_id);
void UpdateEventNPCVendor(uint16 event_id, bool activate);
void UpdateBattlegroundSettings();
+ void RunSmartAIScripts(uint16 event_id, bool activate); //! Runs SMART_EVENT_GAME_EVENT_START/_END SAI
bool CheckOneGameEventConditions(uint16 event_id);
void SaveWorldEventStateToDB(uint16 event_id);
bool hasCreatureQuestActiveEventExcept(uint32 quest_id, uint16 event_id);
diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp
index 82532e6ae29..8b545548946 100755
--- a/src/server/game/Globals/ObjectAccessor.cpp
+++ b/src/server/game/Globals/ObjectAccessor.cpp
@@ -225,9 +225,7 @@ void ObjectAccessor::RemoveCorpse(Corpse* corpse)
// build mapid*cellid -> guid_set map
CellCoord cellCoord = Trinity::ComputeCellCoord(corpse->GetPositionX(), corpse->GetPositionY());
- uint32 cell_id = (cellCoord.y_coord * TOTAL_NUMBER_OF_CELLS_PER_MAP) + cellCoord.x_coord;
-
- sObjectMgr->DeleteCorpseCellData(corpse->GetMapId(), cell_id, GUID_LOPART(corpse->GetOwnerGUID()));
+ sObjectMgr->DeleteCorpseCellData(corpse->GetMapId(), cellCoord.GetId(), GUID_LOPART(corpse->GetOwnerGUID()));
i_player2corpse.erase(iter);
}
@@ -246,9 +244,7 @@ void ObjectAccessor::AddCorpse(Corpse* corpse)
// build mapid*cellid -> guid_set map
CellCoord cellCoord = Trinity::ComputeCellCoord(corpse->GetPositionX(), corpse->GetPositionY());
- uint32 cell_id = (cellCoord.y_coord * TOTAL_NUMBER_OF_CELLS_PER_MAP) + cellCoord.x_coord;
-
- sObjectMgr->AddCorpseCellData(corpse->GetMapId(), cell_id, GUID_LOPART(corpse->GetOwnerGUID()), corpse->GetInstanceId());
+ sObjectMgr->AddCorpseCellData(corpse->GetMapId(), cellCoord.GetId(), GUID_LOPART(corpse->GetOwnerGUID()), corpse->GetInstanceId());
}
}
diff --git a/src/server/game/Globals/ObjectAccessor.h b/src/server/game/Globals/ObjectAccessor.h
index 25fa20dce70..92c947eb86f 100755
--- a/src/server/game/Globals/ObjectAccessor.h
+++ b/src/server/game/Globals/ObjectAccessor.h
@@ -201,16 +201,16 @@ class ObjectAccessor
}
// when using this, you must use the hashmapholder's lock
- //HashMapHolder<Creature>::MapType& GetCreatures()
- //{
- // return HashMapHolder<Creature>::GetContainer();
- //}
-
- //// when using this, you must use the hashmapholder's lock
- //HashMapHolder<GameObject>::MapType& GetGameObjects()
- //{
- // return HashMapHolder<GameObject>::GetContainer();
- //}
+ static HashMapHolder<Creature>::MapType const& GetCreatures()
+ {
+ return HashMapHolder<Creature>::GetContainer();
+ }
+
+ // when using this, you must use the hashmapholder's lock
+ static HashMapHolder<GameObject>::MapType const& GetGameObjects()
+ {
+ return HashMapHolder<GameObject>::GetContainer();
+ }
template<class T> static void AddObject(T* object)
{
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 6201a932a60..020f7bd56a9 100755
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -535,7 +535,7 @@ void ObjectMgr::LoadCreatureTemplateAddons()
if (!result)
{
- sLog->outString(">> Loaded 0 creature template addon definitions. DB table `creature_addon` is empty.");
+ sLog->outString(">> Loaded 0 creature template addon definitions. DB table `creature_template_addon` is empty.");
sLog->outString();
return;
}
@@ -569,7 +569,7 @@ void ObjectMgr::LoadCreatureTemplateAddons()
SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(uint32(atol(*itr)));
if (!AdditionalSpellInfo)
{
- sLog->outErrorDb("Creature (GUID: %u) has wrong spell %u defined in `auras` field in `creature_addon`.", entry, uint32(atol(*itr)));
+ sLog->outErrorDb("Creature (Entry: %u) has wrong spell %u defined in `auras` field in `creature_template_addon`.", entry, uint32(atol(*itr)));
continue;
}
creatureAddon.auras[i++] = uint32(atol(*itr));
@@ -579,13 +579,13 @@ void ObjectMgr::LoadCreatureTemplateAddons()
{
if (!sCreatureDisplayInfoStore.LookupEntry(creatureAddon.mount))
{
- sLog->outErrorDb("Creature (GUID: %u) has invalid displayInfoId (%u) for mount defined in `creature_addon`", entry, creatureAddon.mount);
+ sLog->outErrorDb("Creature (Entry: %u) has invalid displayInfoId (%u) for mount defined in `creature_template_addon`", entry, creatureAddon.mount);
creatureAddon.mount = 0;
}
}
if (!sEmotesStore.LookupEntry(creatureAddon.emote))
- sLog->outErrorDb("Creature (GUID: %u) has invalid emote (%u) defined in `creature_addon`.", entry, creatureAddon.emote);
+ sLog->outErrorDb("Creature (Entry: %u) has invalid emote (%u) defined in `creature_template_addon`.", entry, creatureAddon.emote);
++count;
}
@@ -1569,9 +1569,7 @@ void ObjectMgr::AddCreatureToGrid(uint32 guid, CreatureData const* data)
if (mask & 1)
{
CellCoord cellCoord = Trinity::ComputeCellCoord(data->posX, data->posY);
- uint32 cell_id = (cellCoord.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cellCoord.x_coord;
-
- CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(data->mapid, i)][cell_id];
+ CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(data->mapid, i)][cellCoord.GetId()];
cell_guids.creatures.insert(guid);
}
}
@@ -1585,9 +1583,7 @@ void ObjectMgr::RemoveCreatureFromGrid(uint32 guid, CreatureData const* data)
if (mask & 1)
{
CellCoord cellCoord = Trinity::ComputeCellCoord(data->posX, data->posY);
- uint32 cell_id = (cellCoord.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cellCoord.x_coord;
-
- CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(data->mapid, i)][cell_id];
+ CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(data->mapid, i)][cellCoord.GetId()];
cell_guids.creatures.erase(guid);
}
}
@@ -1878,9 +1874,7 @@ void ObjectMgr::AddGameobjectToGrid(uint32 guid, GameObjectData const* data)
if (mask & 1)
{
CellCoord cellCoord = Trinity::ComputeCellCoord(data->posX, data->posY);
- uint32 cell_id = (cellCoord.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cellCoord.x_coord;
-
- CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(data->mapid, i)][cell_id];
+ CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(data->mapid, i)][cellCoord.GetId()];
cell_guids.gameobjects.insert(guid);
}
}
@@ -1894,9 +1888,7 @@ void ObjectMgr::RemoveGameobjectFromGrid(uint32 guid, GameObjectData const* data
if (mask & 1)
{
CellCoord cellCoord = Trinity::ComputeCellCoord(data->posX, data->posY);
- uint32 cell_id = (cellCoord.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cellCoord.x_coord;
-
- CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(data->mapid, i)][cell_id];
+ CellObjectGuids& cell_guids = mMapObjectGuids[MAKE_PAIR32(data->mapid, i)][cellCoord.GetId()];
cell_guids.gameobjects.erase(guid);
}
}
@@ -3826,11 +3818,11 @@ void ObjectMgr::LoadQuests()
// no changes, quest not dependent from this value but can have problems at client (note some may be 0, we must allow this so no check)
}
//check for proper RequiredSkillId value (skill case)
- if (int32 skill_id = SkillByQuestSort(-int32(qinfo->ZoneOrSort)))
+ if (uint32 skill_id = SkillByQuestSort(-int32(qinfo->ZoneOrSort)))
{
if (qinfo->RequiredSkillId != skill_id)
{
- sLog->outErrorDb("Quest %u has `ZoneOrSort` = %i but `RequiredSkillId` does not have a corresponding value (%i).",
+ sLog->outErrorDb("Quest %u has `ZoneOrSort` = %i but `RequiredSkillId` does not have a corresponding value (%d).",
qinfo->GetQuestId(), qinfo->ZoneOrSort, skill_id);
//override, and force proper value here?
}
@@ -4024,22 +4016,22 @@ void ObjectMgr::LoadQuests()
for (uint8 j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; ++j)
{
- uint32 id = qinfo->RequiredSourceItemid[j];
+ uint32 id = qinfo->RequiredSourceItemId[j];
if (id)
{
if (!sObjectMgr->GetItemTemplate(id))
{
- sLog->outErrorDb("Quest %u has `RequiredSourceItemid%d` = %u but item with entry %u does not exist, quest can't be done.",
+ sLog->outErrorDb("Quest %u has `RequiredSourceItemId%d` = %u but item with entry %u does not exist, quest can't be done.",
qinfo->GetQuestId(), j+1, id, id);
// no changes, quest can't be done for this requirement
}
}
else
{
- if (qinfo->RequiredSourceItemId[j]>0)
+ if (qinfo->RequiredSourceItemCount[j]>0)
{
- sLog->outErrorDb("Quest %u has `RequiredSourceItemid%d` = 0 but `RequiredSourceItemId%d` = %u.",
- qinfo->GetQuestId(), j+1, j+1, qinfo->RequiredSourceItemId[j]);
+ sLog->outErrorDb("Quest %u has `RequiredSourceItemId%d` = 0 but `RequiredSourceItemCount%d` = %u.",
+ qinfo->GetQuestId(), j+1, j+1, qinfo->RequiredSourceItemCount[j]);
// no changes, quest ignore this data
}
}
@@ -8048,8 +8040,11 @@ bool ObjectMgr::AddGameTele(GameTele& tele)
m_GameTeleMap[new_id] = tele;
+ std::string safeName(tele.name);
+ WorldDatabase.EscapeString(safeName);
+
WorldDatabase.PExecute("INSERT INTO game_tele (id, position_x, position_y, position_z, orientation, map, name) VALUES (%u, %f, %f, %f, %f, %d, '%s')",
- new_id, tele.position_x, tele.position_y, tele.position_z, tele.orientation, tele.mapId, tele.name.c_str());
+ new_id, tele.position_x, tele.position_y, tele.position_z, tele.orientation, tele.mapId, safeName.c_str());
return true;
}
diff --git a/src/server/game/Grids/GridDefines.h b/src/server/game/Grids/GridDefines.h
index 44e2588ef81..a9c0bf88769 100644
--- a/src/server/game/Grids/GridDefines.h
+++ b/src/server/game/Grids/GridDefines.h
@@ -135,6 +135,11 @@ struct CoordPair
return *this;
}
+ uint32 GetId() const
+ {
+ return y_coord * LIMIT + x_coord;
+ }
+
uint32 x_coord;
uint32 y_coord;
};
diff --git a/src/server/game/Grids/ObjectGridLoader.cpp b/src/server/game/Grids/ObjectGridLoader.cpp
index 56c6410e6d7..cc5e3f5158a 100755
--- a/src/server/game/Grids/ObjectGridLoader.cpp
+++ b/src/server/game/Grids/ObjectGridLoader.cpp
@@ -44,6 +44,7 @@ void ObjectGridEvacuator::Visit(CreatureMapType &m)
}
// for loading world object at grid loading (Corpses)
+//TODO: to implement npc on transport, also need to load npcs at grid loading
class ObjectWorldLoader
{
public:
@@ -138,38 +139,23 @@ void LoadHelper(CellCorpseSet const& cell_corpses, CellCoord &cell, CorpseMapTyp
void ObjectGridLoader::Visit(GameObjectMapType &m)
{
- uint32 x = (i_cell.GridX()*MAX_NUMBER_OF_CELLS) + i_cell.CellX();
- uint32 y = (i_cell.GridY()*MAX_NUMBER_OF_CELLS) + i_cell.CellY();
- CellCoord cellCoord(x, y);
- uint32 cell_id = (cellCoord.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cellCoord.x_coord;
-
- CellObjectGuids const& cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cell_id);
-
+ CellCoord cellCoord = i_cell.GetCellCoord();
+ CellObjectGuids const& cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cellCoord.GetId());
LoadHelper(cell_guids.gameobjects, cellCoord, m, i_gameObjects, i_map);
}
-void
-ObjectGridLoader::Visit(CreatureMapType &m)
+void ObjectGridLoader::Visit(CreatureMapType &m)
{
- uint32 x = (i_cell.GridX()*MAX_NUMBER_OF_CELLS) + i_cell.CellX();
- uint32 y = (i_cell.GridY()*MAX_NUMBER_OF_CELLS) + i_cell.CellY();
- CellCoord cellCoord(x, y);
- uint32 cell_id = (cellCoord.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cellCoord.x_coord;
-
- CellObjectGuids const& cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cell_id);
-
+ CellCoord cellCoord = i_cell.GetCellCoord();
+ CellObjectGuids const& cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cellCoord.GetId());
LoadHelper(cell_guids.creatures, cellCoord, m, i_creatures, i_map);
}
void ObjectWorldLoader::Visit(CorpseMapType &m)
{
- uint32 x = (i_cell.GridX()*MAX_NUMBER_OF_CELLS) + i_cell.CellX();
- uint32 y = (i_cell.GridY()*MAX_NUMBER_OF_CELLS) + i_cell.CellY();
- CellCoord cellCoord(x, y);
- uint32 cell_id = (cellCoord.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cellCoord.x_coord;
-
+ CellCoord cellCoord = i_cell.GetCellCoord();
// corpses are always added to spawn mode 0 and they are spawned by their instance id
- CellObjectGuids const& cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), 0, cell_id);
+ CellObjectGuids const& cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), 0, cellCoord.GetId());
LoadHelper(cell_guids.corpses, cellCoord, m, i_corpses, i_map);
}
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 6311066f597..11175b13114 100755
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -1121,6 +1121,7 @@ void Group::CountTheRoll(Rolls::iterator rollI, uint32 NumberOfPlayers)
roll->getLoot()->unlootedCount--;
ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(roll->itemid);
player->AutoStoreLoot(pProto->DisenchantID, LootTemplates_Disenchant, true);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, 13262); // Disenchant
}
}
}
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index 59c107bd40f..94fcbbdda25 100755
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -1993,6 +1993,7 @@ bool Guild::Validate()
}
}
}
+
if (broken_ranks)
{
m_ranks.clear();
diff --git a/src/server/game/Mails/Mail.cpp b/src/server/game/Mails/Mail.cpp
index 6d54aacb311..e5de3e35956 100755
--- a/src/server/game/Mails/Mail.cpp
+++ b/src/server/game/Mails/Mail.cpp
@@ -171,6 +171,7 @@ void MailDraft::SendReturnToSender(uint32 sender_acc, uint32 sender_guid, uint32
void MailDraft::SendMailTo(SQLTransaction& trans, MailReceiver const& receiver, MailSender const& sender, MailCheckMask checked, uint32 deliver_delay)
{
Player* pReceiver = receiver.GetPlayer(); // can be NULL
+ Player* pSender = sObjectMgr->GetPlayerByLowGUID(sender.GetSenderId());
if (pReceiver)
prepareItems(pReceiver, trans); // generate mail template items
@@ -188,9 +189,12 @@ void MailDraft::SendMailTo(SQLTransaction& trans, MailReceiver const& receiver,
// mail from battlemaster (rewardmarks) should last only one day
else if (sender.GetMailMessageType() == MAIL_CREATURE && sBattlegroundMgr->GetBattleMasterBG(sender.GetSenderId()) != BATTLEGROUND_TYPE_NONE)
expire_delay = DAY;
- // default case: expire time if COD 3 days, if no COD 30 days
+ // default case: expire time if COD 3 days, if no COD 30 days (or 90 days if sender is a game master)
else
- expire_delay = (m_COD > 0) ? 3 * DAY : 30 * DAY;
+ if (m_COD)
+ expire_delay = 3 * DAY;
+ else
+ expire_delay = pSender && pSender->isGameMaster() ? 90 * DAY : 30 * DAY;
time_t expire_time = deliver_time + expire_delay;
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 13a47633b53..04a5b102a6d 100755
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -685,8 +685,7 @@ void Map::RemoveFromMap(T *obj, bool remove)
}
}
-void
-Map::PlayerRelocation(Player* player, float x, float y, float z, float orientation)
+void Map::PlayerRelocation(Player* player, float x, float y, float z, float orientation)
{
ASSERT(player);
@@ -710,8 +709,7 @@ Map::PlayerRelocation(Player* player, float x, float y, float z, float orientati
player->UpdateObjectVisibility(false);
}
-void
-Map::CreatureRelocation(Creature* creature, float x, float y, float z, float ang, bool respawnRelocationOnFail)
+void Map::CreatureRelocation(Creature* creature, float x, float y, float z, float ang, bool respawnRelocationOnFail)
{
ASSERT(CheckGridIntegrity(creature, false));
@@ -1161,7 +1159,7 @@ bool GridMap::loadHeihgtData(FILE* in, uint32 offset, uint32 /*size*/)
return true;
}
-bool GridMap::loadLiquidData(FILE* in, uint32 offset, uint32 /*size*/)
+bool GridMap::loadLiquidData(FILE* in, uint32 offset, uint32 /*size*/)
{
map_liquidHeader header;
fseek(in, offset, SEEK_SET);
@@ -1203,12 +1201,12 @@ uint16 GridMap::getArea(float x, float y)
return m_area_map[lx*16 + ly];
}
-float GridMap::getHeightFromFlat(float /*x*/, float /*y*/) const
+float GridMap::getHeightFromFlat(float /*x*/, float /*y*/) const
{
return m_gridHeight;
}
-float GridMap::getHeightFromFloat(float x, float y) const
+float GridMap::getHeightFromFloat(float x, float y) const
{
if (!m_V8 || !m_V9)
return m_gridHeight;
@@ -1290,7 +1288,7 @@ float GridMap::getHeightFromFloat(float x, float y) const
return a * x + b * y + c;
}
-float GridMap::getHeightFromUint8(float x, float y) const
+float GridMap::getHeightFromUint8(float x, float y) const
{
if (!m_uint8_V8 || !m_uint8_V9)
return m_gridHeight;
@@ -1357,7 +1355,7 @@ float GridMap::getHeightFromUint8(float x, float y) const
return (float)((a * x) + (b * y) + c)*m_gridIntHeightMultiplier + m_gridHeight;
}
-float GridMap::getHeightFromUint16(float x, float y) const
+float GridMap::getHeightFromUint16(float x, float y) const
{
if (!m_uint16_V8 || !m_uint16_V9)
return m_gridHeight;
@@ -1424,7 +1422,7 @@ float GridMap::getHeightFromUint16(float x, float y) const
return (float)((a * x) + (b * y) + c)*m_gridIntHeightMultiplier + m_gridHeight;
}
-float GridMap::getLiquidLevel(float x, float y)
+float GridMap::getLiquidLevel(float x, float y)
{
if (!m_liquid_map)
return m_liquidLevel;
@@ -1443,7 +1441,7 @@ float GridMap::getLiquidLevel(float x, float y)
return m_liquid_map[cx_int*m_liquid_width + cy_int];
}
-uint8 GridMap::getTerrainType(float x, float y)
+uint8 GridMap::getTerrainType(float x, float y)
{
if (!m_liquid_type)
return 0;
@@ -1530,41 +1528,28 @@ inline GridMap* Map::GetGrid(float x, float y)
return GridMaps[gx][gy];
}
-float Map::GetHeight(float x, float y, float z, bool pUseVmaps, float maxSearchDist) const
+float Map::GetHeight(float x, float y, float z, bool checkVMap /*= true*/, float maxSearchDist /*= DEFAULT_HEIGHT_SEARCH*/) const
{
// find raw .map surface under Z coordinates
- float mapHeight;
+ float mapHeight = VMAP_INVALID_HEIGHT_VALUE;
if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y))
{
- float _mapheight = gmap->getHeight(x, y);
-
+ float gridHeight = gmap->getHeight(x, y);
// look from a bit higher pos to find the floor, ignore under surface case
- if (z + 2.0f > _mapheight)
- mapHeight = _mapheight;
- else
- mapHeight = VMAP_INVALID_HEIGHT_VALUE;
+ if (z + 2.0f > gridHeight)
+ mapHeight = gridHeight;
}
- else
- mapHeight = VMAP_INVALID_HEIGHT_VALUE;
- float vmapHeight;
- if (pUseVmaps)
+ float vmapHeight = VMAP_INVALID_HEIGHT_VALUE;
+ if (checkVMap)
{
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
if (vmgr->isHeightCalcEnabled())
- {
- // look from a bit higher pos to find the floor
- vmapHeight = vmgr->getHeight(GetId(), x, y, z + 2.0f, maxSearchDist);
- }
- else
- vmapHeight = VMAP_INVALID_HEIGHT_VALUE;
+ vmapHeight = vmgr->getHeight(GetId(), x, y, z + 2.0f, maxSearchDist); // look from a bit higher pos to find the floor
}
- else
- vmapHeight = VMAP_INVALID_HEIGHT_VALUE;
// mapHeight set for any above raw ground Z or <= INVALID_HEIGHT
// vmapheight set for any under Z value or <= INVALID_HEIGHT
-
if (vmapHeight > INVALID_HEIGHT)
{
if (mapHeight > INVALID_HEIGHT)
@@ -1581,15 +1566,8 @@ float Map::GetHeight(float x, float y, float z, bool pUseVmaps, float maxSearchD
else
return vmapHeight; // we have only vmapHeight (if have)
}
- else
- {
- if (!pUseVmaps)
- return mapHeight; // explicitly use map data (if have)
- else if (mapHeight > INVALID_HEIGHT && (z < mapHeight + 2 || z == MAX_HEIGHT))
- return mapHeight; // explicitly use map data if original z < mapHeight but map found (z+2 > mapHeight)
- else
- return VMAP_INVALID_HEIGHT_VALUE; // we not have any height
- }
+
+ return mapHeight; // explicitly use map data
}
inline bool IsOutdoorWMO(uint32 mogpFlags, int32 /*adtId*/, int32 /*rootId*/, int32 /*groupId*/, WMOAreaTableEntry const* wmoEntry, AreaTableEntry const* atEntry)
@@ -1826,7 +1804,7 @@ bool Map::CheckGridIntegrity(Creature* c, bool moved) const
return true;
}
-const char* Map::GetMapName() const
+char const* Map::GetMapName() const
{
return i_mapEntry ? i_mapEntry->name[sWorld->GetDefaultDbcLocale()] : "UNNAMEDMAP\x0";
}
@@ -2623,20 +2601,17 @@ void BattlegroundMap::RemoveAllPlayers()
player->TeleportTo(player->GetBattlegroundEntryPoint());
}
-Creature*
-Map::GetCreature(uint64 guid)
+Creature* Map::GetCreature(uint64 guid)
{
return ObjectAccessor::GetObjectInMap(guid, this, (Creature*)NULL);
}
-GameObject*
-Map::GetGameObject(uint64 guid)
+GameObject* Map::GetGameObject(uint64 guid)
{
return ObjectAccessor::GetObjectInMap(guid, this, (GameObject*)NULL);
}
-DynamicObject*
-Map::GetDynamicObject(uint64 guid)
+DynamicObject* Map::GetDynamicObject(uint64 guid)
{
return ObjectAccessor::GetObjectInMap(guid, this, (DynamicObject*)NULL);
}
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 5b652a2524a..8c4703a9f3a 100755
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -296,7 +296,7 @@ class Map : public GridRefManager<NGridType>
// some calls like isInWater should not use vmaps due to processor power
// can return INVALID_HEIGHT if under z+2 z coord not found height
- float GetHeight(float x, float y, float z, bool pCheckVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const;
+ float GetHeight(float x, float y, float z, bool checkVMap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const;
ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = 0) const;
diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h
index ffdf0131143..a6ff663b302 100755
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -42,8 +42,8 @@ enum TrinityStrings
LANG_GMS_ON_SRV = 16,
LANG_GMS_NOT_LOGGED = 17,
LANG_YOU_IN_FLIGHT = 18,
- //LANG_YOU_IN_BATTLEGROUND = 19, not used
- //LANG_TARGET_IN_FLIGHT = 20, not used
+ LANG_UPDATE_DIFF = 19,
+ LANG_SHUTDOWN_TIMELEFT = 20,
LANG_CHAR_IN_FLIGHT = 21,
LANG_CHAR_NON_MOUNTED = 22,
LANG_YOU_IN_COMBAT = 23,
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index a99d0f37c02..952df731c19 100755
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -312,13 +312,13 @@ enum SpellAttr1
SPELL_ATTR1_MELEE_COMBAT_START = 0x00000200, // 9 player starts melee combat after this spell is cast
SPELL_ATTR1_NO_THREAT = 0x00000400, // 10 no generates threat on cast 100% (old NO_INITIAL_AGGRO)
SPELL_ATTR1_UNK11 = 0x00000800, // 11 aura
- SPELL_ATTR1_UNK12 = 0x00001000, // 12
+ SPELL_ATTR1_UNK12 = 0x00001000, // 12 pickpoket
SPELL_ATTR1_FARSIGHT = 0x00002000, // 13 Client removes farsight on aura loss
SPELL_ATTR1_CHANNEL_TRACK_TARGET = 0x00004000, // 14 Client automatically forces player to face target when channeling
SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY = 0x00008000, // 15 remove auras on immunity
SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE = 0x00010000, // 16 on immuniy
SPELL_ATTR1_UNAUTOCASTABLE_BY_PET = 0x00020000, // 17
- SPELL_ATTR1_UNK18 = 0x00040000, // 18
+ SPELL_ATTR1_UNK18 = 0x00040000, // 18 stun, polymorph, daze, hex
SPELL_ATTR1_CANT_TARGET_SELF = 0x00080000, // 19
SPELL_ATTR1_REQ_COMBO_POINTS1 = 0x00100000, // 20 Req combo points on target
SPELL_ATTR1_UNK21 = 0x00200000, // 21
@@ -327,17 +327,17 @@ enum SpellAttr1
SPELL_ATTR1_UNK24 = 0x01000000, // 24 only fishing spells
SPELL_ATTR1_UNK25 = 0x02000000, // 25
SPELL_ATTR1_UNK26 = 0x04000000, // 26 works correctly with [target=focus] and [target=mouseover] macros?
- SPELL_ATTR1_UNK27 = 0x08000000, // 27
+ SPELL_ATTR1_UNK27 = 0x08000000, // 27 melee spell?
SPELL_ATTR1_DONT_DISPLAY_IN_AURA_BAR = 0x10000000, // 28 client doesn't display these spells in aura bar
SPELL_ATTR1_CHANNEL_DISPLAY_SPELL_NAME = 0x20000000, // 29 spell name is displayed in cast bar instead of 'channeling' text
- SPELL_ATTR1_ENABLE_AT_DODGE = 0x40000000, // 30 Overpower, Wolverine Bite
+ SPELL_ATTR1_ENABLE_AT_DODGE = 0x40000000, // 30 Overpower
SPELL_ATTR1_UNK31 = 0x80000000 // 31
};
enum SpellAttr2
{
SPELL_ATTR2_CAN_TARGET_DEAD = 0x00000001, // 0 can target dead unit or corpse
- SPELL_ATTR2_UNK1 = 0x00000002, // 1 ? many triggered spells have this flag
+ SPELL_ATTR2_UNK1 = 0x00000002, // 1 vanish, shadowform, Ghost Wolf and other
SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS = 0x00000004, // 2 26368 4.0.1 dbc change
SPELL_ATTR2_UNK3 = 0x00000008, // 3
SPELL_ATTR2_DISPLAY_IN_STANCE_BAR = 0x00000010, // 4 client displays icon in stance bar when learned, even if not shapeshift
@@ -346,9 +346,9 @@ enum SpellAttr2
SPELL_ATTR2_UNK7 = 0x00000080, // 7
SPELL_ATTR2_UNK8 = 0x00000100, // 8 not set in 3.0.3
SPELL_ATTR2_UNK9 = 0x00000200, // 9
- SPELL_ATTR2_UNK10 = 0x00000400, // 10
+ SPELL_ATTR2_UNK10 = 0x00000400, // 10 related to tame
SPELL_ATTR2_HEALTH_FUNNEL = 0x00000800, // 11
- SPELL_ATTR2_UNK12 = 0x00001000, // 12
+ SPELL_ATTR2_UNK12 = 0x00001000, // 12 Cleave, Heart Strike, Maul, Sunder Armor, Swipe
SPELL_ATTR2_UNK13 = 0x00002000, // 13 Items enchanted by spells with this flag preserve the enchant to arenas
SPELL_ATTR2_UNK14 = 0x00004000, // 14
SPELL_ATTR2_UNK15 = 0x00008000, // 15 not set in 3.0.3
@@ -358,13 +358,13 @@ enum SpellAttr2
SPELL_ATTR2_NOT_NEED_SHAPESHIFT = 0x00080000, // 19 does not necessarly need shapeshift
SPELL_ATTR2_UNK20 = 0x00100000, // 20
SPELL_ATTR2_DAMAGE_REDUCED_SHIELD = 0x00200000, // 21 for ice blocks, pala immunity buffs, priest absorb shields, but used also for other spells -> not sure!
- SPELL_ATTR2_UNK22 = 0x00400000, // 22
+ SPELL_ATTR2_UNK22 = 0x00400000, // 22 Ambush, Backstab, Cheap Shot, Death Grip, Garrote, Judgements, Mutilate, Pounce, Ravage, Shiv, Shred
SPELL_ATTR2_UNK23 = 0x00800000, // 23 Only mage Arcane Concentration have this flag
SPELL_ATTR2_UNK24 = 0x01000000, // 24
SPELL_ATTR2_UNK25 = 0x02000000, // 25
SPELL_ATTR2_UNK26 = 0x04000000, // 26 unaffected by school immunity
SPELL_ATTR2_UNK27 = 0x08000000, // 27
- SPELL_ATTR2_UNK28 = 0x10000000, // 28 no breaks stealth if it fails??
+ SPELL_ATTR2_UNK28 = 0x10000000, // 28
SPELL_ATTR2_CANT_CRIT = 0x20000000, // 29 Spell can't crit
SPELL_ATTR2_TRIGGERED_CAN_TRIGGER_PROC = 0x40000000, // 30 spell can trigger even if triggered
SPELL_ATTR2_FOOD_BUFF = 0x80000000 // 31 Food or Drink Buff (like Well Fed)
@@ -393,7 +393,7 @@ enum SpellAttr3
SPELL_ATTR3_IGNORE_HIT_RESULT = 0x00040000, // 18 Spell should always hit its target
SPELL_ATTR3_DISABLE_PROC = 0x00080000, // 19 during aura proc no spells can trigger (20178, 20375)
SPELL_ATTR3_DEATH_PERSISTENT = 0x00100000, // 20 Death persistent spells
- SPELL_ATTR3_UNK21 = 0x00200000, // 21
+ SPELL_ATTR3_UNK21 = 0x00200000, // 21 unused
SPELL_ATTR3_REQ_WAND = 0x00400000, // 22 Req wand
SPELL_ATTR3_UNK23 = 0x00800000, // 23
SPELL_ATTR3_REQ_OFFHAND = 0x01000000, // 24 Req offhand weapon
@@ -417,7 +417,7 @@ enum SpellAttr4
SPELL_ATTR4_NOT_STEALABLE = 0x00000040, // 6 although such auras might be dispellable, they cannot be stolen
SPELL_ATTR4_TRIGGERED = 0x00000080, // 7 spells forced to be triggered
SPELL_ATTR4_UNK8 = 0x00000100, // 8 ignores taken percent damage mods?
- SPELL_ATTR4_UNK9 = 0x00000200, // 9
+ SPELL_ATTR4_TRIGGER_ACTIVATE = 0x00000200, // 9 initially disabled / trigger activate from event (Execute, Riposte, Deep Freeze end other)
SPELL_ATTR4_SPELL_VS_EXTEND_COST = 0x00000400, // 10 Rogue Shiv have this flag
SPELL_ATTR4_UNK11 = 0x00000800, // 11
SPELL_ATTR4_UNK12 = 0x00001000, // 12
@@ -427,16 +427,16 @@ enum SpellAttr4
SPELL_ATTR4_NOT_USABLE_IN_ARENA = 0x00010000, // 16
SPELL_ATTR4_USABLE_IN_ARENA = 0x00020000, // 17
SPELL_ATTR4_AREA_TARGET_CHAIN = 0x00040000, // 18 (NYI)hits area targets one after another instead of all at once
- SPELL_ATTR4_UNK19 = 0x00080000, // 19
+ SPELL_ATTR4_UNK19 = 0x00080000, // 19 proc dalayed, after damage or don't proc on absorb?
SPELL_ATTR4_NOT_CHECK_SELFCAST_POWER = 0x00100000, // 20 supersedes message "More powerful spell applied" for self casts.
- SPELL_ATTR4_UNK21 = 0x00200000, // 21
+ SPELL_ATTR4_UNK21 = 0x00200000, // 21 Pally aura, dk presence, dudu form, warrior stance, shadowform, hunter track
SPELL_ATTR4_UNK22 = 0x00400000, // 22
SPELL_ATTR4_UNK23 = 0x00800000, // 23
- SPELL_ATTR4_UNK24 = 0x01000000, // 24
+ SPELL_ATTR4_UNK24 = 0x01000000, // 24 some shoot spell
SPELL_ATTR4_UNK25 = 0x02000000, // 25 pet scaling auras
SPELL_ATTR4_CAST_ONLY_IN_OUTLAND = 0x04000000, // 26 Can only be used in Outland.
SPELL_ATTR4_UNK27 = 0x08000000, // 27
- SPELL_ATTR4_UNK28 = 0x10000000, // 28
+ SPELL_ATTR4_UNK28 = 0x10000000, // 28 Aimed Shot
SPELL_ATTR4_UNK29 = 0x20000000, // 29
SPELL_ATTR4_UNK30 = 0x40000000, // 30
SPELL_ATTR4_UNK31 = 0x80000000 // 31
@@ -456,7 +456,7 @@ enum SpellAttr5
SPELL_ATTR5_START_PERIODIC_AT_APPLY = 0x00000200, // 9 begin periodic tick at aura apply
SPELL_ATTR5_HIDE_DURATION = 0x00000400, // 10 do not send duration to client
SPELL_ATTR5_ALLOW_TARGET_OF_TARGET_AS_TARGET = 0x00000800, // 11 (NYI) uses target's target as target if original target not valid (intervene for example)
- SPELL_ATTR5_UNK12 = 0x00001000, // 12
+ SPELL_ATTR5_UNK12 = 0x00001000, // 12 Cleave related?
SPELL_ATTR5_HASTE_AFFECT_DURATION = 0x00002000, // 13 haste effects decrease duration of this
SPELL_ATTR5_UNK14 = 0x00004000, // 14
SPELL_ATTR5_UNK15 = 0x00008000, // 15
@@ -470,7 +470,7 @@ enum SpellAttr5
SPELL_ATTR5_UNK23 = 0x00800000, // 23
SPELL_ATTR5_UNK24 = 0x01000000, // 24
SPELL_ATTR5_UNK25 = 0x02000000, // 25
- SPELL_ATTR5_UNK26 = 0x04000000, // 26
+ SPELL_ATTR5_UNK26 = 0x04000000, // 26 aoe related - Boulder, Cannon, Corpse Explosion, Fire Nova, Flames, Frost Bomb, Living Bomb, Seed of Corruption, Starfall, Thunder Clap, Volley
SPELL_ATTR5_UNK27 = 0x08000000, // 27
SPELL_ATTR5_UNK28 = 0x10000000, // 28
SPELL_ATTR5_UNK29 = 0x20000000, // 29
@@ -495,23 +495,23 @@ enum SpellAttr6
SPELL_ATTR6_CASTABLE_WHILE_ON_VEHICLE = 0x00001000, // 12 castable while caster is on vehicle
SPELL_ATTR6_CAN_TARGET_INVISIBLE = 0x00002000, // 13 ignore visibility requirement for spell target (phases, invisibility, etc.)
SPELL_ATTR6_UNK14 = 0x00004000, // 14
- SPELL_ATTR6_UNK15 = 0x00008000, // 15 not set in 3.0.3
+ SPELL_ATTR6_UNK15 = 0x00008000, // 15 only 54368, 67892
SPELL_ATTR6_UNK16 = 0x00010000, // 16
- SPELL_ATTR6_UNK17 = 0x00020000, // 17
+ SPELL_ATTR6_UNK17 = 0x00020000, // 17 Mount spell
SPELL_ATTR6_CAST_BY_CHARMER = 0x00040000, // 18 client won't allow to cast these spells when unit is not possessed && charmer of caster will be original caster
- SPELL_ATTR6_UNK19 = 0x00080000, // 19
- SPELL_ATTR6_UNK20 = 0x00100000, // 20
+ SPELL_ATTR6_UNK19 = 0x00080000, // 19 only 47488, 50782
+ SPELL_ATTR6_UNK20 = 0x00100000, // 20 only 58371, 62218
SPELL_ATTR6_CLIENT_UI_TARGET_EFFECTS = 0x00200000, // 21 it's only client-side attribute
- SPELL_ATTR6_UNK22 = 0x00400000, // 22
+ SPELL_ATTR6_UNK22 = 0x00400000, // 22 only 72054
SPELL_ATTR6_UNK23 = 0x00800000, // 23
SPELL_ATTR6_CAN_TARGET_UNTARGETABLE = 0x01000000, // 24
- SPELL_ATTR6_UNK25 = 0x02000000, // 25
- SPELL_ATTR6_UNK26 = 0x04000000, // 26
+ SPELL_ATTR6_UNK25 = 0x02000000, // 25 Exorcism, Flash of Light
+ SPELL_ATTR6_UNK26 = 0x04000000, // 26 related to player castable positive buff
SPELL_ATTR6_UNK27 = 0x08000000, // 27
- SPELL_ATTR6_UNK28 = 0x10000000, // 28
+ SPELL_ATTR6_UNK28 = 0x10000000, // 28 Death Grip
SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS = 0x20000000, // 29 ignores done percent damage mods?
SPELL_ATTR6_UNK30 = 0x40000000, // 30
- SPELL_ATTR6_UNK31 = 0x80000000 // 31 some special cooldown calc?
+ SPELL_ATTR6_UNK31 = 0x80000000 // 31 some special cooldown calc? only 2894
};
enum SpellAttr7
@@ -520,7 +520,7 @@ enum SpellAttr7
SPELL_ATTR7_UNK1 = 0x00000002, // 1 Not set in 3.2.2a.
SPELL_ATTR7_REACTIVATE_AT_RESURRECT = 0x00000004, // 2 Paladin's auras and 65607 only.
SPELL_ATTR7_IS_CHEAT_SPELL = 0x00000008, // 3 Cannot cast if caster doesn't have UnitFlag2 & UNIT_FLAG2_ALLOW_CHEAT_SPELLS
- SPELL_ATTR7_UNK4 = 0x00000010, // 4 Only 66109 test spell.
+ SPELL_ATTR7_UNK4 = 0x00000010, // 4 Only 47883 (Soulstone Resurrection) and test spell.
SPELL_ATTR7_SUMMON_PLAYER_TOTEM = 0x00000020, // 5 Only Shaman player totems.
SPELL_ATTR7_UNK6 = 0x00000040, // 6 Dark Surge, Surge of Light, Burning Breath triggers (boss spells).
SPELL_ATTR7_UNK7 = 0x00000080, // 7 66218 (Launch) spell.
@@ -536,18 +536,18 @@ enum SpellAttr7
SPELL_ATTR7_UNK17 = 0x00020000, // 17 Only 27965 (Suicide) spell.
SPELL_ATTR7_HAS_CHARGE_EFFECT = 0x00040000, // 18 Only spells that have Charge among effects.
SPELL_ATTR7_ZONE_TELEPORT = 0x00080000, // 19 Teleports to specific zones.
- SPELL_ATTR7_UNK20 = 0x00100000, // 20
- SPELL_ATTR7_UNK21 = 0x00200000, // 21
+ SPELL_ATTR7_UNK20 = 0x00100000, // 20 Blink, Divine Shield, Ice Block
+ SPELL_ATTR7_UNK21 = 0x00200000, // 21 Not set
SPELL_ATTR7_UNK22 = 0x00400000, // 22
- SPELL_ATTR7_UNK23 = 0x00800000, // 23
- SPELL_ATTR7_UNK24 = 0x01000000, // 24
+ SPELL_ATTR7_UNK23 = 0x00800000, // 23 Motivate, Mutilate, Shattering Throw
+ SPELL_ATTR7_UNK24 = 0x01000000, // 24 Motivate, Mutilate, Perform Speech, Shattering Throw
SPELL_ATTR7_UNK25 = 0x02000000, // 25
SPELL_ATTR7_UNK26 = 0x04000000, // 26
- SPELL_ATTR7_UNK27 = 0x08000000, // 27
- SPELL_ATTR7_UNK28 = 0x10000000, // 28
- SPELL_ATTR7_UNK29 = 0x20000000, // 29
- SPELL_ATTR7_UNK30 = 0x40000000, // 30
- SPELL_ATTR7_UNK31 = 0x80000000 // 31
+ SPELL_ATTR7_UNK27 = 0x08000000, // 27 Not set
+ SPELL_ATTR7_UNK28 = 0x10000000, // 28 related to player positive buff
+ SPELL_ATTR7_UNK29 = 0x20000000, // 29 only 69028, 71237
+ SPELL_ATTR7_UNK30 = 0x40000000, // 30 Burning Determination, Divine Sacrifice, Earth Shield, Prayer of Mending
+ SPELL_ATTR7_UNK31 = 0x80000000 // 31 only 70769
};
#define MIN_TALENT_SPEC 0
diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
index 5bd0a23207e..09af2303397 100755
--- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
@@ -47,11 +47,10 @@ template<>
void
RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature)
{
- float X, Y, Z, z, nx, ny, nz, ori, dist;
+ float X, Y, Z, nx, ny, nz, ori, dist;
creature.GetHomePosition(X, Y, Z, ori);
- z = creature.GetPositionZ();
Map const* map = creature.GetBaseMap();
// For 2D/3D system selection
diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp
index 29bd95a73a3..feb1c071b6d 100755
--- a/src/server/game/Quests/QuestDef.cpp
+++ b/src/server/game/Quests/QuestDef.cpp
@@ -106,10 +106,10 @@ Quest::Quest(Field* questRecord)
RequiredNpcOrGoCount[i] = questRecord[93+i].GetUInt32();
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
- RequiredSourceItemid[i] = questRecord[97+i].GetUInt32();
+ RequiredSourceItemId[i] = questRecord[97+i].GetUInt32();
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
- RequiredSourceItemId[i] = questRecord[101+i].GetUInt32();
+ RequiredSourceItemCount[i] = questRecord[101+i].GetUInt32();
for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
RequiredItemId[i] = questRecord[105+i].GetUInt32();
diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h
index fc9a432a11b..989c63d2a64 100755
--- a/src/server/game/Quests/QuestDef.h
+++ b/src/server/game/Quests/QuestDef.h
@@ -262,8 +262,8 @@ class Quest
std::string ObjectiveText[QUEST_OBJECTIVES_COUNT];
uint32 RequiredItemId[QUEST_ITEM_OBJECTIVES_COUNT];
uint32 RequiredItemCount[QUEST_ITEM_OBJECTIVES_COUNT];
- uint32 RequiredSourceItemid[QUEST_SOURCE_ITEM_IDS_COUNT];
uint32 RequiredSourceItemId[QUEST_SOURCE_ITEM_IDS_COUNT];
+ uint32 RequiredSourceItemCount[QUEST_SOURCE_ITEM_IDS_COUNT];
int32 RequiredNpcOrGo[QUEST_OBJECTIVES_COUNT]; // >0 Creature <0 Gameobject
uint32 RequiredNpcOrGoCount[QUEST_OBJECTIVES_COUNT];
uint32 RequiredSpellCast[QUEST_OBJECTIVES_COUNT];
diff --git a/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp b/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp
index 2f8a27740be..1710a387307 100755
--- a/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp
@@ -115,6 +115,8 @@ void WorldSession::SendAuctionOwnerNotification(AuctionEntry* auction)
//this void creates new auction and adds auction to some auctionhouse
void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
{
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_AUCTION_SELL_ITEM");
+
uint64 auctioneer, item;
uint32 etime, bid, buyout, count;
recv_data >> auctioneer;
@@ -253,6 +255,8 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
//this function is called when client bids or buys out auction
void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
{
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_AUCTION_PLACE_BID");
+
uint64 auctioneer;
uint32 auctionId;
uint32 price;
@@ -374,6 +378,8 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
//this void is called when auction_owner cancels his auction
void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data)
{
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_AUCTION_REMOVE_ITEM");
+
uint64 auctioneer;
uint32 auctionId;
recv_data >> auctioneer;
@@ -452,6 +458,8 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data)
//called when player lists his bids
void WorldSession::HandleAuctionListBidderItems(WorldPacket & recv_data)
{
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_AUCTION_LIST_BIDDER_ITEMS");
+
uint64 guid; //NPC guid
uint32 listfrom; //page of auctions
uint32 outbiddedCount; //count of outbidded auctions
@@ -469,6 +477,7 @@ void WorldSession::HandleAuctionListBidderItems(WorldPacket & recv_data)
if (!creature)
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleAuctionListBidderItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
+ recv_data.rfinish();
return;
}
@@ -506,6 +515,8 @@ void WorldSession::HandleAuctionListBidderItems(WorldPacket & recv_data)
//this void sends player info about his auctions
void WorldSession::HandleAuctionListOwnerItems(WorldPacket & recv_data)
{
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_AUCTION_LIST_OWNER_ITEMS");
+
uint32 listfrom;
uint64 guid;
@@ -541,6 +552,8 @@ void WorldSession::HandleAuctionListOwnerItems(WorldPacket & recv_data)
//this void is called when player clicks on search button
void WorldSession::HandleAuctionListItems(WorldPacket & recv_data)
{
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_AUCTION_LIST_ITEMS");
+
std::string searchedname;
uint8 levelmin, levelmax, usable;
uint32 listfrom, auctionSlotID, auctionMainCategory, auctionSubCategory, quality;
@@ -606,7 +619,7 @@ void WorldSession::HandleAuctionListItems(WorldPacket & recv_data)
void WorldSession::HandleAuctionListPendingSales(WorldPacket & recv_data)
{
- sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_AUCTION_LIST_PENDING_SALES");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_AUCTION_LIST_PENDING_SALES");
recv_data.read_skip<uint64>();
diff --git a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
index 83b9ab048ad..3d33e506655 100755
--- a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
@@ -997,7 +997,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
pCurrChar->RemoveAtLoginFlag(AT_LOGIN_FIRST);
// show time before shutdown if shutdown planned.
- if (sWorld->IsShutdowning())
+ if (sWorld->IsShuttingDown())
sWorld->ShutdownMsg(true, pCurrChar);
if (sWorld->getBoolConfig(CONFIG_ALL_TAXI_PATHS))
@@ -1085,15 +1085,17 @@ void WorldSession::HandleSetFactionInactiveOpcode(WorldPacket & recv_data)
_player->GetReputationMgr().SetInactive(replistid, inactive);
}
-void WorldSession::HandleShowingHelmOpcode(WorldPacket & /*recv_data*/)
+void WorldSession::HandleShowingHelmOpcode(WorldPacket& recv_data)
{
sLog->outStaticDebug("CMSG_SHOWING_HELM for %s", _player->GetName());
+ recv_data.read_skip<uint8>(); // unknown, bool?
_player->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM);
}
-void WorldSession::HandleShowingCloakOpcode(WorldPacket & /*recv_data*/)
+void WorldSession::HandleShowingCloakOpcode(WorldPacket& recv_data)
{
sLog->outStaticDebug("CMSG_SHOWING_CLOAK for %s", _player->GetName());
+ recv_data.read_skip<uint8>(); // unknown, bool?
_player->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_CLOAK);
}
diff --git a/src/server/game/Server/Protocol/Handlers/CombatHandler.cpp b/src/server/game/Server/Protocol/Handlers/CombatHandler.cpp
index 31a09e830ff..e6c4499baab 100755
--- a/src/server/game/Server/Protocol/Handlers/CombatHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/CombatHandler.cpp
@@ -23,13 +23,15 @@
#include "ObjectAccessor.h"
#include "CreatureAI.h"
#include "ObjectDefines.h"
+#include "Vehicle.h"
+#include "VehicleDefines.h"
-void WorldSession::HandleAttackSwingOpcode(WorldPacket & recv_data)
+void WorldSession::HandleAttackSwingOpcode(WorldPacket& recv_data)
{
uint64 guid;
recv_data >> guid;
- sLog->outStaticDebug("WORLD: Recvd CMSG_ATTACKSWING Message guidlow:%u guidhigh:%u", GUID_LOPART(guid), GUID_HIPART(guid));
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_ATTACKSWING Message guidlow:%u guidhigh:%u", GUID_LOPART(guid), GUID_HIPART(guid));
Unit* pEnemy = ObjectAccessor::GetUnit(*_player, guid);
@@ -47,6 +49,20 @@ void WorldSession::HandleAttackSwingOpcode(WorldPacket & recv_data)
return;
}
+ //! Client explicitly checks the following before sending CMSG_ATTACKSWING packet,
+ //! so we'll place the same check here. Note that it might be possible to reuse this snippet
+ //! in other places as well.
+ if (Vehicle* vehicle = _player->GetVehicle())
+ {
+ VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(_player);
+ ASSERT(seat);
+ if (!(seat->m_flags & VEHICLE_SEAT_FLAG_CAN_ATTACK))
+ {
+ SendAttackStop(pEnemy);
+ return;
+ }
+ }
+
_player->Attack(pEnemy, true);
}
@@ -55,7 +71,7 @@ void WorldSession::HandleAttackStopOpcode(WorldPacket & /*recv_data*/)
GetPlayer()->AttackStop();
}
-void WorldSession::HandleSetSheathedOpcode(WorldPacket & recv_data)
+void WorldSession::HandleSetSheathedOpcode(WorldPacket& recv_data)
{
uint32 sheathed;
recv_data >> sheathed;
@@ -79,4 +95,3 @@ void WorldSession::SendAttackStop(Unit const* enemy)
data << uint32(0); // unk, can be 1 also
SendPacket(&data);
}
-
diff --git a/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp b/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp
index a675214930a..9c247655c3a 100755
--- a/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp
@@ -878,19 +878,18 @@ void WorldSession::HandleRepairItemOpcode(WorldPacket & recv_data)
// reputation discount
float discountMod = _player->GetReputationPriceDiscount(unit);
- uint32 TotalCost = 0;
if (itemGUID)
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "ITEM: Repair item, itemGUID = %u, npcGUID = %u", GUID_LOPART(itemGUID), GUID_LOPART(npcGUID));
Item* item = _player->GetItemByGuid(itemGUID);
if (item)
- TotalCost = _player->DurabilityRepair(item->GetPos(), true, discountMod, guildBank);
+ _player->DurabilityRepair(item->GetPos(), true, discountMod, guildBank);
}
else
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "ITEM: Repair all items, npcGUID = %u", GUID_LOPART(npcGUID));
- TotalCost = _player->DurabilityRepairAll(true, discountMod, guildBank);
+ _player->DurabilityRepairAll(true, discountMod, guildBank);
}
}
diff --git a/src/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp b/src/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp
index a931d8a5b3d..2e9b88bd3f0 100755
--- a/src/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp
@@ -311,21 +311,17 @@ void WorldSession::SendPetitionQueryOpcode(uint64 petitionguid)
uint64 ownerguid = 0;
uint32 type;
std::string name = "NO_NAME_FOR_GUID";
- uint8 signs = 0;
- QueryResult result = CharacterDatabase.PQuery(
- "SELECT ownerguid, name, "
- " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs, "
- " type "
- "FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid), GUID_LOPART(petitionguid));
+ // TODO: Use CHAR_LOAD_PETITION PS
+ QueryResult result = CharacterDatabase.PQuery("SELECT ownerguid, name, type "
+ "FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
if (result)
{
Field* fields = result->Fetch();
ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
name = fields[1].GetString();
- signs = fields[2].GetUInt8();
- type = fields[3].GetUInt32();
+ type = fields[2].GetUInt32();
}
else
{
diff --git a/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp b/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp
index bf951619e63..042b1242a95 100755
--- a/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp
@@ -413,7 +413,10 @@ void WorldSession::HandleQuestPOIQuery(WorldPacket& recv_data)
recv_data >> count; // quest count, max=25
if (count >= MAX_QUEST_LOG_SIZE)
+ {
+ recv_data.rfinish();
return;
+ }
WorldPacket data(SMSG_QUEST_POI_QUERY_RESPONSE, 4+(4+4)*count);
data << uint32(count); // count
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index c4487fbd950..beb55733e71 100755
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -1518,7 +1518,7 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
spellId3 = 47180;
break;
}
- target->CastSpell(target, spellId, true, NULL, this);
+ target->CastSpell(target, spellId3, true, NULL, this);
}
// Master Shapeshifter - Cat
if (AuraEffect const* aurEff = target->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2851, 0))
@@ -4803,6 +4803,10 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
case 71563:
if (Aura* newAura = target->AddAura(71564, target))
newAura->SetStackAmount(newAura->GetSpellInfo()->StackAmount);
+ break;
+ case 59628: // Tricks of the Trade
+ target->SetReducedThreatPercent(100,caster->GetGUID());
+ break;
}
}
// AT REMOVE
@@ -4950,6 +4954,15 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
if (GetId() == 61777)
target->CastSpell(target, GetAmount(), true);
break;
+ case SPELLFAMILY_ROGUE:
+ // Tricks of the trade
+ switch(GetId())
+ {
+ case 59628:
+ case 57934:
+ target->SetReducedThreatPercent(0,0);
+ break;
+ }
default:
break;
}
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 8a4c0a768d8..e1c5b9074ba 100755
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -4126,9 +4126,6 @@ void Spell::SendChannelUpdate(uint32 time)
m_caster->SetUInt32Value(UNIT_CHANNEL_SPELL, 0);
}
- if (m_caster->GetTypeId() != TYPEID_PLAYER)
- return;
-
WorldPacket data(MSG_CHANNEL_UPDATE, 8+4);
data.append(m_caster->GetPackGUID());
data << uint32(time);
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index e42294f59ae..97332436f09 100755
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -606,57 +606,67 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
case SPELLFAMILY_ROGUE:
{
// Envenom
- if (m_caster->GetTypeId() == TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags[1] & 0x8))
+ if (m_spellInfo->SpellFamilyFlags[1] & 0x00000008)
{
- // consume from stack dozes not more that have combo-points
- if (uint32 combo = m_caster->ToPlayer()->GetComboPoints())
+ if (Player* player = m_caster->ToPlayer())
{
- // Lookup for Deadly poison (only attacker applied)
- if (AuraEffect const* aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_ROGUE, 0x10000, 0, 0, m_caster->GetGUID()))
+ // consume from stack dozes not more that have combo-points
+ if (uint32 combo = player->GetComboPoints())
{
- // count consumed deadly poison doses at target
- bool needConsume = true;
- uint32 spellId = aurEff->GetId();
- uint32 doses = aurEff->GetBase()->GetStackAmount();
- if (doses > combo)
- doses = combo;
- // Master Poisoner
- Unit::AuraEffectList const& auraList = m_caster->ToPlayer()->GetAuraEffectsByType(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK);
- for (Unit::AuraEffectList::const_iterator iter = auraList.begin(); iter != auraList.end(); ++iter)
+ // Lookup for Deadly poison (only attacker applied)
+ if (AuraEffect const* aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_ROGUE, 0x00010000, 0, 0, m_caster->GetGUID()))
{
- if ((*iter)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellInfo()->SpellIconID == 1960)
+ // count consumed deadly poison doses at target
+ bool needConsume = true;
+ uint32 spellId = aurEff->GetId();
+
+ uint32 doses = aurEff->GetBase()->GetStackAmount();
+ if (doses > combo)
+ doses = combo;
+
+ // Master Poisoner
+ Unit::AuraEffectList const& auraList = player->GetAuraEffectsByType(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK);
+ for (Unit::AuraEffectList::const_iterator iter = auraList.begin(); iter != auraList.end(); ++iter)
{
- uint32 chance = (*iter)->GetSpellInfo()->Effects[EFFECT_2].CalcValue(m_caster);
+ if ((*iter)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellInfo()->SpellIconID == 1960)
+ {
+ uint32 chance = (*iter)->GetSpellInfo()->Effects[EFFECT_2].CalcValue(m_caster);
- if (chance && roll_chance_i(chance))
- needConsume = false;
+ if (chance && roll_chance_i(chance))
+ needConsume = false;
- break;
+ break;
+ }
}
+
+ if (needConsume)
+ for (uint32 i = 0; i < doses; ++i)
+ unitTarget->RemoveAuraFromStack(spellId);
+
+ damage *= doses;
+ damage += int32(player->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * combo);
}
- if (needConsume)
- for (uint32 i = 0; i < doses; ++i)
- unitTarget->RemoveAuraFromStack(spellId);
- damage *= doses;
- damage += int32(((Player*)m_caster)->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * doses);
+ // Eviscerate and Envenom Bonus Damage (item set effect)
+ if (m_caster->HasAura(37169))
+ damage += combo * 40;
}
- // Eviscerate and Envenom Bonus Damage (item set effect)
- if (m_caster->HasAura(37169))
- damage += ((Player*)m_caster)->GetComboPoints()*40;
}
}
// Eviscerate
- else if ((m_spellInfo->SpellFamilyFlags[0] & 0x00020000) && m_caster->GetTypeId() == TYPEID_PLAYER)
+ else if (m_spellInfo->SpellFamilyFlags[0] & 0x00020000)
{
- if (uint32 combo = ((Player*)m_caster)->GetComboPoints())
+ if (m_caster->GetTypeId() == TYPEID_PLAYER)
{
- float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
- damage += irand(int32(ap * combo * 0.03f), int32(ap * combo * 0.07f));
+ if (uint32 combo = ((Player*)m_caster)->GetComboPoints())
+ {
+ float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
+ damage += irand(int32(ap * combo * 0.03f), int32(ap * combo * 0.07f));
- // Eviscerate and Envenom Bonus Damage (item set effect)
- if (m_caster->HasAura(37169))
- damage += combo*40;
+ // Eviscerate and Envenom Bonus Damage (item set effect)
+ if (m_caster->HasAura(37169))
+ damage += combo*40;
+ }
}
}
break;
@@ -1421,11 +1431,19 @@ void Spell::EffectDummy(SpellEffIndex effIndex)
{
if (!unitTarget)
return;
- // Restorative Totems
if (Unit* owner = m_caster->GetOwner())
+ {
+ if (m_triggeredByAuraSpell)
+ damage = int32(owner->SpellHealingBonus(unitTarget, m_triggeredByAuraSpell, damage, HEAL));
+
+ // Restorative Totems
if (AuraEffect* dummy = owner->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, 338, 1))
AddPctN(damage, dummy->GetAmount());
+ // Glyph of Healing Stream Totem
+ if (AuraEffect const* aurEff = owner->GetAuraEffect(55456, EFFECT_0))
+ AddPctN(damage, aurEff->GetAmount());
+ }
m_caster->CastCustomSpell(unitTarget, 52042, &damage, 0, 0, true, 0, 0, m_originalCasterGUID);
return;
}
@@ -2093,12 +2111,12 @@ void Spell::EffectUnlearnSpecialization(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- Player* _player = unitTarget->ToPlayer();
+ Player* player = unitTarget->ToPlayer();
uint32 spellToUnlearn = m_spellInfo->Effects[effIndex].TriggerSpell;
- _player->removeSpell(spellToUnlearn);
+ player->removeSpell(spellToUnlearn);
- sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell: Player %u has unlearned spell %u from NpcGUID: %u", _player->GetGUIDLow(), spellToUnlearn, m_caster->GetGUIDLow());
+ sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell: Player %u has unlearned spell %u from NpcGUID: %u", player->GetGUIDLow(), spellToUnlearn, m_caster->GetGUIDLow());
}
void Spell::EffectPowerDrain(SpellEffIndex effIndex)
@@ -5875,16 +5893,15 @@ void Spell::EffectFeedPet(SpellEffIndex effIndex)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
- if (m_caster->GetTypeId() != TYPEID_PLAYER)
+ Player* player = m_caster->ToPlayer();
+ if (!player)
return;
- Player* _player = m_caster->ToPlayer();
-
Item* foodItem = itemTarget;
if (!foodItem)
return;
- Pet* pet = _player->GetPet();
+ Pet* pet = player->GetPet();
if (!pet)
return;
@@ -5898,7 +5915,7 @@ void Spell::EffectFeedPet(SpellEffIndex effIndex)
ExecuteLogEffectDestroyItem(effIndex, foodItem->GetEntry());
uint32 count = 1;
- _player->DestroyItemCount(foodItem, count, true);
+ player->DestroyItemCount(foodItem, count, true);
// TODO: fix crash when a spell has two effects, both pointed at the same item target
m_caster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, NULL, NULL, true);
@@ -6097,7 +6114,7 @@ void Spell::EffectReputation(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- Player* _player = unitTarget->ToPlayer();
+ Player* player = unitTarget->ToPlayer();
int32 rep_change = damage;
@@ -6114,10 +6131,10 @@ void Spell::EffectReputation(SpellEffIndex effIndex)
}
// Bonus from spells that increase reputation gain
- float bonus = rep_change * _player->GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN) / 100.0f; // 10%
+ float bonus = rep_change * player->GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN) / 100.0f; // 10%
rep_change += (int32)bonus;
- _player->GetReputationMgr().ModifyReputation(factionEntry, rep_change);
+ player->GetReputationMgr().ModifyReputation(factionEntry, rep_change);
}
void Spell::EffectQuestComplete(SpellEffIndex effIndex)
@@ -6227,9 +6244,13 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/)
if (!unitTarget)
return;
- float x, y, z;
- unitTarget->GetContactPoint(m_caster, x, y, z);
- m_caster->GetMotionMaster()->MoveCharge(x, y, z);
+ float angle = unitTarget->GetRelativeAngle(m_caster);
+ Position pos;
+
+ unitTarget->GetContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ);
+ unitTarget->GetFirstCollisionPosition(pos, unitTarget->GetObjectSize(), angle);
+
+ m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ + unitTarget->GetObjectSize());
}
if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT_TARGET)
@@ -6250,9 +6271,13 @@ void Spell::EffectChargeDest(SpellEffIndex /*effIndex*/)
if (m_targets.HasDst())
{
- float x, y, z;
- m_targets.GetDst()->GetPosition(x, y, z);
- m_caster->GetMotionMaster()->MoveCharge(x, y, z);
+ Position pos;
+ m_targets.GetDst()->GetPosition(&pos);
+ float angle = m_caster->GetRelativeAngle(pos.GetPositionX(), pos.GetPositionY());
+ float dist = m_caster->GetDistance(pos);
+ m_caster->GetFirstCollisionPosition(pos, dist, angle);
+
+ m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ);
}
}
@@ -6432,20 +6457,20 @@ void Spell::EffectSummonDeadPet(SpellEffIndex /*effIndex*/)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
- if (m_caster->GetTypeId() != TYPEID_PLAYER)
- return;
- Player* _player = m_caster->ToPlayer();
- Pet* pet = _player->GetPet();
- if (!pet)
+ Player* player = m_caster->ToPlayer();
+ if (!player)
return;
- if (pet->isAlive())
+
+ Pet* pet = player->GetPet();
+ if (!pet || pet->isAlive())
return;
+
if (damage < 0)
return;
float x, y, z;
- _player->GetPosition(x, y, z);
- _player->GetMap()->CreatureRelocation(pet, x, y, z, _player->GetOrientation());
+ player->GetPosition(x, y, z);
+ player->GetMap()->CreatureRelocation(pet, x, y, z, player->GetOrientation());
pet->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_NONE);
pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
@@ -6454,7 +6479,7 @@ void Spell::EffectSummonDeadPet(SpellEffIndex /*effIndex*/)
pet->SetHealth(pet->CountPctFromMaxHealth(damage));
//pet->AIM_Initialize();
- //_player->PetSpellInitialize();
+ //player->PetSpellInitialize();
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
}
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 55a70066a8d..058ddf7d269 100755
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -2824,6 +2824,13 @@ void SpellMgr::LoadSpellCustomAttr()
case 48689:
case 48690:
case 48691:
+ case 6785: // Ravage
+ case 6787:
+ case 9866:
+ case 9867:
+ case 27005:
+ case 48578:
+ case 48579:
case 21987: // Lash of Pain
case 23959: // Test Stab R50
case 24825: // Test Backstab
@@ -2968,6 +2975,7 @@ void SpellMgr::LoadDbcDataCorrections()
case 51904: // Summon Ghouls On Scarlet Crusade (this should use conditions table, script for this spell needs to be fixed)
case 2895: // Wrath of Air Totem rank 1 (Aura)
case 68933: // Wrath of Air Totem rank 2 (Aura)
+ case 29200: // Purify Helboar Meat
spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_CASTER;
spellInfo->EffectImplicitTargetB[0] = 0;
break;
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 8aca4563b91..a139c50fb3e 100755
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1387,7 +1387,7 @@ void World::SetInitialWorldSettings()
sLog->outString("Loading pet default spells additional to levelup spells...");
sSpellMgr->LoadPetDefaultSpells();
- sLog->outString("Loading Creature Template Addon Data...");
+ sLog->outString("Loading Creature Addon Data...");
sObjectMgr->LoadCreatureAddons(); // must be after LoadCreatureTemplates() and LoadCreatures()
sLog->outString("Loading Creature Respawn Data..."); // must be after PackInstances()
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index f643ae60287..9354c14f51c 100755
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -634,7 +634,8 @@ class World
void SendServerMessage(ServerMessageType type, const char *text = "", Player* player = NULL);
/// Are we in the middle of a shutdown?
- bool IsShutdowning() const { return m_ShutdownTimer > 0; }
+ bool IsShuttingDown() const { return m_ShutdownTimer > 0; }
+ uint32 GetShutDownTimeLeft() const { return m_ShutdownTimer; }
void ShutdownServ(uint32 time, uint32 options, uint8 exitcode);
void ShutdownCancel();
void ShutdownMsg(bool show = false, Player* player = NULL);
diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp
index 28bc17a7450..c32abb9537b 100644
--- a/src/server/scripts/Commands/cs_modify.cpp
+++ b/src/server/scripts/Commands/cs_modify.cpp
@@ -1129,7 +1129,12 @@ public:
uint16 drunkMod = drunklevel * 0xFFFF / 100;
- handler->GetSession()->GetPlayer()->SetDrunkValue(drunkMod);
+ Player* target = handler->getSelectedPlayer();
+ if (!target)
+ target = handler->GetSession()->GetPlayer();
+
+ if (target)
+ target->SetDrunkValue(drunkMod);
return true;
}
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp
index 82f16dd7784..7cbb1b91755 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp
@@ -582,7 +582,7 @@ public:
{
Unit* pJaina = GetClosestCreatureWithEntry(me, NPC_JAINA, 50.0f);
if (!pJaina)
- pJaina = pJaina = me->SummonCreature(NPC_JAINA, 1895.48f, 1292.66f, 143.706f, 0.023475f, TEMPSUMMON_DEAD_DESPAWN, 180000);
+ pJaina = me->SummonCreature(NPC_JAINA, 1895.48f, 1292.66f, 143.706f, 0.023475f, TEMPSUMMON_DEAD_DESPAWN, 180000);
if (pJaina)
uiJainaGUID = pJaina->GetGUID();
bStepping = false;
diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp
index 545dc79453d..e0892ffb009 100644
--- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp
+++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp
@@ -91,49 +91,50 @@ public:
struct boss_anub_arakAI : public ScriptedAI
{
- boss_anub_arakAI(Creature* c) : ScriptedAI(c), lSummons(me)
+ boss_anub_arakAI(Creature* creature) : ScriptedAI(creature), Summons(me)
{
- instance = c->GetInstanceScript();
+ instance = creature->GetInstanceScript();
}
InstanceScript* instance;
- bool bChanneling;
- bool bGuardianSummoned;
- bool bVenomancerSummoned;
- bool bDatterSummoned;
- uint8 uiPhase;
- uint32 uiUndergroundPhase;
- uint32 uiCarrionBeetlesTimer;
- uint32 uiLeechingSwarmTimer;
- uint32 uiPoundTimer;
- uint32 uiSubmergeTimer;
- uint32 uiUndergroundTimer;
- uint32 uiVenomancerTimer;
- uint32 uiDatterTimer;
-
- uint32 uiImpaleTimer;
- uint32 uiImpalePhase;
- uint64 uiImpaleTarget;
-
- SummonList lSummons;
+ bool Channeling;
+ bool GuardianSummoned;
+ bool VenomancerSummoned;
+ bool DatterSummoned;
+ uint8 Phase;
+ uint32 UndergroundPhase;
+ uint32 CarrionBeetlesTimer;
+ uint32 LeechingSwarmTimer;
+ uint32 PoundTimer;
+ uint32 SubmergeTimer;
+ uint32 UndergroundTimer;
+ uint32 VenomancerTimer;
+ uint32 DatterTimer;
+ uint32 DelayTimer;
+
+ uint32 ImpaleTimer;
+ uint32 ImpalePhase;
+ uint64 ImpaleTarget;
+
+ SummonList Summons;
void Reset()
{
- uiCarrionBeetlesTimer = 8*IN_MILLISECONDS;
- uiLeechingSwarmTimer = 20*IN_MILLISECONDS;
- uiImpaleTimer = 9*IN_MILLISECONDS;
- uiPoundTimer = 15*IN_MILLISECONDS;
+ CarrionBeetlesTimer = 8*IN_MILLISECONDS;
+ LeechingSwarmTimer = 20*IN_MILLISECONDS;
+ ImpaleTimer = 9*IN_MILLISECONDS;
+ PoundTimer = 15*IN_MILLISECONDS;
- uiPhase = PHASE_MELEE;
- uiUndergroundPhase = 0;
- bChanneling = false;
- uiImpalePhase = IMPALE_PHASE_TARGET;
+ Phase = PHASE_MELEE;
+ UndergroundPhase = 0;
+ Channeling = false;
+ ImpalePhase = IMPALE_PHASE_TARGET;
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
me->RemoveAura(SPELL_SUBMERGE);
- lSummons.DespawnAll();
+ Summons.DespawnAll();
if (instance)
{
@@ -147,13 +148,13 @@ public:
Position targetPos;
target->GetPosition(&targetPos);
- if (TempSummon* pImpaleTarget = me->SummonCreature(CREATURE_IMPALE_TARGET, targetPos, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 6*IN_MILLISECONDS))
+ if (TempSummon* impaleTarget = me->SummonCreature(CREATURE_IMPALE_TARGET, targetPos, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 6*IN_MILLISECONDS))
{
- uiImpaleTarget = pImpaleTarget->GetGUID();
- pImpaleTarget->SetReactState(REACT_PASSIVE);
- pImpaleTarget->SetDisplayId(DISPLAY_INVISIBLE);
- pImpaleTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE|UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
- return pImpaleTarget;
+ ImpaleTarget = impaleTarget->GetGUID();
+ impaleTarget->SetReactState(REACT_PASSIVE);
+ impaleTarget->SetDisplayId(DISPLAY_INVISIBLE);
+ impaleTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE|UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
+ return impaleTarget;
}
return NULL;
@@ -162,11 +163,15 @@ public:
void EnterCombat(Unit* /*who*/)
{
DoScriptText(SAY_AGGRO, me);
+ DelayTimer = 0;
if (instance)
- {
- instance->SetData(DATA_ANUBARAK_EVENT, IN_PROGRESS);
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
- }
+ }
+
+ void DelayEventStart()
+ {
+ if (instance)
+ instance->SetData(DATA_ANUBARAK_EVENT, IN_PROGRESS);
}
void UpdateAI(const uint32 diff)
@@ -174,41 +179,45 @@ public:
if (!UpdateVictim())
return;
- switch (uiPhase)
+ if (DelayTimer && DelayTimer > 5000)
+ DelayEventStart();
+ else DelayTimer+=diff;
+
+ switch (Phase)
{
case PHASE_UNDERGROUND:
- if (uiImpaleTimer <= diff)
+ if (ImpaleTimer <= diff)
{
- switch (uiImpalePhase)
+ switch (ImpalePhase)
{
case IMPALE_PHASE_TARGET:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
{
- if (Creature* pImpaleTarget = DoSummonImpaleTarget(target))
- pImpaleTarget->CastSpell(pImpaleTarget, SPELL_IMPALE_SHAKEGROUND, true);
- uiImpaleTimer = 3*IN_MILLISECONDS;
- uiImpalePhase = IMPALE_PHASE_ATTACK;
+ if (Creature* impaleTarget = DoSummonImpaleTarget(target))
+ impaleTarget->CastSpell(impaleTarget, SPELL_IMPALE_SHAKEGROUND, true);
+ ImpaleTimer = 3*IN_MILLISECONDS;
+ ImpalePhase = IMPALE_PHASE_ATTACK;
}
break;
case IMPALE_PHASE_ATTACK:
- if (Creature* pImpaleTarget = Unit::GetCreature(*me, uiImpaleTarget))
+ if (Creature* impaleTarget = Unit::GetCreature(*me, ImpaleTarget))
{
- pImpaleTarget->CastSpell(pImpaleTarget, SPELL_IMPALE_SPIKE, false);
- pImpaleTarget->RemoveAurasDueToSpell(SPELL_IMPALE_SHAKEGROUND);
+ impaleTarget->CastSpell(impaleTarget, SPELL_IMPALE_SPIKE, false);
+ impaleTarget->RemoveAurasDueToSpell(SPELL_IMPALE_SHAKEGROUND);
}
- uiImpalePhase = IMPALE_PHASE_DMG;
- uiImpaleTimer = 1*IN_MILLISECONDS;
+ ImpalePhase = IMPALE_PHASE_DMG;
+ ImpaleTimer = 1*IN_MILLISECONDS;
break;
case IMPALE_PHASE_DMG:
- if (Creature* pImpaleTarget = Unit::GetCreature(*me, uiImpaleTarget))
- me->CastSpell(pImpaleTarget, DUNGEON_MODE(SPELL_IMPALE_DMG, SPELL_IMPALE_DMG_H), true);
- uiImpalePhase = IMPALE_PHASE_TARGET;
- uiImpaleTimer = 9*IN_MILLISECONDS;
+ if (Creature* impaleTarget = Unit::GetCreature(*me, ImpaleTarget))
+ me->CastSpell(impaleTarget, DUNGEON_MODE(SPELL_IMPALE_DMG, SPELL_IMPALE_DMG_H), true);
+ ImpalePhase = IMPALE_PHASE_TARGET;
+ ImpaleTimer = 9*IN_MILLISECONDS;
break;
}
- } else uiImpaleTimer -= diff;
+ } else ImpaleTimer -= diff;
- if (!bGuardianSummoned)
+ if (!GuardianSummoned)
{
for (uint8 i = 0; i < 2; ++i)
{
@@ -218,14 +227,14 @@ public:
DoZoneInCombat(Guardian);
}
}
- bGuardianSummoned = true;
+ GuardianSummoned = true;
}
- if (!bVenomancerSummoned)
+ if (!VenomancerSummoned)
{
- if (uiVenomancerTimer <= diff)
+ if (VenomancerTimer <= diff)
{
- if (uiUndergroundPhase > 1)
+ if (UndergroundPhase > 1)
{
for (uint8 i = 0; i < 2; ++i)
{
@@ -235,16 +244,16 @@ public:
DoZoneInCombat(Venomancer);
}
}
- bVenomancerSummoned = true;
+ VenomancerSummoned = true;
}
- } else uiVenomancerTimer -= diff;
+ } else VenomancerTimer -= diff;
}
- if (!bDatterSummoned)
+ if (!DatterSummoned)
{
- if (uiDatterTimer <= diff)
+ if (DatterTimer <= diff)
{
- if (uiUndergroundPhase > 2)
+ if (UndergroundPhase > 2)
{
for (uint8 i = 0; i < 2; ++i)
{
@@ -254,71 +263,74 @@ public:
DoZoneInCombat(Datter);
}
}
- bDatterSummoned = true;
+ DatterSummoned = true;
}
- } else uiDatterTimer -= diff;
+ } else DatterTimer -= diff;
+
+ if(me->HasAura(SPELL_LEECHING_SWARM))
+ me->RemoveAurasDueToSpell(SPELL_LEECHING_SWARM);
}
- if (uiUndergroundTimer <= diff)
+ if (UndergroundTimer <= diff)
{
me->RemoveAura(SPELL_SUBMERGE);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
- uiPhase = PHASE_MELEE;
- } else uiUndergroundTimer -= diff;
+ Phase = PHASE_MELEE;
+ } else UndergroundTimer -= diff;
break;
case PHASE_MELEE:
- if (((uiUndergroundPhase == 0 && HealthBelowPct(75))
- || (uiUndergroundPhase == 1 && HealthBelowPct(50))
- || (uiUndergroundPhase == 2 && HealthBelowPct(25)))
+ if (((UndergroundPhase == 0 && HealthBelowPct(75))
+ || (UndergroundPhase == 1 && HealthBelowPct(50))
+ || (UndergroundPhase == 2 && HealthBelowPct(25)))
&& !me->HasUnitState(UNIT_STAT_CASTING))
{
- bGuardianSummoned = false;
- bVenomancerSummoned = false;
- bDatterSummoned = false;
+ GuardianSummoned = false;
+ VenomancerSummoned = false;
+ DatterSummoned = false;
- uiUndergroundTimer = 40*IN_MILLISECONDS;
- uiVenomancerTimer = 25*IN_MILLISECONDS;
- uiDatterTimer = 32*IN_MILLISECONDS;
+ UndergroundTimer = 40*IN_MILLISECONDS;
+ VenomancerTimer = 25*IN_MILLISECONDS;
+ DatterTimer = 32*IN_MILLISECONDS;
- uiImpalePhase = 0;
- uiImpaleTimer = 9*IN_MILLISECONDS;
+ ImpalePhase = 0;
+ ImpaleTimer = 9*IN_MILLISECONDS;
DoCast(me, SPELL_SUBMERGE, false);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
- uiPhase = PHASE_UNDERGROUND;
- ++uiUndergroundPhase;
+ Phase = PHASE_UNDERGROUND;
+ ++UndergroundPhase;
}
- if (bChanneling == true)
+ if (Channeling == true)
{
for (uint8 i = 0; i < 8; ++i)
DoCast(me->getVictim(), SPELL_SUMMON_CARRION_BEETLES, true);
- bChanneling = false;
+ Channeling = false;
}
- else if (uiCarrionBeetlesTimer <= diff)
+ else if (CarrionBeetlesTimer <= diff)
{
- bChanneling = true;
+ Channeling = true;
DoCastVictim(SPELL_CARRION_BEETLES);
- uiCarrionBeetlesTimer = 25*IN_MILLISECONDS;
- } else uiCarrionBeetlesTimer -= diff;
+ CarrionBeetlesTimer = 25*IN_MILLISECONDS;
+ } else CarrionBeetlesTimer -= diff;
- if (uiLeechingSwarmTimer <= diff)
+ if (LeechingSwarmTimer <= diff)
{
DoCast(me, SPELL_LEECHING_SWARM, true);
- uiLeechingSwarmTimer = 19*IN_MILLISECONDS;
- } else uiLeechingSwarmTimer -= diff;
+ LeechingSwarmTimer = 19*IN_MILLISECONDS;
+ } else LeechingSwarmTimer -= diff;
- if (uiPoundTimer <= diff)
+ if (PoundTimer <= diff)
{
if (Unit* target = me->getVictim())
{
if (Creature* pImpaleTarget = DoSummonImpaleTarget(target))
me->CastSpell(pImpaleTarget, DUNGEON_MODE(SPELL_POUND, SPELL_POUND_H), false);
}
- uiPoundTimer = 16500;
- } else uiPoundTimer -= diff;
+ PoundTimer = 16500;
+ } else PoundTimer -= diff;
DoMeleeAttackIfReady();
break;
@@ -328,7 +340,7 @@ public:
void JustDied(Unit* /*killer*/)
{
DoScriptText(SAY_DEATH, me);
- lSummons.DespawnAll();
+ Summons.DespawnAll();
if (instance)
instance->SetData(DATA_ANUBARAK_EVENT, DONE);
}
@@ -342,7 +354,7 @@ public:
void JustSummoned(Creature* summon)
{
- lSummons.Summon(summon);
+ Summons.Summon(summon);
}
};
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
index 29c3276467b..25610341a2f 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
@@ -341,7 +341,7 @@ class boss_sindragosa : public CreatureScript
{
if (uint32 spellId = sSpellMgr->GetSpellIdForDifficulty(_isThirdPhase ? SPELL_FROST_BREATH_P2 : SPELL_FROST_BREATH_P1, me))
{
- if (player->GetQuestStatus(QUEST_FROST_INFUSION) != QUEST_STATUS_REWARDED && spellId == spell->Id)
+ if (player->GetQuestStatus(QUEST_FROST_INFUSION) == QUEST_STATUS_INCOMPLETE && spellId == spell->Id)
{
if (Item* shadowsEdge = player->GetWeaponForAttack(BASE_ATTACK, true))
{
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp b/src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp
index 16c258af756..e63d50b0133 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp
+++ b/src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp
@@ -289,6 +289,7 @@ public:
void JustDied(Unit* /*killer*/)
{
_JustDied();
+ DoCast(me, SPELL_DEATH_SPELL, true); // we cast the spell as triggered or the summon effect does not occur
}
void LeaveCombat()
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp b/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp
index f3384b7ec15..4dcd2618895 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp
+++ b/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp
@@ -144,8 +144,8 @@ public:
void JustDied(Unit* /*killer*/)
{
_JustDied();
-
Talk(SAY_DEATH);
+ DoCast(me, SPELL_DEATH_SPELL, true); // we cast the spell as triggered or the summon effect does not occur
}
private:
bool firstCoreEnergize;
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp
index f8839aa0028..b9799103214 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp
+++ b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp
@@ -50,6 +50,12 @@ enum Drakes
NPC_ETERNOS = 27659
};
+enum Says
+{
+ SAY_VAROS = 0,
+ SAY_UROM = 1
+};
+
class npc_oculus_drake : public CreatureScript
{
public:
@@ -174,7 +180,38 @@ public:
};
+class npc_image_belgaristrasz : public CreatureScript
+{
+public:
+ npc_image_belgaristrasz() : CreatureScript("npc_image_belgaristrasz") { }
+
+ struct npc_image_belgaristraszAI : public ScriptedAI
+ {
+ npc_image_belgaristraszAI(Creature* creature) : ScriptedAI(creature) {}
+
+ void IsSummonedBy(Unit* summoner)
+ {
+ if (summoner->GetEntry() == NPC_VAROS)
+ {
+ Talk(SAY_VAROS);
+ me->DespawnOrUnsummon(60000);
+ }
+ if (summoner->GetEntry() == NPC_UROM)
+ {
+ Talk(SAY_UROM);
+ me->DespawnOrUnsummon(60000);
+ }
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_image_belgaristraszAI(creature);
+ }
+};
+
void AddSC_oculus()
{
new npc_oculus_drake();
+ new npc_image_belgaristrasz();
}
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/oculus.h b/src/server/scripts/Northrend/Nexus/Oculus/oculus.h
index e04f2c8aab9..dab2821b5e5 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/oculus.h
+++ b/src/server/scripts/Northrend/Nexus/Oculus/oculus.h
@@ -71,6 +71,7 @@ enum OculusWorldStates
enum OculusSpells
{
- SPELL_CENTRIFUGE_SHIELD = 50053
+ SPELL_CENTRIFUGE_SHIELD = 50053,
+ SPELL_DEATH_SPELL = 50415
};
#endif
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp
index e7d8b070e53..13c174a9607 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp
@@ -526,7 +526,7 @@ class boss_freya : public CreatureScript
{
uint8 n = 0;
- // Handling recieved data
+ // Handling received data
for (uint8 i = 0; i < 5; ++i) // We have created "instances" for keeping informations about last 6 death lashers - needed because of respawning
{
deforestation[i][0] = deforestation[(i + 1)][0]; // Time
@@ -590,7 +590,7 @@ class boss_freya : public CreatureScript
waveCount++;
}
- void JustDied(Unit* who)
+ void JustDied(Unit* /*who*/)
{
//! Freya's chest is dynamically spawned on death by different spells.
const uint32 summonSpell[2][4] =
diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
index a690f3cbd9b..ec7f9a8e070 100644
--- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
+++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
@@ -364,8 +364,8 @@ static const Animation DemonTransformation[10]=
{0, SPELL_DEMON_TRANSFORM_3, 0, 0, 0, 8, true}
};
-#define EMOTE_SETS_GAZE_ON "sets its gaze on $N!"
-#define EMOTE_UNABLE_TO_SUMMON "is unable to summon Maiev Shadowsong and enter Phase 4. Resetting Encounter."
+#define EMOTE_SETS_GAZE_ON "%s sets its gaze on $N!"
+#define EMOTE_UNABLE_TO_SUMMON "%s is unable to summon Maiev Shadowsong and enter Phase 4. Resetting Encounter."
class mob_flame_of_azzinoth : public CreatureScript
{
diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp
index 4f837870612..5965c352975 100644
--- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp
+++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp
@@ -303,9 +303,7 @@ class boss_warchief_kargath_bladefist : public CreatureScript
if (resetcheck_timer <= diff)
{
- uint32 tempx, tempy;
- tempx = uint32(me->GetPositionX());
- tempy = uint32(me->GetPositionY());
+ uint32 tempx = uint32(me->GetPositionX());
if (tempx > 255 || tempx < 205)
{
EnterEvadeMode();
diff --git a/src/server/scripts/Outland/nagrand.cpp b/src/server/scripts/Outland/nagrand.cpp
index c556253ecf1..bae3aa65b98 100644
--- a/src/server/scripts/Outland/nagrand.cpp
+++ b/src/server/scripts/Outland/nagrand.cpp
@@ -573,7 +573,7 @@ public:
{
Talk(SAY_KUR_MORE);
- if (Creature* temp = me->SummonCreature(NPC_KUR_MURK_PUTRIFIER, kurenaiAmbushB[0], kurenaiAmbushB[1], kurenaiAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000))
+ if (me->SummonCreature(NPC_KUR_MURK_PUTRIFIER, kurenaiAmbushB[0], kurenaiAmbushB[1], kurenaiAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000))
Talk(SAY_KUR_MORE_TWO);
me->SummonCreature(NPC_KUR_MURK_PUTRIFIER, kurenaiAmbushB[0]-2.5f, kurenaiAmbushB[1]-2.5f, kurenaiAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp
index 3bb969977b6..44c3ab9bdc9 100644
--- a/src/server/scripts/World/go_scripts.cpp
+++ b/src/server/scripts/World/go_scripts.cpp
@@ -47,6 +47,7 @@ go_jotunheim_cage
go_table_theka
go_soulwell
go_bashir_crystalforge
+go_ethereal_teleport_pad
EndContentData */
#include "ScriptPCH.h"
@@ -922,6 +923,32 @@ public:
};
/*######
+## go_ethereal_teleport_pad
+######*/
+
+enum eEtherealTeleportPad
+{
+ NPC_IMAGE_WIND_TRADER = 20518,
+ ITEM_TELEPORTER_POWER_PACK = 28969,
+};
+
+class go_ethereal_teleport_pad : public GameObjectScript
+{
+public:
+ go_ethereal_teleport_pad() : GameObjectScript("go_ethereal_teleport_pad") { }
+
+ bool OnGossipHello(Player* player, GameObject* pGO)
+ {
+ if (!player->HasItemCount(ITEM_TELEPORTER_POWER_PACK, 1))
+ return false;
+
+ pGO->SummonCreature(NPC_IMAGE_WIND_TRADER, pGO->GetPositionX(), pGO->GetPositionY(), pGO->GetPositionZ(), pGO->GetAngle(player), TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000);
+
+ return true;
+ }
+};
+
+/*######
## go_soulwell
######*/
@@ -1282,6 +1309,7 @@ void AddSC_go_scripts()
new go_jotunheim_cage;
new go_table_theka;
new go_inconspicuous_landmark;
+ new go_ethereal_teleport_pad;
new go_soulwell;
new go_tadpole_cage;
new go_dragonflayer_cage;
diff --git a/src/server/shared/Database/MySQLConnection.cpp b/src/server/shared/Database/MySQLConnection.cpp
index 70a8beb3d70..9ce924127ba 100755
--- a/src/server/shared/Database/MySQLConnection.cpp
+++ b/src/server/shared/Database/MySQLConnection.cpp
@@ -527,7 +527,12 @@ bool MySQLConnection::_HandleMySQLErrno(uint32 errNo)
// Query related errors - skip query
case 1058: // "Column count doesn't match value count"
case 1062: // "Duplicate entry '%s' for key '%d'"
- case 1054: // "Unknown column '%s' in 'order clause'"
+ return false;
+
+ // Outdated table or database structure - terminate core
+ case 1054: // "Unknown column '%s' in '%s'"
+ case 1146: // "Table '%s' doesn't exist"
+ WPFatal(!errNo, "Your database structure is not up to date. Please make sure you've executed all queries in the sql/updates folders.");
return false;
default:
diff --git a/src/server/shared/Debugging/Errors.h b/src/server/shared/Debugging/Errors.h
index cfa1452864f..921363d6dc5 100755
--- a/src/server/shared/Debugging/Errors.h
+++ b/src/server/shared/Debugging/Errors.h
@@ -22,11 +22,12 @@
#include "Common.h"
#include "Log.h"
#include <ace/Stack_Trace.h>
+#include <ace/OS_NS_unistd.h>
#define WPAssert( assertion ) { if (!(assertion)) { ACE_Stack_Trace st; sLog->outError( "\n%s:%i in %s ASSERTION FAILED:\n %s\n%s\n", __FILE__, __LINE__, __FUNCTION__, #assertion, st.c_str()); assert( #assertion &&0 ); ((void(*)())NULL)();} }
#define WPError( assertion, errmsg ) if ( ! (assertion) ) { sLog->outError( "%\n%s:%i in %s ERROR:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg ); assert( false ); }
#define WPWarning( assertion, errmsg ) if ( ! (assertion) ) { sLog->outError( "\n%s:%i in %s WARNING:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg ); }
-#define WPFatal( assertion, errmsg ) if ( ! (assertion) ) { sLog->outError( "\n%s:%i in %s FATAL ERROR:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg ); assert( #assertion &&0 ); abort(); }
+#define WPFatal( assertion, errmsg ) if ( ! (assertion) ) { sLog->outError( "\n%s:%i in %s FATAL ERROR:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg ); ACE_OS::sleep(10); assert( #assertion &&0 ); abort(); }
#define ASSERT WPAssert
#endif
diff --git a/src/server/worldserver/CommandLine/CliRunnable.cpp b/src/server/worldserver/CommandLine/CliRunnable.cpp
index 564f6028eca..61352521d9f 100755
--- a/src/server/worldserver/CommandLine/CliRunnable.cpp
+++ b/src/server/worldserver/CommandLine/CliRunnable.cpp
@@ -104,7 +104,7 @@ void utf8print(void* /*arg*/, const char* str)
printf(temp_buf);
#else
{
- printf(str);
+ printf("%s", str);
fflush(stdout);
}
#endif
diff --git a/src/server/worldserver/RemoteAccess/RASocket.cpp b/src/server/worldserver/RemoteAccess/RASocket.cpp
index 71d4d1df035..82238ee54bc 100755
--- a/src/server/worldserver/RemoteAccess/RASocket.cpp
+++ b/src/server/worldserver/RemoteAccess/RASocket.cpp
@@ -286,7 +286,7 @@ int RASocket::subnegotiate()
if (n >= 1024)
{
- sLog->outRemote("RASocket::subnegotiate: allocated buffer 1024 bytes was too small for negotiation packet, size: %u", n);
+ sLog->outRemote("RASocket::subnegotiate: allocated buffer 1024 bytes was too small for negotiation packet, size: %u", uint32(n));
return -1;
}
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index a8c0d91b2e6..1e37f50aa63 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -1744,7 +1744,8 @@ Channel.RestrictedLfg = 1
#
# Channel.SilentlyGMJoin
-# Description: Silently join GM characters to channels
+# Description: Silently join GM characters to channels. If set to 1, channel kick and ban
+# commands issued by a GM will not be broadcasted.
# Default: 0 - (Disabled, Join with announcement)
# 1 - (Enabled, Join without announcement)