Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add leather addon #1720

Draft
wants to merge 14 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added data/RTTR/assets/addons/0x01000001/AFR_ICON.LST
Binary file not shown.
Binary file added data/RTTR/assets/addons/0x01000001/AFR_Z.LST
Binary file not shown.
Binary file added data/RTTR/assets/addons/0x01000001/JAP_ICON.LST
Binary file not shown.
Binary file added data/RTTR/assets/addons/0x01000001/JAP_Z.LST
Binary file not shown.
Binary file added data/RTTR/assets/addons/0x01000001/ROM_ICON.LST
Binary file not shown.
Binary file added data/RTTR/assets/addons/0x01000001/ROM_Z.LST
Binary file not shown.
Binary file added data/RTTR/assets/addons/0x01000001/VIK_ICON.LST
Binary file not shown.
Binary file added data/RTTR/assets/addons/0x01000001/VIK_Z.LST
Binary file not shown.
Binary file added data/RTTR/assets/addons/0x01000001/WAFR_Z.LST
Binary file not shown.
Binary file added data/RTTR/assets/addons/0x01000001/WJAP_Z.LST
Binary file not shown.
Binary file added data/RTTR/assets/addons/0x01000001/WROM_Z.LST
Binary file not shown.
Binary file added data/RTTR/assets/addons/0x01000001/WVIK_Z.LST
Binary file not shown.
Binary file added data/RTTR/assets/addons/0x01000001/bab_icon.lst
Binary file not shown.
Binary file added data/RTTR/assets/addons/0x01000001/bab_z.lst
Binary file not shown.
Binary file added data/RTTR/assets/addons/0x01000001/wbab_z.lst
Binary file not shown.
Binary file added data/RTTR/assets/base/leather_bobs.lst
Binary file not shown.
4 changes: 4 additions & 0 deletions libs/s25main/BuildingRegister.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later

#include "BuildingRegister.h"
#include "LeatherLoader.h"
#include "SerializedGameData.h"
#include "WineLoader.h"
#include "buildings/noBuildingSite.h"
Expand Down Expand Up @@ -41,6 +42,9 @@ void BuildingRegister::Deserialize(SerializedGameData& sgd)
if(sgd.GetGameDataVersion() < 11 && wineaddon::isWineAddonBuildingType(bld))
continue;

if(sgd.GetGameDataVersion() < 12 && leatheraddon::isLeatherAddonBuildingType(bld))
continue;

if(BuildingProperties::IsUsual(bld))
sgd.PopObjectContainer(buildings[bld], GO_Type::NobUsual);
}
Expand Down
5 changes: 4 additions & 1 deletion libs/s25main/GameCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ namespace gc {
unsigned Deserializer::getCurrentVersion()
{
// 1: Add wine addon --> 3 new values in distribution
return 1;
// 2: Add leather addon --> 3 new values in distribution, 1 new value in transport order and transport order default
// values changed
return 2;
}

GameCommandPtr GameCommand::Deserialize(Deserializer& ser)
Expand All @@ -37,6 +39,7 @@ GameCommandPtr GameCommand::Deserialize(Deserializer& ser)
case GCType::Attack: gc = new Attack(ser); break;
case GCType::SeaAttack: gc = new SeaAttack(ser); break;
case GCType::SetCoinsAllowed: gc = new SetCoinsAllowed(ser); break;
case GCType::SetArmorAllowed: gc = new SetArmorAllowed(ser); break;
case GCType::SetProductionEnabled: gc = new SetProductionEnabled(ser); break;
case GCType::SetInventorySetting: gc = new SetInventorySetting(ser); break;
case GCType::SetAllInventorySettings: gc = new SetAllInventorySettings(ser); break;
Expand Down
3 changes: 2 additions & 1 deletion libs/s25main/GameCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,11 @@ enum class GCType : uint8_t
SetTroopLimit,
NotifyAlliesOfLocation,
SetTempleProductionMode,
SetArmorAllowed,
};
constexpr auto maxEnumValue(GCType)
{
return GCType::SetTempleProductionMode;
return GCType::SetArmorAllowed;
}

class GameCommand
Expand Down
69 changes: 61 additions & 8 deletions libs/s25main/GameCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "GameCommands.h"
#include "GamePlayer.h"
#include "LeatherLoader.h"
#include "WineLoader.h"
#include "buildings/nobBaseWarehouse.h"
#include "buildings/nobHarborBuilding.h"
Expand All @@ -16,6 +17,7 @@
#include "world/GameWorld.h"
#include "nodeObjs/noFlag.h"
#include "nodeObjs/noShip.h"
#include "gameData/SettingTypeConv.h"
#include <algorithm>
#include <stdexcept>

