From 55914733a0af78db8b363591a4b824f3ae586e1a Mon Sep 17 00:00:00 2001 From: Aokromes Date: Sat, 25 Mar 2017 10:27:51 +0100 Subject: [PATCH] Core/Scripts: Add support for spawn specific C++ scripts By Krudor. --- .../world/4.3.4/2017_03_25_00_world.sql | 4 +++ .../game/Entities/Creature/Creature.cpp | 5 +++- src/server/game/Entities/Creature/Creature.h | 1 + .../game/Entities/GameObject/GameObject.cpp | 10 ++++++- .../game/Entities/GameObject/GameObject.h | 3 +- src/server/game/Globals/ObjectMgr.cpp | 29 ++++++++++++++----- src/server/game/Handlers/MiscHandler.cpp | 6 ++-- src/server/game/Scripting/ScriptMgr.cpp | 2 +- 8 files changed, 46 insertions(+), 14 deletions(-) create mode 100644 sql/updates/world/4.3.4/2017_03_25_00_world.sql diff --git a/sql/updates/world/4.3.4/2017_03_25_00_world.sql b/sql/updates/world/4.3.4/2017_03_25_00_world.sql new file mode 100644 index 00000000000..e872b06b9a8 --- /dev/null +++ b/sql/updates/world/4.3.4/2017_03_25_00_world.sql @@ -0,0 +1,4 @@ +-- +ALTER TABLE `creature` ADD COLUMN `ScriptName` CHAR(64) NULL DEFAULT '' AFTER `dynamicflags`; +ALTER TABLE `gameobject` ADD COLUMN `ScriptName` CHAR(64) NULL DEFAULT '' AFTER `state`; +-- diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 0121f2b594d..2c79ef9b70f 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -927,7 +927,7 @@ bool Creature::Create(ObjectGuid::LowType guidlow, Map* map, uint32 /*phaseMask* Relocate(x, y, z, ang); } - LastUsedScriptID = GetCreatureTemplate()->ScriptID; + LastUsedScriptID = GetScriptId(); /// @todo Replace with spell, handle from DB if (IsSpiritHealer() || IsSpiritGuide()) @@ -2483,6 +2483,9 @@ std::string Creature::GetScriptName() const uint32 Creature::GetScriptId() const { + if (CreatureData const* creatureData = GetCreatureData()) + return creatureData->ScriptId; + return sObjectMgr->GetCreatureTemplate(GetEntry())->ScriptID; } diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 85cbe084f1a..f0509414cae 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -282,6 +282,7 @@ struct CreatureData uint32 dynamicflags; uint32 phaseid; uint32 phaseGroup; + uint32 ScriptId; bool dbData; }; diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index e6da8ea3289..b9b76291887 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -1,4 +1,4 @@ -/* +// overwrite WorldObject function for proper name localization/* * Copyright (C) 2008-2017 TrinityCore * Copyright (C) 2005-2009 MaNGOS * @@ -1945,6 +1945,14 @@ void GameObject::EventInform(uint32 eventId, WorldObject* invoker /*= nullptr*/) bgMap->GetBG()->ProcessEvent(this, eventId, invoker); } +uint32 GameObject::GetScriptId() const +{ + if (GameObjectData const* gameObjectData = GetGOData()) + return gameObjectData->ScriptId; + + return GetGOInfo()->ScriptId; +} + // overwrite WorldObject function for proper name localization std::string const & GameObject::GetNameForLocaleIdx(LocaleConstant loc_idx) const { diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index f64bb6f7e12..a467b5a82e6 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -660,6 +660,7 @@ struct GameObjectData uint8 artKit; uint32 phaseid; uint32 phaseGroup; + uint32 ScriptId; bool dbData; }; @@ -879,7 +880,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject void EventInform(uint32 eventId, WorldObject* invoker = NULL); - virtual uint32 GetScriptId() const { return GetGOInfo()->ScriptId; } + virtual uint32 GetScriptId() const; GameObjectAI* AI() const { return m_AI; } std::string GetAIName() const; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 2672d60d89c..b75711ff95a 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -1803,8 +1803,10 @@ void ObjectMgr::LoadCreatures() // 0 1 2 3 4 5 6 7 8 9 10 QueryResult result = WorldDatabase.Query("SELECT creature.guid, id, map, modelid, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, " - // 11 12 13 14 15 16 17 18 19 20 21 22 23 - "currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.dynamicflags, creature.phaseid, creature.phasegroup " + // 11 12 13 14 15 16 17 18 19 20 21 22 + "currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.dynamicflags, creature.phaseid, " + // 23 24 + "creature.phasegroup, creature.ScriptName " "FROM creature " "LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid " "LEFT OUTER JOIN pool_creature ON creature.guid = pool_creature.guid"); @@ -1861,8 +1863,11 @@ void ObjectMgr::LoadCreatures() data.npcflag = fields[19].GetUInt32(); data.unit_flags = fields[20].GetUInt32(); data.dynamicflags = fields[21].GetUInt32(); - data.phaseid = fields[22].GetUInt32(); - data.phaseGroup = fields[23].GetUInt32(); + data.phaseid = fields[22].GetUInt32(); + data.phaseGroup = fields[23].GetUInt32(); + data.ScriptId = GetScriptId(fields[23].GetString()); + if (!data.ScriptId) + data.ScriptId = cInfo->ScriptID; MapEntry const* mapEntry = sMapStore.LookupEntry(data.mapid); if (!mapEntry) @@ -2111,8 +2116,10 @@ void ObjectMgr::LoadGameobjects() // 0 1 2 3 4 5 6 QueryResult result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, " - // 7 8 9 10 11 12 13 14 15 16 17 18 19 - "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, phaseMask, eventEntry, pool_entry, phaseid, phasegroup " + // 7 8 9 10 11 12 13 14 15 16 17 + "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, phaseMask, eventEntry, pool_entry, " + // 18 19 + "phaseid, phasegroup, ScriptName " "FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid " "LEFT OUTER JOIN pool_gameobject ON gameobject.guid = pool_gameobject.guid"); @@ -2228,6 +2235,10 @@ void ObjectMgr::LoadGameobjects() data.phaseGroup = 0; } + data.ScriptId = GetScriptId(fields[19].GetString()); + if (!data.ScriptId) + data.ScriptId = gInfo->ScriptId; + if (std::abs(data.orientation) > 2 * float(M_PI)) { TC_LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: %u Entry: %u) with abs(`orientation`) > 2*PI (orientation is expressed in radians), normalized.", guid, data.id); @@ -8822,11 +8833,15 @@ void ObjectMgr::LoadScriptNames() "UNION " "SELECT DISTINCT(ScriptName) FROM battleground_template WHERE ScriptName <> '' " "UNION " + "SELECT DISTINCT(ScriptName) FROM creature WHERE ScriptName <> '' " + "UNION " "SELECT DISTINCT(ScriptName) FROM creature_template WHERE ScriptName <> '' " "UNION " + "SELECT DISTINCT(ScriptName) FROM gameobject WHERE ScriptName <> '' " + "UNION " "SELECT DISTINCT(ScriptName) FROM gameobject_template WHERE ScriptName <> '' " "UNION " - "SELECT DISTINCT(ScriptName) FROM item_script_names WHERE ScriptName <> '' " + "SELECT DISTINCT(ScriptName) FROM item_script_names WHERE ScriptName <> '' " "UNION " "SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' " "UNION " diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 37960f83892..9b9af1d4506 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -132,13 +132,13 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket& recvData) if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); - if ((unit && unit->GetCreatureTemplate()->ScriptID != unit->LastUsedScriptID) || (go && go->GetGOInfo()->ScriptId != go->LastUsedScriptID)) + if ((unit && unit->GetScriptId() != unit->LastUsedScriptID) || (go && go->GetScriptId() != go->LastUsedScriptID)) { TC_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - Script reloaded while in use, ignoring and set new scipt id"); if (unit) - unit->LastUsedScriptID = unit->GetCreatureTemplate()->ScriptID; + unit->LastUsedScriptID = unit->GetScriptId(); if (go) - go->LastUsedScriptID = go->GetGOInfo()->ScriptId; + go->LastUsedScriptID = go->GetScriptId(); _player->PlayerTalkClass->SendCloseGossip(); return; } diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index c332087470c..1dc250111c9 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -1645,7 +1645,7 @@ bool ScriptMgr::CanSpawn(ObjectGuid::LowType spawnId, uint32 entry, CreatureTemp CreatureTemplate const* baseTemplate = sObjectMgr->GetCreatureTemplate(entry); if (!baseTemplate) baseTemplate = actTemplate; - GET_SCRIPT_RET(CreatureScript, baseTemplate->ScriptID, tmpscript, true); + GET_SCRIPT_RET(CreatureScript, (cData ? cData->ScriptId : baseTemplate->ScriptID), tmpscript, true); return tmpscript->CanSpawn(spawnId, entry, baseTemplate, actTemplate, cData, map); }