aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Garrison/Garrison.cpp
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2015-05-11 18:23:43 +0200
committerShauren <shauren.trinity@gmail.com>2015-05-11 18:23:43 +0200
commit9d4c568596fbfe911f0edb0a92d75b175ad900af (patch)
tree3929f57e05516380953a25829c30376ec39291a4 /src/server/game/Garrison/Garrison.cpp
parent3c79914e7b01a44bd5b34f7728e5cb575fa48723 (diff)
Core/Garrisons: Added more building checks and implemented canceling building construction
Diffstat (limited to 'src/server/game/Garrison/Garrison.cpp')
-rw-r--r--src/server/game/Garrison/Garrison.cpp175
1 files changed, 154 insertions, 21 deletions
diff --git a/src/server/game/Garrison/Garrison.cpp b/src/server/game/Garrison/Garrison.cpp
index 15387d9a9b6..35c07e1590c 100644
--- a/src/server/game/Garrison/Garrison.cpp
+++ b/src/server/game/Garrison/Garrison.cpp
@@ -210,6 +210,15 @@ Garrison::Plot* Garrison::GetPlot(uint32 garrPlotInstanceId)
return nullptr;
}
+Garrison::Plot const* Garrison::GetPlot(uint32 garrPlotInstanceId) const
+{
+ auto itr = _plots.find(garrPlotInstanceId);
+ if (itr != _plots.end())
+ return &itr->second;
+
+ return nullptr;
+}
+
void Garrison::LearnBlueprint(uint32 garrBuildingId)
{
WorldPackets::Garrison::GarrisonLearnBlueprintResult learnBlueprintResult;
@@ -253,33 +262,88 @@ void Garrison::PlaceBuilding(uint32 garrPlotInstanceId, uint32 garrBuildingId)
placeBuildingResult.BuildingInfo.TimeBuilt = time(nullptr);
Plot* plot = GetPlot(garrPlotInstanceId);
+ uint32 oldBuildingId = 0;
+ Map* map = FindMap();
+ GarrBuildingEntry const* building = sGarrBuildingStore.AssertEntry(garrBuildingId);
+ if (map)
+ plot->DeleteGameObject(map);
- if (Map* map = FindMap())
+ if (plot->BuildingInfo.PacketInfo)
{
- if (!plot->BuildingInfo.Guid.IsEmpty())
- {
- if (GameObject* oldBuilding = map->GetGameObject(plot->BuildingInfo.Guid))
- oldBuilding->AddObjectToRemoveList();
-
- plot->BuildingInfo.Guid.Clear();
- }
+ oldBuildingId = plot->BuildingInfo.PacketInfo->GarrBuildingID;
+ if (sGarrBuildingStore.AssertEntry(oldBuildingId)->Type != building->Type)
+ plot->ClearBuildingInfo(_owner);
+ }
- plot->BuildingInfo.PacketInfo = placeBuildingResult.BuildingInfo;
+ plot->SetBuildingInfo(placeBuildingResult.BuildingInfo, _owner);
+ if (map)
if (GameObject* go = plot->CreateGameObject(map, GetFaction()))
- {
map->AddToMap(go);
- GarrBuildingEntry const* building = sGarrBuildingStore.AssertEntry(garrBuildingId);
- _owner->ModifyCurrency(building->CostCurrencyID, -building->CostCurrencyAmount, false, true);
- _owner->ModifyMoney(-building->CostMoney, false);
- }
- else
- plot->BuildingInfo.PacketInfo = boost::none;
+
+ _owner->ModifyCurrency(building->CostCurrencyID, -building->CostCurrencyAmount, false, true);
+ _owner->ModifyMoney(-building->CostMoney * GOLD, false);
+
+ if (oldBuildingId)
+ {
+ WorldPackets::Garrison::GarrisonBuildingRemoved buildingRemoved;
+ buildingRemoved.Result = GARRISON_SUCCESS;
+ buildingRemoved.GarrPlotInstanceID = garrPlotInstanceId;
+ buildingRemoved.GarrBuildingID = oldBuildingId;
+ _owner->SendDirectMessage(buildingRemoved.Write());
}
}
_owner->SendDirectMessage(placeBuildingResult.Write());
}
+void Garrison::CancelBuildingConstruction(uint32 garrPlotInstanceId)
+{
+ WorldPackets::Garrison::GarrisonBuildingRemoved buildingRemoved;
+ buildingRemoved.Result = CheckBuildingRemoval(garrPlotInstanceId);
+ if (buildingRemoved.Result == GARRISON_SUCCESS)
+ {
+ Plot* plot = GetPlot(garrPlotInstanceId);
+
+ buildingRemoved.GarrPlotInstanceID = garrPlotInstanceId;
+ buildingRemoved.GarrBuildingID = plot->BuildingInfo.PacketInfo->GarrBuildingID;
+
+ Map* map = FindMap();
+ if (map)
+ plot->DeleteGameObject(map);
+
+ plot->ClearBuildingInfo(_owner);
+ _owner->SendDirectMessage(buildingRemoved.Write());
+
+ GarrBuildingEntry const* constructing = sGarrBuildingStore.AssertEntry(buildingRemoved.GarrBuildingID);
+ // Refund construction/upgrade cost
+ _owner->ModifyCurrency(constructing->CostCurrencyID, constructing->CostCurrencyAmount, false, true);
+ _owner->ModifyMoney(constructing->CostMoney * GOLD, false);
+
+ if (constructing->Level > 1)
+ {
+ // Restore previous level building
+ GarrBuildingEntry const* restored = sGarrisonMgr.GetPreviousLevelBuilding(constructing->Type, constructing->Level);
+ ASSERT(restored);
+
+ WorldPackets::Garrison::GarrisonPlaceBuildingResult placeBuildingResult;
+ placeBuildingResult.Result = GARRISON_SUCCESS;
+ placeBuildingResult.BuildingInfo.GarrPlotInstanceID = garrPlotInstanceId;
+ placeBuildingResult.BuildingInfo.GarrBuildingID = restored->ID;
+ placeBuildingResult.BuildingInfo.TimeBuilt = time(nullptr);
+ placeBuildingResult.BuildingInfo.Active = true;
+
+ plot->SetBuildingInfo(placeBuildingResult.BuildingInfo, _owner);
+ _owner->SendDirectMessage(placeBuildingResult.Write());
+ }
+
+ if (map)
+ if (GameObject* go = plot->CreateGameObject(map, GetFaction()))
+ map->AddToMap(go);
+ }
+ else
+ _owner->SendDirectMessage(buildingRemoved.Write());
+}
+
void Garrison::SendInfo()
{
WorldPackets::Garrison::GetGarrisonInfoResult garrisonInfo;
@@ -347,7 +411,8 @@ Map* Garrison::FindMap() const
GarrisonError Garrison::CheckBuildingPlacement(uint32 garrPlotInstanceId, uint32 garrBuildingId) const
{
GarrPlotInstanceEntry const* plotInstance = sGarrPlotInstanceStore.LookupEntry(garrPlotInstanceId);
- if (!plotInstance || !_plots.count(garrPlotInstanceId))
+ Plot const* plot = GetPlot(garrPlotInstanceId);
+ if (!plotInstance || !plot)
return GARRISON_ERROR_INVALID_PLOT;
GarrBuildingEntry const* building = sGarrBuildingStore.LookupEntry(garrBuildingId);
@@ -357,9 +422,13 @@ GarrisonError Garrison::CheckBuildingPlacement(uint32 garrPlotInstanceId, uint32
if (!sGarrisonMgr.IsPlotMatchingBuilding(plotInstance->GarrPlotID, garrBuildingId))
return GARRISON_ERROR_INVALID_PLOT_BUILDING;
+ // Cannot place buldings of higher level than garrison level
+ if (building->Level > _siteLevel->Level)
+ return GARRISON_ERROR_INVALID_BUILDINGID;
+
if (building->Flags & GARRISON_BUILDING_FLAG_NEEDS_PLAN)
{
- if (_knownBuildings.count(garrBuildingId))
+ if (!_knownBuildings.count(garrBuildingId))
return GARRISON_ERROR_BLUEPRINT_NOT_KNOWN;
}
else // Building is built as a quest reward
@@ -373,7 +442,7 @@ GarrisonError Garrison::CheckBuildingPlacement(uint32 garrPlotInstanceId, uint32
{
existingBuilding = sGarrBuildingStore.AssertEntry(p.second.BuildingInfo.PacketInfo->GarrBuildingID);
if (existingBuilding->Type == building->Type)
- if (p.first != garrPlotInstanceId || existingBuilding->Level != building->Level + 1) // check if its an upgrade in same plot
+ if (p.first != garrPlotInstanceId || existingBuilding->Level + 1 != building->Level) // check if its an upgrade in same plot
return GARRISON_ERROR_BUILDING_EXISTS;
}
}
@@ -381,9 +450,29 @@ GarrisonError Garrison::CheckBuildingPlacement(uint32 garrPlotInstanceId, uint32
if (!_owner->HasCurrency(building->CostCurrencyID, building->CostCurrencyAmount))
return GARRISON_ERROR_NOT_ENOUGH_CURRENCY;
- if (!_owner->HasEnoughMoney(uint64(building->CostMoney)))
+ if (!_owner->HasEnoughMoney(uint64(building->CostMoney * GOLD)))
return GARRISON_ERROR_NOT_ENOUGH_GOLD;
+ // New building cannot replace another building currently under construction
+ if (plot->BuildingInfo.PacketInfo)
+ if (!plot->BuildingInfo.PacketInfo->Active)
+ return GARRISON_ERROR_NO_BUILDING;
+
+ return GARRISON_SUCCESS;
+}
+
+GarrisonError Garrison::CheckBuildingRemoval(uint32 garrPlotInstanceId) const
+{
+ Plot const* plot = GetPlot(garrPlotInstanceId);
+ if (!plot)
+ return GARRISON_ERROR_INVALID_PLOT;
+
+ if (!plot->BuildingInfo.PacketInfo)
+ return GARRISON_ERROR_NO_BUILDING;
+
+ if (plot->BuildingInfo.CanActivate())
+ return GARRISON_ERROR_BUILDING_EXISTS;
+
return GARRISON_SUCCESS;
}
@@ -395,7 +484,7 @@ GameObject* Garrison::Plot::CreateGameObject(Map* map, GarrisonFactionIndex fact
GarrPlotInstanceEntry const* plotInstance = sGarrPlotInstanceStore.AssertEntry(PacketInfo.GarrPlotInstanceID);
GarrPlotEntry const* plot = sGarrPlotStore.AssertEntry(plotInstance->GarrPlotID);
GarrBuildingEntry const* building = sGarrBuildingStore.AssertEntry(BuildingInfo.PacketInfo->GarrBuildingID);
- if (BuildingInfo.PacketInfo->TimeBuilt + building->BuildDuration <= time(nullptr) && BuildingInfo.PacketInfo->Active)
+ if (BuildingInfo.PacketInfo->Active)
entry = faction == GARRISON_FACTION_INDEX_HORDE ? building->HordeGameObjectID : building->AllianceGameObjectID;
else
entry = faction == GARRISON_FACTION_INDEX_HORDE ? plot->HordeConstructionGameObjectID : plot->AllianceConstructionGameObjectID;
@@ -419,3 +508,47 @@ GameObject* Garrison::Plot::CreateGameObject(Map* map, GarrisonFactionIndex fact
BuildingInfo.Guid = go->GetGUID();
return go;
}
+
+void Garrison::Plot::DeleteGameObject(Map* map)
+{
+ if (BuildingInfo.Guid.IsEmpty())
+ return;
+
+ if (GameObject* oldBuilding = map->GetGameObject(BuildingInfo.Guid))
+ oldBuilding->Delete();
+
+ BuildingInfo.Guid.Clear();
+}
+
+void Garrison::Plot::ClearBuildingInfo(Player* owner)
+{
+ WorldPackets::Garrison::GarrisonPlotPlaced plotPlaced;
+ plotPlaced.PlotInfo = &PacketInfo;
+ owner->SendDirectMessage(plotPlaced.Write());
+
+ BuildingInfo.PacketInfo = boost::none;
+}
+
+void Garrison::Plot::SetBuildingInfo(WorldPackets::Garrison::GarrisonBuildingInfo const& buildingInfo, Player* owner)
+{
+ if (!BuildingInfo.PacketInfo)
+ {
+ WorldPackets::Garrison::GarrisonPlotRemoved plotRemoved;
+ plotRemoved.GarrPlotInstanceID = PacketInfo.GarrPlotInstanceID;
+ owner->SendDirectMessage(plotRemoved.Write());
+ }
+
+ BuildingInfo.PacketInfo = buildingInfo;
+}
+
+bool Garrison::Building::CanActivate() const
+{
+ if (PacketInfo)
+ {
+ GarrBuildingEntry const* building = sGarrBuildingStore.AssertEntry(PacketInfo->GarrBuildingID);
+ if (PacketInfo->TimeBuilt + building->BuildDuration <= time(nullptr))
+ return true;
+ }
+
+ return false;
+}