Expand Down Expand Up @@ -90,20 +92,43 @@ void UpgradeRoad::Execute(GameWorld& world, uint8_t playerId)

ChangeDistribution::ChangeDistribution(Deserializer& ser) : GameCommand(GCType::ChangeDistribution)
{
if(ser.getDataVersion() >= 1)
if(ser.getDataVersion() >= 2)
helpers::popContainer(ser, data);
else
{
std::array<Distributions::value_type,
std::tuple_size<Distributions>::value - 3>
tmpData; // 3 entries for wine addon
helpers::popContainer(ser, tmpData);
const unsigned wineAddonAdditionalDistributions = 3;
const unsigned leatherAddonAdditionalDistributions = 3;

auto const additionalDistributions =
leatherAddonAdditionalDistributions + (ser.getDataVersion() < 1 ? wineAddonAdditionalDistributions : 0);

std::vector<Distributions::value_type> tmpData(std::tuple_size<Distributions>::value - additionalDistributions);

auto skipBuilding = [&](DistributionMapping const& mapping) {
// Skipped and standard distribution in skipped case
std::tuple<bool, unsigned int> result = {false, 0};
if(ser.getDataVersion() < 1)
{
// skip over wine buildings
std::get<0>(result) |= wineaddon::isWineAddonBuildingType(std::get<BuildingType>(mapping));
}

// skip over leather addon buildings and leather addon wares only
std::get<0>(result) |= leatheraddon::isLeatherAddonBuildingType(std::get<BuildingType>(mapping));

if(std::get<BuildingType>(mapping) == BuildingType::Slaughterhouse
&& (std::get<GoodType>(mapping) == GoodType::Ham))
result = {true, 8};
return result;
};

helpers::popContainer(ser, tmpData, true);
size_t srcIdx = 0, tgtIdx = 0;
for(const auto& mapping : distributionMap)
{
// skip over wine buildings in tmpData
const auto setting =
wineaddon::isWineAddonBuildingType(std::get<BuildingType>(mapping)) ? 0 : tmpData[srcIdx++];
// skip over not stored buildings in tmpData
const auto skipped = skipBuilding(mapping);
const auto setting = std::get<0>(skipped) ? std::get<1>(skipped) : tmpData[srcIdx++];
data[tgtIdx++] = setting;
}
}
Expand All @@ -129,6 +154,27 @@ void DestroyBuilding::Execute(GameWorld& world, uint8_t playerId)
world.DestroyBuilding(pt_, playerId);
}

ChangeTransport::ChangeTransport(Deserializer& ser) : GameCommand(GCType::ChangeTransport)
{
if(ser.getDataVersion() >= 2)
helpers::popContainer(ser, data);
else
{
const unsigned leatherAddonAdditionalTransportOrders = 1;
std::vector<TransportOrders::value_type> tmpData(std::tuple_size<TransportOrders>::value
- leatherAddonAdditionalTransportOrders);

helpers::popContainer(ser, tmpData, true);
std::copy(tmpData.begin(), tmpData.end(), data.begin());
// all transport prios greater equal 7 are increased by one because the new leatherwork
// uses prio 7
std::transform(data.begin(), data.end() - leatherAddonAdditionalTransportOrders, data.begin(),
[](uint8_t& prio) { return prio < 7 ? prio : prio + 1; });
data[std::tuple_size<TransportOrders>::value - leatherAddonAdditionalTransportOrders] =
STD_TRANSPORT_PRIO[GoodType::Leather];
}
}

void ChangeTransport::Execute(GameWorld& world, uint8_t playerId)
{
world.GetPlayer(playerId).ConvertTransportData(data);
Expand Down Expand Up @@ -173,6 +219,13 @@ void SetCoinsAllowed::Execute(GameWorld& world, uint8_t playerId)
bld->SetCoinsAllowed(enabled);
}

void SetArmorAllowed::Execute(GameWorld& world, uint8_t playerId)
{
auto* const bld = world.GetSpecObj<nobMilitary>(pt_);
if(bld && bld->GetPlayer() == playerId)
bld->SetArmorAllowed(enabled);
}

