diff options
-rw-r--r-- | sql/updates/world/2015_06_23_00_world.sql | 38 | ||||
-rw-r--r-- | src/server/game/Garrison/Garrison.cpp | 35 | ||||
-rw-r--r-- | src/server/game/Garrison/GarrisonMgr.cpp | 99 | ||||
-rw-r--r-- | src/server/game/Garrison/GarrisonMgr.h | 13 |
4 files changed, 178 insertions, 7 deletions
diff --git a/sql/updates/world/2015_06_23_00_world.sql b/sql/updates/world/2015_06_23_00_world.sql new file mode 100644 index 00000000000..45e0b362ef1 --- /dev/null +++ b/sql/updates/world/2015_06_23_00_world.sql @@ -0,0 +1,38 @@ +-- +-- Table structure for table `garrison_plot_finalize_info` +-- + +DROP TABLE IF EXISTS `garrison_plot_finalize_info`; +CREATE TABLE `garrison_plot_finalize_info` ( + `garrPlotInstanceId` int(10) unsigned NOT NULL, + `hordeGameObjectId` int(10) unsigned NOT NULL DEFAULT '0', + `hordeX` float NOT NULL DEFAULT '0', + `hordeY` float NOT NULL DEFAULT '0', + `hordeZ` float NOT NULL DEFAULT '0', + `hordeO` float NOT NULL DEFAULT '0', + `hordeAnimKitId` smallint(5) unsigned NOT NULL DEFAULT '0', + `allianceGameObjectId` int(10) unsigned NOT NULL DEFAULT '0', + `allianceX` float NOT NULL DEFAULT '0', + `allianceY` float NOT NULL DEFAULT '0', + `allianceZ` float NOT NULL DEFAULT '0', + `allianceO` float NOT NULL DEFAULT '0', + `allianceAnimKitId` smallint(5) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`garrPlotInstanceId`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `garrison_plot_finalize_info` +-- + +INSERT INTO `garrison_plot_finalize_info` (`garrPlotInstanceId`, `hordeGameObjectId`, `hordeX`, `hordeY`, `hordeZ`, `hordeO`, `hordeAnimKitId`, `allianceGameObjectId`, `allianceX`, `allianceY`, `allianceZ`, `allianceO`, `allianceAnimKitId`) VALUES +(18,233248,5642.37,4514.43,119.27,1.88088,1696,0,0,0,0,0,0), +(19,231964,5652.18,4539.69,119.27,3.74629,1696,0,0,0,0,0,0), +(20,236186,5623.58,4516.67,119.27,0.97567,1696,0,0,0,0,0,0), +(22,233249,5547.58,4522.44,131.393,0.0108777,1696,0,0,0,0,0,0), +(23,231217,5589.08,4480.11,130.349,1.05262,1696,0,0,0,0,0,0), +(24,236187,5643.26,4463.4,130.525,1.9379,1696,0,0,0,0,0,0), +(25,236188,5679.95,4486.13,131.107,2.4223,1696,0,0,0,0,0,0), +(59,236176,5475.8,4447.15,144.519,0.955649,1696,0,0,0,0,0,0), +(63,236177,5424.65,4567.79,137.431,0.112897,1696,0,0,0,0,0,0), +(67,236185,5476.71,4617.02,134.45,5.02338,1696,0,0,0,0,0,0), +(81,236175,5621.77,4652.88,142.448,4.39222,1696,0,0,0,0,0,0); diff --git a/src/server/game/Garrison/Garrison.cpp b/src/server/game/Garrison/Garrison.cpp index 12c924c1f30..99db2336566 100644 --- a/src/server/game/Garrison/Garrison.cpp +++ b/src/server/game/Garrison/Garrison.cpp @@ -649,16 +649,39 @@ GameObject* Garrison::Plot::CreateGameObject(Map* map, GarrisonFactionIndex fact } Position const& pos = PacketInfo.PlotPos; - GameObject* go = new GameObject(); - if (!go->Create(map->GenerateLowGuid<HighGuid::GameObject>(), entry, map, 0, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), - 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_ACTIVE)) + GameObject* building = new GameObject(); + if (!building->Create(map->GenerateLowGuid<HighGuid::GameObject>(), entry, map, 0, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), + 0.0f, 0.0f, 0.0f, 0.0f, 255, GO_STATE_READY)) { - delete go; + delete building; return nullptr; } - BuildingInfo.Guid = go->GetGUID(); - return go; + if (BuildingInfo.CanActivate() && BuildingInfo.PacketInfo && !BuildingInfo.PacketInfo->Active) + { + if (FinalizeGarrisonPlotGOInfo const* finalizeInfo = sGarrisonMgr.GetPlotFinalizeGOInfo(PacketInfo.GarrPlotInstanceID)) + { + Position const& pos2 = finalizeInfo->FactionInfo[faction].Pos; + GameObject* finalizer = new GameObject(); + if (finalizer->Create(map->GenerateLowGuid<HighGuid::GameObject>(), finalizeInfo->FactionInfo[faction].GameObjectId, map, 0, pos2.GetPositionX(), pos2.GetPositionY(), + pos2.GetPositionZ(), pos2.GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 255, GO_STATE_READY)) + { + // set some spell id to make the object delete itself after use + finalizer->SetSpellId(finalizer->GetGOInfo()->goober.spell); + finalizer->SetRespawnTime(0); + + if (uint16 animKit = finalizeInfo->FactionInfo[faction].AnimKitId) + finalizer->SetAIAnimKitId(animKit); + + map->AddToMap(finalizer); + } + else + delete finalizer; + } + } + + BuildingInfo.Guid = building->GetGUID(); + return building; } void Garrison::Plot::DeleteGameObject(Map* map) diff --git a/src/server/game/Garrison/GarrisonMgr.cpp b/src/server/game/Garrison/GarrisonMgr.cpp index f95acef952c..7da1c929c43 100644 --- a/src/server/game/Garrison/GarrisonMgr.cpp +++ b/src/server/game/Garrison/GarrisonMgr.cpp @@ -58,6 +58,7 @@ void GarrisonMgr::Initialize() } InitializeDbIdSequences(); + LoadPlotFinalizeGOInfo(); LoadFollowerClassSpecAbilities(); } @@ -121,6 +122,15 @@ GarrBuildingEntry const* GarrisonMgr::GetPreviousLevelBuilding(uint32 buildingTy return nullptr; } +FinalizeGarrisonPlotGOInfo const* GarrisonMgr::GetPlotFinalizeGOInfo(uint32 garrPlotInstanceID) const +{ + auto itr = _finalizePlotGOInfo.find(garrPlotInstanceID); + if (itr != _finalizePlotGOInfo.end()) + return &itr->second; + + return nullptr; +} + uint64 GarrisonMgr::GenerateFollowerDbId() { if (_followerDbIdGenerator >= std::numeric_limits<uint64>::max()) @@ -312,6 +322,92 @@ void GarrisonMgr::InitializeDbIdSequences() _followerDbIdGenerator = (*result)[0].GetUInt64() + 1; } +void GarrisonMgr::LoadPlotFinalizeGOInfo() +{ + // 0 1 2 3 4 5 6 + QueryResult result = WorldDatabase.Query("SELECT garrPlotInstanceId, hordeGameObjectId, hordeX, hordeY, hordeZ, hordeO, hordeAnimKitId, " + // 7 8 9 10 11 12 + "allianceGameObjectId, allianceX, allianceY, allianceZ, allianceO, allianceAnimKitId FROM garrison_plot_finalize_info"); + if (!result) + { + TC_LOG_INFO("server.loading", ">> Loaded 0 garrison follower class spec abilities. DB table `garrison_plot_finalize_info` is empty."); + return; + } + + uint32 msTime = getMSTime(); + do + { + Field* fields = result->Fetch(); + uint32 garrPlotInstanceId = fields[0].GetUInt32(); + uint32 hordeGameObjectId = fields[1].GetUInt32(); + uint32 allianceGameObjectId = fields[7].GetUInt32(); + uint16 hordeAnimKitId = fields[6].GetUInt16(); + uint16 allianceAnimKitId = fields[12].GetUInt16(); + + if (!sGarrPlotInstanceStore.LookupEntry(garrPlotInstanceId)) + { + TC_LOG_ERROR("sql.sql", "Non-existing GarrPlotInstance.db2 entry %u was referenced in `garrison_plot_finalize_info`.", garrPlotInstanceId); + continue; + } + + GameObjectTemplate const* goTemplate = sObjectMgr->GetGameObjectTemplate(hordeGameObjectId); + if (!goTemplate) + { + TC_LOG_ERROR("sql.sql", "Non-existing gameobject_template entry %u was referenced in `garrison_plot_finalize_info`.`hordeGameObjectId` for garrPlotInstanceId %u.", + hordeGameObjectId, garrPlotInstanceId); + continue; + } + + if (goTemplate->type != GAMEOBJECT_TYPE_GOOBER) + { + TC_LOG_ERROR("sql.sql", "Invalid gameobject type %u (entry %u) was referenced in `garrison_plot_finalize_info`.`hordeGameObjectId` for garrPlotInstanceId %u.", + goTemplate->type, hordeGameObjectId, garrPlotInstanceId); + continue; + } + + goTemplate = sObjectMgr->GetGameObjectTemplate(allianceGameObjectId); + if (!goTemplate) + { + TC_LOG_ERROR("sql.sql", "Non-existing gameobject_template entry %u was referenced in `garrison_plot_finalize_info`.`allianceGameObjectId` for garrPlotInstanceId %u.", + allianceGameObjectId, garrPlotInstanceId); + continue; + } + + if (goTemplate->type != GAMEOBJECT_TYPE_GOOBER) + { + TC_LOG_ERROR("sql.sql", "Invalid gameobject type %u (entry %u) was referenced in `garrison_plot_finalize_info`.`allianceGameObjectId` for garrPlotInstanceId %u.", + goTemplate->type, allianceGameObjectId, garrPlotInstanceId); + continue; + } + + if (hordeAnimKitId && !sAnimKitStore.LookupEntry(hordeAnimKitId)) + { + TC_LOG_ERROR("sql.sql", "Non-existing AnimKit.dbc entry %u was referenced in `garrison_plot_finalize_info`.`hordeAnimKitId` for garrPlotInstanceId %u.", + hordeAnimKitId, garrPlotInstanceId); + continue; + } + + if (allianceAnimKitId && !sAnimKitStore.LookupEntry(allianceAnimKitId)) + { + TC_LOG_ERROR("sql.sql", "Non-existing AnimKit.dbc entry %u was referenced in `garrison_plot_finalize_info`.`allianceAnimKitId` for garrPlotInstanceId %u.", + allianceAnimKitId, garrPlotInstanceId); + continue; + } + + FinalizeGarrisonPlotGOInfo& info = _finalizePlotGOInfo[garrPlotInstanceId]; + info.FactionInfo[GARRISON_FACTION_INDEX_HORDE].GameObjectId = hordeGameObjectId; + info.FactionInfo[GARRISON_FACTION_INDEX_HORDE].Pos.Relocate(fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat(), fields[5].GetFloat()); + info.FactionInfo[GARRISON_FACTION_INDEX_HORDE].AnimKitId = hordeAnimKitId; + + info.FactionInfo[GARRISON_FACTION_INDEX_ALLIANCE].GameObjectId = allianceGameObjectId; + info.FactionInfo[GARRISON_FACTION_INDEX_ALLIANCE].Pos.Relocate(fields[8].GetFloat(), fields[9].GetFloat(), fields[10].GetFloat(), fields[11].GetFloat()); + info.FactionInfo[GARRISON_FACTION_INDEX_ALLIANCE].AnimKitId = allianceAnimKitId; + + } while (result->NextRow()); + + TC_LOG_INFO("server.loading", ">> Loaded %u garrison plot finalize entries in %u.", uint32(_finalizePlotGOInfo.size()), GetMSTimeDiffToNow(msTime)); +} + void GarrisonMgr::LoadFollowerClassSpecAbilities() { QueryResult result = WorldDatabase.Query("SELECT classSpecId, abilityId FROM garrison_follower_class_spec_abilities"); @@ -321,6 +417,7 @@ void GarrisonMgr::LoadFollowerClassSpecAbilities() return; } + uint32 msTime = getMSTime(); uint32 count = 0; do { @@ -349,5 +446,5 @@ void GarrisonMgr::LoadFollowerClassSpecAbilities() for (auto& pair : _garrisonFollowerClassSpecAbilities) pair.second.sort(); - TC_LOG_INFO("server.loading", ">> Loaded %u garrison follower class spec abilities.", count); + TC_LOG_INFO("server.loading", ">> Loaded %u garrison follower class spec abilities in %u.", count, GetMSTimeDiffToNow(msTime)); } diff --git a/src/server/game/Garrison/GarrisonMgr.h b/src/server/game/Garrison/GarrisonMgr.h index 63810e3c3ab..26fc6867f0c 100644 --- a/src/server/game/Garrison/GarrisonMgr.h +++ b/src/server/game/Garrison/GarrisonMgr.h @@ -21,6 +21,16 @@ #include "DB2Stores.h" #include <unordered_set> +struct FinalizeGarrisonPlotGOInfo +{ + struct + { + uint32 GameObjectId; + Position Pos; + uint16 AnimKitId; + } FactionInfo[2]; +}; + struct GarrAbilities { std::unordered_set<GarrAbilityEntry const*> Counters; @@ -44,12 +54,14 @@ public: bool IsPlotMatchingBuilding(uint32 garrPlotId, uint32 garrBuildingId) const; uint32 GetGarrBuildingPlotInst(uint32 garrBuildingId, uint32 garrSiteLevelPlotInstId) const; GarrBuildingEntry const* GetPreviousLevelBuilding(uint32 buildingType, uint32 currentLevel) const; + FinalizeGarrisonPlotGOInfo const* GetPlotFinalizeGOInfo(uint32 garrPlotInstanceID) const; uint64 GenerateFollowerDbId(); std::list<GarrAbilityEntry const*> RollFollowerAbilities(GarrFollowerEntry const* follower, uint32 quality, uint32 faction, bool initial) const; std::list<GarrAbilityEntry const*> GetClassSpecAbilities(GarrFollowerEntry const* follower, uint32 faction) const; private: void InitializeDbIdSequences(); + void LoadPlotFinalizeGOInfo(); void LoadFollowerClassSpecAbilities(); std::unordered_map<uint32 /*garrSiteId*/, std::vector<GarrSiteLevelPlotInstEntry const*>> _garrisonPlotInstBySiteLevel; @@ -57,6 +69,7 @@ private: std::unordered_map<uint32 /*garrPlotId*/, std::unordered_set<uint32/*garrBuildingId*/>> _garrisonBuildingsByPlot; std::unordered_map<uint64 /*garrBuildingId | garrSiteLevelPlotInstId << 32*/, uint32 /*garrBuildingPlotInstId*/> _garrisonBuildingPlotInstances; std::unordered_map<uint32 /*buildingType*/, std::vector<GarrBuildingEntry const*>> _garrisonBuildingsByType; + std::unordered_map<uint32 /*garrPlotInstanceId*/, FinalizeGarrisonPlotGOInfo> _finalizePlotGOInfo; std::unordered_map<uint32 /*garrFollowerId*/, GarrAbilities> _garrisonFollowerAbilities[2]; std::unordered_map<uint32 /*classSpecId*/, std::list<GarrAbilityEntry const*>> _garrisonFollowerClassSpecAbilities; std::set<GarrAbilityEntry const*> _garrisonFollowerRandomTraits; |