diff options
63 files changed, 591 insertions, 345 deletions
diff --git a/cmake/macros/FindMySQL.cmake b/cmake/macros/FindMySQL.cmake index 5c05fdb884d..d42dc5caf74 100644 --- a/cmake/macros/FindMySQL.cmake +++ b/cmake/macros/FindMySQL.cmake @@ -75,13 +75,16 @@ find_path(MYSQL_INCLUDE_DIR "C:/Program Files/MySQL/include" "C:/Program Files/MySQL/MySQL Server 5.0/include" "C:/Program Files/MySQL/MySQL Server 5.1/include" + "C:/Program Files/MySQL/MySQL Server 5.6/include" "C:/MySQL/include" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.0;Location]/include" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.1;Location]/include" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.5;Location]/include" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.6;Location]/include" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.0;Location]/include" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.1;Location]/include" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.5;Location]/include" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.6;Location]/include" "$ENV{ProgramFiles}/MySQL/*/include" "$ENV{SystemDrive}/MySQL/*/include" "c:/msys/local/include" @@ -115,13 +118,17 @@ if( WIN32 ) "C:/Program Files/MySQL/lib" "C:/Program Files/MySQL/MySQL Server 5.0/lib/opt" "C:/Program Files/MySQL/MySQL Server 5.1/lib/opt" + "C:/Program Files/MySQL/MySQL Server 5.6/lib/opt" "C:/MySQL/lib/debug" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.0;Location]/lib/opt" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.1;Location]/lib/opt" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.6;Location]/lib/opt" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.5;Location]/lib" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.6;Location]/lib" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.0;Location]/lib/opt" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.1;Location]/lib/opt" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.5;Location]/lib" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.6;Location]/lib" "$ENV{ProgramFiles}/MySQL/*/lib/opt" "$ENV{SystemDrive}/MySQL/*/lib/opt" "c:/msys/local/include" diff --git a/sql/updates/world/2011_12_12_00_world_spell_bonus_data.sql b/sql/updates/world/2011_12_12_00_world_spell_bonus_data.sql new file mode 100644 index 00000000000..cb728e70dd9 --- /dev/null +++ b/sql/updates/world/2011_12_12_00_world_spell_bonus_data.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_bonus_data` WHERE `entry` IN (52042,5672); +INSERT INTO `spell_bonus_data` (`entry`,`direct_bonus`,`dot_bonus`,`ap_bonus`,`ap_dot_bonus`,`comments`) VALUES +(5672,0.0827,-1,-1,-1, 'Shaman - Healing Stream Totem Rank 1'); diff --git a/sql/updates/world/2011_12_13_00_world_misc.sql b/sql/updates/world/2011_12_13_00_world_misc.sql new file mode 100644 index 00000000000..48848c368f1 --- /dev/null +++ b/sql/updates/world/2011_12_13_00_world_misc.sql @@ -0,0 +1,6 @@ +DELETE FROM `creature_text` WHERE `entry`=28012; +INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES +(28012,0,0,'The trickster Mage-Lord Urom protects the third ring. He will appear alone and defenseless, but do not be fooled by appearences! Urom is a powerful conjurer who commands a menagerie of Phantasmal creatures. Seek him out above.',12,0,0,0,0,0,''), +(28012,1,1,'Your greatest challenge lies ahead. Ley-Guardian Eregos is a Blue dragon of immense power. You will find him flying above the uppermost ring.',12,0,0,0,0,0,''); + +UPDATE `creature_template` SET `ScriptName`='npc_image_belgaristrasz' WHERE `entry`=28012;
\ No newline at end of file diff --git a/sql/updates/world/2011_12_13_01_world_achievement_criteria_data.sql b/sql/updates/world/2011_12_13_01_world_achievement_criteria_data.sql new file mode 100644 index 00000000000..9f3f22d7792 --- /dev/null +++ b/sql/updates/world/2011_12_13_01_world_achievement_criteria_data.sql @@ -0,0 +1,12 @@ +-- Experienced Drake Rider Achiev + +DELETE FROM `disables` WHERE `entry` IN (7177,7178,7179); + +DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (7177,7178,7179); +INSERT INTO `achievement_criteria_data` (`criteria_id`,`type`,`value1`,`value2`,`ScriptName`) VALUES +(7177,5,49460,1,''), -- Amber Drake +(7177,12,1,0, ''), -- hc mode only +(7178,5,49346,1,''), -- Emerald Drake +(7178,12,1,0, ''), -- hc mode only +(7179,5,49464,1,''), -- Ruby Drake +(7179,12,1,0, ''); -- hc mode only
\ No newline at end of file diff --git a/sql/updates/world/2011_12_13_02_creature_template_addon.sql b/sql/updates/world/2011_12_13_02_creature_template_addon.sql new file mode 100644 index 00000000000..2e7280927bf --- /dev/null +++ b/sql/updates/world/2011_12_13_02_creature_template_addon.sql @@ -0,0 +1,2 @@ +-- Fix speed of oculus drakes +UPDATE `creature_template_addon` SET `auras`='50325' WHERE `entry` IN (27755,27692,27756);
\ No newline at end of file diff --git a/sql/updates/world/2011_12_14_00_world_command.sql b/sql/updates/world/2011_12_14_00_world_command.sql new file mode 100644 index 00000000000..e871a82d89d --- /dev/null +++ b/sql/updates/world/2011_12_14_00_world_command.sql @@ -0,0 +1,4 @@ +DELETE FROM `trinity_string` WHERE `entry` IN(19,20); # unused entries +INSERT INTO `trinity_string` (`entry`,`content_default`) VALUES +(19,'Update time diff: %u.'), +(20,'Time left until shutdown/restart: %s'); diff --git a/sql/updates/world/2011_12_14_01_gameobject_template.sql b/sql/updates/world/2011_12_14_01_gameobject_template.sql new file mode 100644 index 00000000000..12729afd6b8 --- /dev/null +++ b/sql/updates/world/2011_12_14_01_gameobject_template.sql @@ -0,0 +1 @@ +UPDATE `gameobject_template` SET `scriptName` = 'go_ethereal_teleport_pad' WHERE `entry` = 184073; -- Update Ethereal Teleport Pad scriptname
\ No newline at end of file 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 fde660e483e..7dd793a302b 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -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 9755055cd6e..dded086b584 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -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 e80da52ccd3..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; @@ -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 a0463227931..c43bfb2ca8b 100755 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -451,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) @@ -1766,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)) @@ -2000,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); @@ -2115,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) @@ -2381,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/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index c434105610c..bd85968ca9a 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -13300,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++); @@ -13319,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) @@ -18121,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); @@ -18897,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); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 659ebef92af..232be095e2b 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 @@ -8920,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: { 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.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 75573367241..020f7bd56a9 100755 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -3818,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? } @@ -8040,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/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/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 f9b79b4f195..04a5b102a6d 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -1528,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) @@ -1579,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) 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/Server/Protocol/Handlers/CharacterHandler.cpp b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp index aea6466924b..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)) 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/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index b690a811fbb..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)) diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 034e38916ef..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; } 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 877971aa502..13c174a9607 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp @@ -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/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) |