void SetTroopLimit::Execute(GameWorld& world, uint8_t playerId)
{
auto* const bld = world.GetSpecObj<nobMilitary>(pt_);
Expand Down
21 changes: 20 additions & 1 deletion libs/s25main/GameCommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ class ChangeTransport : public GameCommand

protected:
ChangeTransport(const TransportOrders& data) : GameCommand(GCType::ChangeTransport), data(data) {}
ChangeTransport(Serializer& ser) : GameCommand(GCType::ChangeTransport) { helpers::popContainer(ser, data); }
ChangeTransport(Deserializer& ser);

public:
void Serialize(Serializer& ser) const override
Expand Down Expand Up @@ -405,6 +405,25 @@ class SetCoinsAllowed : public Coords
void Execute(GameWorld& world, uint8_t playerId) override;
};

/// Allow/stop armor delivery to building
class SetArmorAllowed : public Coords
{
GC_FRIEND_DECL;
const bool enabled;

protected:
SetArmorAllowed(const MapPoint pt, bool enabled) : Coords(GCType::SetArmorAllowed, pt), enabled(enabled) {}
SetArmorAllowed(Serializer& ser) : Coords(GCType::SetArmorAllowed, ser), enabled(ser.PopBool()) {}

public:
void Serialize(Serializer& ser) const override
{
Coords::Serialize(ser);
ser.PushBool(enabled);
}
void Execute(GameWorld& world, uint8_t playerId) override;
};

