Core/Garrisons: Implemented spawning "Finalize Garrison Plot" gameobjects when building under construction is ready

This commit is contained in:
Shauren
2015-06-23 00:05:51 +02:00
parent 812fa65c61
commit 73384e56d4
4 changed files with 178 additions and 7 deletions

View File

@@ -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);

View File

@@ -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)

View File

@@ -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));
}

View File

@@ -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;