/// Produktivität in einem Gebäude deaktivieren/aktivieren
class SetProductionEnabled : public Coords
{
Expand Down
80 changes: 71 additions & 9 deletions libs/s25main/GamePlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "FindWhConditions.h"
#include "GameInterface.h"
#include "GlobalGameSettings.h"
#include "LeatherLoader.h"
#include "RoadSegment.h"
#include "SerializedGameData.h"
#include "TradePathCache.h"
Expand Down Expand Up @@ -137,6 +138,8 @@ void GamePlayer::LoadStandardDistribution()
distribution[GoodType::Stones].client_buildings.push_back(BuildingType::Catapult);
distribution[GoodType::Grapes].client_buildings.push_back(BuildingType::Winery);
distribution[GoodType::Wine].client_buildings.push_back(BuildingType::Temple);
distribution[GoodType::Skins].client_buildings.push_back(BuildingType::Tannery);
distribution[GoodType::Leather].client_buildings.push_back(BuildingType::LeatherWorks);

// Waren mit mehreren möglichen Zielen erstmal nullen, kann dann im Fenster eingestellt werden
for(const auto i : helpers::enumRange<GoodType>())
Expand Down Expand Up @@ -265,8 +268,18 @@ void GamePlayer::Deserialize(SerializedGameData& sgd)
if(sgd.GetGameDataVersion() < 11 && wineaddon::isWineAddonGoodType(i))
continue;

if(sgd.GetGameDataVersion() < 12 && leatheraddon::isLeatherAddonGoodType(i))
continue;

Distribution& dist = distribution[i];
helpers::popContainer(sgd, dist.percent_buildings);
// Set standard value otherwise its zero and Slaughterhouse never gets ham
// because the ham distribution was not there in earlier versions
if(sgd.GetGameDataVersion() < 12 && i == GoodType::Ham)
{
dist.percent_buildings[BuildingType::Slaughterhouse] = 8;
}

if(sgd.GetGameDataVersion() < 7)
{
dist.client_buildings.resize(sgd.PopUnsignedInt());
Expand All @@ -283,17 +296,28 @@ void GamePlayer::Deserialize(SerializedGameData& sgd)

useCustomBuildOrder_ = sgd.PopBool();

if(sgd.GetGameDataVersion() < 11)
if(sgd.GetGameDataVersion() < 12)
{
std::vector<BuildingType> build_order_raw(build_order.size() - 3);
auto countOfNotAvailableBuildingsInSaveGame = sgd.GetGameDataVersion() < 11 ? 6 : 3;
std::vector<BuildingType> build_order_raw(build_order.size() - countOfNotAvailableBuildingsInSaveGame);
helpers::popContainer(sgd, build_order_raw, true);
build_order_raw.insert(build_order_raw.end(),
{BuildingType::Vineyard, BuildingType::Winery, BuildingType::Temple});

if(sgd.GetGameDataVersion() < 11)
build_order_raw.insert(build_order_raw.end(),
{BuildingType::Vineyard, BuildingType::Winery, BuildingType::Temple});

if(sgd.GetGameDataVersion() < 12)
build_order_raw.insert(build_order_raw.end(),
{BuildingType::Skinner, BuildingType::Tannery, BuildingType::LeatherWorks});

std::copy(build_order_raw.begin(), build_order_raw.end(), build_order.begin());

std::vector<uint8_t> transportPrio_raw(transportPrio.size() - 2);
auto countOfNotAvailableGoodsInSaveGame = sgd.GetGameDataVersion() < 11 ? 5 : 3;
std::vector<uint8_t> transportPrio_raw(transportPrio.size() - countOfNotAvailableGoodsInSaveGame);
helpers::popContainer(sgd, transportPrio_raw, true);
std::copy(transportPrio_raw.begin(), transportPrio_raw.end(), transportPrio.begin());
std::transform(transportPrio.begin(), transportPrio.end() - countOfNotAvailableGoodsInSaveGame,
transportPrio.begin(), [](uint8_t& prio) { return prio < 7 ? prio : prio + 1; });
} else
{
helpers::popContainer(sgd, build_order);
Expand All @@ -307,13 +331,17 @@ void GamePlayer::Deserialize(SerializedGameData& sgd)
helpers::popContainer(sgd, tools_ordered);
tools_ordered_delta = {};

if(sgd.GetGameDataVersion() < 11)
if(sgd.GetGameDataVersion() < 12)
{
std::vector<unsigned int> global_inventory_good_raw(global_inventory.goods.size() - 2);
auto countOfNotAvailableGoodsInSaveGame = sgd.GetGameDataVersion() < 11 ? 5 : 3;
std::vector<unsigned int> global_inventory_good_raw(global_inventory.goods.size()
- countOfNotAvailableGoodsInSaveGame);
helpers::popContainer(sgd, global_inventory_good_raw, true);
std::copy(global_inventory_good_raw.begin(), global_inventory_good_raw.end(), global_inventory.goods.begin());

std::vector<unsigned int> global_inventory_people_raw(global_inventory.people.size() - 3);
auto countOfNotAvailableJobsInSaveGame = sgd.GetGameDataVersion() < 11 ? 6 : 3;
std::vector<unsigned int> global_inventory_people_raw(global_inventory.people.size()
- countOfNotAvailableJobsInSaveGame);
helpers::popContainer(sgd, global_inventory_people_raw, true);
std::copy(global_inventory_people_raw.begin(), global_inventory_people_raw.end(),
global_inventory.people.begin());
Expand Down Expand Up @@ -974,9 +1002,11 @@ struct ClientForWare

noBaseBuilding* GamePlayer::FindClientForWare(const Ware& ware)
{
// Wenn es eine Goldmünze ist, wird das Ziel auf eine andere Art und Weise berechnet
// If the ware is a coin or an armor, the goal is determined by another logic
if(ware.type == GoodType::Coins)
return FindClientForCoin(ware);
else if(ware.type == GoodType::Armor)
return FindClientForArmor(ware);

// Warentyp herausfinden
GoodType gt = ware.type;
Expand Down Expand Up @@ -1153,6 +1183,38 @@ nobBaseMilitary* GamePlayer::FindClientForCoin(const Ware& ware) const
return bb;
}

nobBaseMilitary* GamePlayer::FindClientForArmor(const Ware& ware) const
{
nobBaseMilitary* bb = nullptr;
unsigned best_points = 0, points;

for(nobMilitary* milBld : buildings.GetMilitaryBuildings())
{
unsigned way_points;

points = milBld->CalcArmorPoints();
// If 0, it does not want any armor (armor delivery stopped)
if(points)
{
// Find the nearest building
if(world.FindPathForWareOnRoads(*ware.GetLocation(), *milBld, &way_points) != RoadPathDirection::None)
{
points -= way_points;
if(points > best_points)
{
best_points = points;
bb = milBld;
}
}
}
}

if(!bb)
bb = FindWarehouseForWare(ware);

return bb;
}

unsigned GamePlayer::GetBuidingSitePriority(const noBuildingSite* building_site)
{
if(useCustomBuildOrder_)
Expand Down
1 change: 1 addition & 0 deletions libs/s25main/GamePlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ class GamePlayer : public GamePlayerInfo

/// Sucht einen Abnehmer (sprich Militärgebäude), wenn es keinen findet, wird ein Warenhaus zurückgegeben bzw. 0
nobBaseMilitary* FindClientForCoin(const Ware& ware) const;
nobBaseMilitary* FindClientForArmor(const Ware& ware) const;

/// Gibt Priorität der Baustelle zurück (entscheidet selbständig, welche Reihenfolge usw)
/// je kleiner die Rückgabe, destro größer die Priorität!
Expand Down
3 changes: 2 additions & 1 deletion libs/s25main/GlobalGameSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ void GlobalGameSettings::registerAllAddons()
AddonToolOrdering,
AddonTrade,
AddonAutoFlags,
AddonWine
AddonWine,
AddonLeather
>;
// clang-format on
using namespace boost::mp11;
Expand Down
Loading
Loading