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

Spike/addons/settlers iv mining #1501

Draft
wants to merge 15 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
4 changes: 4 additions & 0 deletions libs/s25main/GlobalGameSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ void GlobalGameSettings::registerAllAddons()
AddonMilitaryAid,
AddonMilitaryControl,
AddonMilitaryHitpoints,
AddonMiningOverhaulCoal,
AddonMiningOverhaulGold,
AddonMiningOverhaulGranite,
AddonMiningOverhaulIron,
AddonMoreAnimals,
AddonNoAlliedPush,
AddonNoCoinsDefault,
Expand Down
21 changes: 11 additions & 10 deletions libs/s25main/SerializedGameData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,17 @@
/// Then reset this number to 1.
/// TODO: Let GO_Type start at 0 again when resetting this
/// Changelog:
/// 2: All player buildings together, variable width size for containers and ship names
/// 3: Landscape and terrain names stored as strings
/// 4: HunterWaitingForAnimalReady introduced as sub-state of HunterFindingShootingpoint
/// 5: Make RoadPathDirection contiguous and use optional for ware in nofBuildingWorker
/// 6: Make TradeDirection contiguous, Serialize only nobUsuals in BuildingRegister::buildings,
/// include water and fish in geologists resourceFound
/// 7: Use helpers::push/popContainer (uses var size)
/// 8: noFlag::Wares converted to static_vector
/// 9: Drop serialization of node BQ
static const unsigned currentGameDataVersion = 9;
/// 2: All player buildings together, variable width size for containers and ship names
/// 3: Landscape and terrain names stored as strings
/// 4: HunterWaitingForAnimalReady introduced as sub-state of HunterFindingShootingpoint
/// 5: Make RoadPathDirection contiguous and use optional for ware in nofBuildingWorker
/// 6: Make TradeDirection contiguous, Serialize only nobUsuals in BuildingRegister::buildings,
/// include water and fish in geologists resourceFound
/// 7: Use helpers::push/popContainer (uses var size)
/// 8: noFlag::Wares converted to static_vector
/// 9: Drop serialization of node BQ
/// 10: nofMiner saves isAlteredWorkcycle boolean variable
static const unsigned currentGameDataVersion = 10;
// clang-format on

std::unique_ptr<GameObject> SerializedGameData::Create_GameObject(const GO_Type got, const unsigned obj_id)
Expand Down
62 changes: 62 additions & 0 deletions libs/s25main/addons/AddonMiningOverhaul.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (C) 2005 - 2021 Settlers Freaks (sf-team at siedler25.org)
//
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include "AddonList.h"
#include "mygettext/mygettext.h"

enum class MiningBehavior
{
Normal,
S4Like,
Inexhaustible,
AlwaysAvailable
};

class AddonMiningOverhaulBase : public AddonList
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this lengthy name (here and in the name)? How would you translate it (to German)?

I mean:

  • Name: "Mining overhaul: Coal"
  • Description: "This addon lets you control mining behavior"

This is why I suggested "Mining behavior" thinking about how it will look in the (already long) list of addons with their currently active setting in the window: "Mining behavior (coal): No change" vs "Mining overhaul: Coal: No Change"

PS: Funny how the roles are reversed for once: You thinking like a developer, me like a user :D

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this lengthy name (here and in the name)? How would you translate it (to German)?

AddonZumAnpassenDerBergwerklogik :D

I'm not so happy with the behavior anymore. This somewhat more feels like something visible, possibly a worker. Like how does a soldier behave when his home building is lost, does he return, does he wander around. Overhaul implied some change of logic, which is often invisible and just like "physics", you feel the result but can't grab the reason itself - it's just the way it is. Can change the name if you don't agree to that though :)

"Mining behavior (coal): No change" vs "Mining overhaul: Coal: No Change"

I don't see where this Representation comes from, as there is no textual representation that way as values are highlighted by the right column. So I rather see Mining behavior (coal) vs Mining overhaul: coal where I liked the second version more, besides the discussion if it should be overhaul or behavior. Anyway, I don't care that much for the name in the window (except lenghty names like "Number of scouts required fore exploration expedition"). So same here, can change the name if you'd like me to :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see where this Representation comes from, as there is no textual representation that way

I mean the Addon settings window. Currently it really reads (to me) like Addon title: Current setting. E.g. "Economy mode game length: 120min" and I kinda like that. I.e. a list that reads like plain English for every row so you understand it easily even when not reading the hint.

AddonZumAnpassenDerBergwerklogik :D

Ouch :D Seriously, I have that settings window in mind and try to imagine how it would look there.

So I rather see Mining behavior (coal) vs Mining overhaul: coal where I liked the second version more, besides the discussion if it should be overhaul or behavior.

I'd really like "behavior" better for a setting. Yes you are right with the description of "overhaul" but (at least to me) "overhaul" is the process of changing the behavior. I.e. reimplementing a part of the game to be "better" (performance, crash-resistance, ...). E.g. we need an overhaul of the save/load system as the current one sucks and crashes on big maps ;-)

As for the setting: This is something you change when selecting an option. And that option doesn't "overhaul" something but changes its "behavior".

Maybe we haven't found a good name yet. I mean what it changes is the behavior of the mines regarding resources. So maybe "Resource usage by mines: Coal". But that still doesn't fully hit it. It misses that the miner may produce nothing for a cycle. That's why I was asking for the German name. Just another way to think about it to come up with a nice flashy name for this :)

So I'd say come up with an English and German name here, maybe ask in Discord if anyone else has ideas, and check how it looks like in the Addon window before we finalize the name. So it is at least as good as possible in English and German ;-)

My current favourite is still "behavior", similar to what we have for the toolmaker: "Behavior [...]: ProduceNothing | ProduceRandom"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I may add my 2 cents:

First, on "mine" vs "mining":

  • "Mining overhaul", as the act of mining is being overhauled.
  • "Mine behavior", as behavior applies to the exhaustion of the mine.

Personally, I'd use "Mine exhaustion (Coal)"/"Minenerschöpfung (Kohle)". Also, note the parentheses. Otherwise, you'd end up with an awkward double-colon when writing out settings: "Mine exhaustion: Coal: Default"

An alternative might be "Mine productivity"/"Minenergiebigkeit". I don't like it but maybe it sparks someone else's idea.

{
protected:
AddonMiningOverhaulBase(AddonId addonId, const std::string& addonName)
: AddonList(addonId, AddonGroup::Economy, addonName,
_("This addon allows you to change the ore mining behavior.\n\n"
"No change: Original behavior\n"
"Settlers IV: Mines never fully deplete. Range is decreased to 1. Chance for production"
" depends on remaining resource amount in range.\n"
"Inexhaustible: Mines never deplete\n"
"Everywhere: Mines never deplete, can mine everywhere"),
{
_("No change"),
_("Settlers IV"),
_("Inexhaustible"),
_("Everywhere"),
})
{}
};

class AddonMiningOverhaulCoal : public AddonMiningOverhaulBase
{
public:
AddonMiningOverhaulCoal() : AddonMiningOverhaulBase(AddonId::MINING_OVERHAUL_COAL, _("Mining overhaul: Coal")) {}
};

class AddonMiningOverhaulGold : public AddonMiningOverhaulBase
{
public:
AddonMiningOverhaulGold() : AddonMiningOverhaulBase(AddonId::MINING_OVERHAUL_GOLD, _("Mining overhaul: Gold")) {}
};

class AddonMiningOverhaulGranite : public AddonMiningOverhaulBase
{
public:
AddonMiningOverhaulGranite()
: AddonMiningOverhaulBase(AddonId::MINING_OVERHAUL_GRANITE, _("Mining overhaul: Granite"))
{}
};

class AddonMiningOverhaulIron : public AddonMiningOverhaulBase
{
public:
AddonMiningOverhaulIron() : AddonMiningOverhaulBase(AddonId::MINING_OVERHAUL_IRON, _("Mining overhaul: Iron")) {}
};
4 changes: 3 additions & 1 deletion libs/s25main/addons/Addons.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@
#include "addons/AddonToolOrdering.h"

#include "addons/AddonInexhaustibleFish.h"
#include "addons/AddonInexhaustibleGraniteMines.h"
#include "addons/AddonMaxRank.h"
#include "addons/AddonMilitaryAid.h"
#include "addons/AddonSeaAttack.h"

#include "addons/AddonInexhaustibleGraniteMines.h"
#include "addons/AddonMiningOverhaul.h"

#include "addons/AddonBattlefieldPromotion.h"
#include "addons/AddonBurnDuration.h"
#include "addons/AddonHalfCostMilEquip.h"
Expand Down
3 changes: 3 additions & 0 deletions libs/s25main/addons/const_addons.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ ENUM_WITH_STRING(AddonId, LIMIT_CATAPULTS = 0x00000000, INEXHAUSTIBLE_MINES = 0x

INEXHAUSTIBLE_GRANITEMINES = 0x00800000,

MINING_OVERHAUL_COAL = 0x00800001, MINING_OVERHAUL_GOLD = 0x00800002,
MINING_OVERHAUL_GRANITE = 0x00800003, MINING_OVERHAUL_IRON = 0x00800004,

MAX_RANK = 0x00900000, SEA_ATTACK = 0x00900001, INEXHAUSTIBLE_FISH = 0x00900002,
MORE_ANIMALS = 0x00900003, BURN_DURATION = 0x00900004, NO_ALLIED_PUSH = 0x00900005,
BATTLEFIELD_PROMOTION = 0x00900006, HALF_COST_MIL_EQUIP = 0x00900007, MILITARY_CONTROL = 0x00900008,
Expand Down
7 changes: 1 addition & 6 deletions libs/s25main/ai/aijh/AIPlayerJH.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -977,13 +977,8 @@ MapPoint AIPlayerJH::FindPositionForBuildingAround(BuildingType type, const MapP
foundPos = FindBestPosition(around, AIResource::Ironore, BuildingQuality::Mine, searchRadius);
break;
case BuildingType::GraniteMine:
if(!ggs.isEnabled(
AddonId::INEXHAUSTIBLE_GRANITEMINES)) // inexhaustible granite mines do not require granite
foundPos = FindBestPosition(around, AIResource::Granite, BuildingQuality::Mine, searchRadius);
else
foundPos = SimpleFindPosition(around, BuildingQuality::Mine, searchRadius);
foundPos = FindBestPosition(around, AIResource::Granite, BuildingQuality::Mine, searchRadius);
break;

case BuildingType::Fishery:
foundPos = FindBestPosition(around, AIResource::Fish, BUILDING_SIZE[type], searchRadius);
if(foundPos.isValid() && !ValidFishInRange(foundPos))
Expand Down
128 changes: 116 additions & 12 deletions libs/s25main/figures/nofMiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,27 @@
#include "nofMiner.h"
#include "GlobalGameSettings.h"
#include "Loader.h"
#include "SerializedGameData.h"
#include "SoundManager.h"
#include "addons/const_addons.h"
#include "buildings/nobUsual.h"
#include "network/GameClient.h"
#include "ogl/glArchivItem_Bitmap_Player.h"
#include "world/GameWorld.h"
#include <gameData/GameConsts.h>
#include <random/Random.h>

nofMiner::nofMiner(const MapPoint pos, const unsigned char player, nobUsual* workplace)
: nofWorkman(Job::Miner, pos, player, workplace)
: nofWorkman(Job::Miner, pos, player, workplace), isAlteredWorkcycle(false)
{}

nofMiner::nofMiner(SerializedGameData& sgd, const unsigned obj_id) : nofWorkman(sgd, obj_id) {}
nofMiner::nofMiner(SerializedGameData& sgd, const unsigned obj_id) : nofWorkman(sgd, obj_id)
{
if(sgd.GetGameDataVersion() >= 10)
isAlteredWorkcycle = sgd.PopBool();
else
isAlteredWorkcycle = false;
}

void nofMiner::DrawWorking(DrawPoint drawPt)
{
Expand Down Expand Up @@ -60,6 +69,9 @@ unsigned short nofMiner::GetCarryID() const

helpers::OptionalEnum<GoodType> nofMiner::ProduceWare()
{
if(isAlteredWorkcycle)
return boost::none;

switch(workplace->GetBuildingType())
{
case BuildingType::GoldMine: return GoodType::Gold;
Expand All @@ -71,20 +83,103 @@ helpers::OptionalEnum<GoodType> nofMiner::ProduceWare()

bool nofMiner::AreWaresAvailable() const
{
return nofWorkman::AreWaresAvailable() && FindPointWithResource(GetRequiredResType()).isValid();
if(!nofWorkman::AreWaresAvailable())
return false;

const MiningBehavior addonSetting = GetMiningBehavior();

if(addonSetting == MiningBehavior::AlwaysAvailable)
return true;

if(addonSetting == MiningBehavior::S4Like)
return FindPointWithResource(GetRequiredResType(), MINER_ORE_RADIUS_SETTLERSIV).isValid();
else
return FindPointWithResource(GetRequiredResType()).isValid();
}

bool nofMiner::StartWorking()
MiningBehavior nofMiner::GetMiningBehavior() const
{
MapPoint resPt = FindPointWithResource(GetRequiredResType());
if(!resPt.isValid())
return false;
const GlobalGameSettings& settings = world->GetGGS();
bool inexhaustibleRes = settings.isEnabled(AddonId::INEXHAUSTIBLE_MINES)
|| (workplace->GetBuildingType() == BuildingType::GraniteMine
&& settings.isEnabled(AddonId::INEXHAUSTIBLE_GRANITEMINES));
if(!inexhaustibleRes)
world->ReduceResource(resPt);

auto miningBehavior = MiningBehavior::Normal;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either use the default switch or a default value. Using both doesn't make sense... I'd say the default case doesn't make sense anway: It should be unreachable...
BTW: With the current implementation of this function you are better off with return static_cast<...>(...) instead of all this C&P miningBehavior = static_cast...; break because the return makes the break superflous so it can be removed.

I guess this comes from a variation of my suggestion: That was to use the switch only to "translate" the building type to the correct AddonId, which I still think is a good idea, as it makes the code shorter which is usually good ;)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had to add the default statement as I otherwise get warned that for any other building types no value is returned and that warning is treated as error. But when using return values thats needed anways.


switch(workplace->GetBuildingType())
{
case BuildingType::GoldMine:
miningBehavior = static_cast<MiningBehavior>(settings.getSelection(AddonId::MINING_OVERHAUL_GOLD));
break;
case BuildingType::IronMine:
miningBehavior = static_cast<MiningBehavior>(settings.getSelection(AddonId::MINING_OVERHAUL_IRON));
break;
case BuildingType::CoalMine:
miningBehavior = static_cast<MiningBehavior>(settings.getSelection(AddonId::MINING_OVERHAUL_COAL));
break;
case BuildingType::GraniteMine:
miningBehavior = static_cast<MiningBehavior>(settings.getSelection(AddonId::MINING_OVERHAUL_GRANITE));
break;
default: miningBehavior = MiningBehavior::Normal;
}

return miningBehavior;
}

bool nofMiner::StartWorking()
{
isAlteredWorkcycle = false;

switch(GetMiningBehavior())
{
case MiningBehavior::S4Like:
{
int sumResAmount = 0;
MapPoint nonMinimumResPt;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this variable is worth a comment, despite its name. Something like: Resources never deplete, only get reduced to 1. Hence find any point with at least 2 of the required resource and reduce that.


const std::vector<MapPoint> reachablePts =
world->GetPointsInRadiusWithCenter(workplace->GetPos(), MINER_ORE_RADIUS_SETTLERSIV);

for(const MapPoint curPt : reachablePts)
{
const Resource resource = world->GetNode(curPt).resources;

if(resource.getType() != GetRequiredResType())
continue;

const auto resAmount = resource.getAmount();
sumResAmount += resAmount;

if(resAmount > 1u && !nonMinimumResPt.isValid())
nonMinimumResPt = curPt;
}

// depending on remaining resources, roll if this workcycle needs to be altered or not
if(RANDOM_RAND(reachablePts.size() * MAX_ORE_QUANTITY) > sumResAmount)
{
isAlteredWorkcycle = true;
} else
{
if(nonMinimumResPt.isValid())
world->ReduceResource(nonMinimumResPt);
}
}
break;
case MiningBehavior::Inexhaustible:
{
if(!FindPointWithResource(GetRequiredResType()).isValid())
return false;
}
Comment on lines +166 to +169
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can never be false, as this is checked in the has wares function.

Suggested change
{
if(!FindPointWithResource(GetRequiredResType()).isValid())
return false;
}
// Already checked in AreWaresAvailable
RTTR_Assert(FindPointWithResource(GetRequiredResType()).isValid())

Notes:

  • Braces in switch-case only required when introducing a variable, otherwise you can omit them to save space ;-)
  • RTTR_Assert "asserts" (i.e. assumes) something which should be true at this point. In release builds this check is removed(!), in debug builds (or in non-default release builds, there is a CMake-option) the condition is checked and the game aborts if it doesn't hold true. So only use for something which really must be true at this point and if not obvious add a comment why.

break;
case MiningBehavior::AlwaysAvailable: break;
case MiningBehavior::Normal:
{
const MapPoint resPt = FindPointWithResource(GetRequiredResType());
if(!resPt.isValid())
return false;

world->ReduceResource(resPt);
}
break;
}

return nofWorkman::StartWorking();
}

Expand All @@ -98,3 +193,12 @@ ResourceType nofMiner::GetRequiredResType() const
default: return ResourceType::Granite;
}
}

void nofMiner::Serialize(SerializedGameData& sgd) const
{
nofWorkman::Serialize(sgd);

sgd.PushBool(isAlteredWorkcycle);

sgd.GetGameDataVersion();
}
7 changes: 6 additions & 1 deletion libs/s25main/figures/nofMiner.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
#pragma once

#include "nofWorkman.h"
#include "addons/AddonMiningOverhaul.h"

class SerializedGameData;
class nobUsual;

/// Klasse für den Schreiner
class nofMiner : public nofWorkman
{
protected:
Expand All @@ -19,14 +19,19 @@ class nofMiner : public nofWorkman
unsigned short GetCarryID() const override;
/// Der Arbeiter erzeugt eine Ware
helpers::OptionalEnum<GoodType> ProduceWare() override;
/// alter workcycle (addon)
bool isAlteredWorkcycle;
Comment on lines +22 to +23
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is the work cycle "altered" (i.e. "changed", I guess)? I mean: It is the same, it simply produces nothing.
So suggestions: isFailedMiningAttempt or produceNothing (with a comment: "... in this work cycle")

See also the usage in ProduceWare at https://github.com/Return-To-The-Roots/s25client/pull/1501/files#diff-a34581854bed9a5f4ca267f64c0e919f48ffd4b9c09f732351db4c127fb2e932R65-R66 and how the name makes the code more readable: if(produceNothing) return boost::none

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I knew you'd stumble across this :)

I called it altered for two reasons, I may also add an addon which lets you switch between "Produce nothing" and "Produce granite" when using settlers IV mining. This also allows other addons (if one likes) like gold mines have a chance to produce a gem. So in my special case, I could name the variable like you suggested, but as this can be a more general variable I named it isAlteredWorkcycle. Are you good with that, if not, I will change it until this variable becomes another use.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it is very good to write code with future extensions in mind, I don't think it applies here. If we never implement that new addon (cool idea, though!) everyone will always be confused by this. And: We might want an enum here later, like: produceNormal, produceNothing, produceSpecial. And it is a private class variable, so with very limited scope where renaming later on will not hurt.

So here, in this case we likely gain more by less speculation and giving it a clear name for the current use, and adapt when and if required.


bool AreWaresAvailable() const override;
bool StartWorking() override;
ResourceType GetRequiredResType() const;
MiningBehavior GetMiningBehavior() const;

public:
nofMiner(MapPoint pos, unsigned char player, nobUsual* workplace);
nofMiner(SerializedGameData& sgd, unsigned obj_id);

GO_Type GetGOT() const final { return GO_Type::NofMiner; }

void Serialize(SerializedGameData& sgd) const override;
};
9 changes: 6 additions & 3 deletions libs/s25main/figures/nofWorkman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,16 @@ struct NodeHasResource

MapPoint nofWorkman::FindPointWithResource(ResourceType type) const
{
// Alle Punkte durchgehen, bis man einen findet, wo man graben kann
return FindPointWithResource(type, MINER_RADIUS);
}

MapPoint nofWorkman::FindPointWithResource(ResourceType type, unsigned radius) const {
const std::vector<MapPoint> pts =
world->GetMatchingPointsInRadius<1>(pos, MINER_RADIUS, NodeHasResource(*world, type), true);
world->GetMatchingPointsInRadius<1>(pos, radius, NodeHasResource(*world, type), true);
if(!pts.empty())
return pts.front();

workplace->OnOutOfResources();
Flamefire marked this conversation as resolved.
Show resolved Hide resolved

return MapPoint::Invalid();
}
}
1 change: 1 addition & 0 deletions libs/s25main/figures/nofWorkman.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class nofWorkman : public nofBuildingWorker

/// Looks for a point with a given resource on the node
MapPoint FindPointWithResource(ResourceType type) const;
MapPoint FindPointWithResource(ResourceType type, unsigned radius) const;

public:
/// Going to workplace
Expand Down
4 changes: 4 additions & 0 deletions libs/s25main/gameData/GameConsts.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ constexpr GameSpeed referenceSpeed = GameSpeed::Normal;

/// Reichweite der Bergarbeiter
constexpr unsigned MINER_RADIUS = 2;
constexpr unsigned MINER_ORE_RADIUS_SETTLERSIV = 1u;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I Always read this as "settler siv" and am confused :D Maybe add another underscore or just use "4"? Similar to "MiningBehavior::S4Like"

From the other comment:

I've never seen a well as a mine - which makes the name MINER_RADIUS_SETTLERSIV also wrong.

This is actually a (code quality) bug, that nofWorkman::FindPointWithResource is used by the wellguy and miners and has MINER_RADIUS hard-coded. So your original name here was correct and you can remove the _ORE infix.
If you want, you can fix this bug by removing nofWorkman::FindPointWithResource(ResourceType type) (i.e. the one without the radius as the parameter) and keep only the one with the radius which you added. Then either change the call sites to always pass the correct radius constant (add a new WELL_RADIUS or so here) Optionally you can move the old FindPointWithResource (without radius) into the nofMiner and nofWellGuy classes to avoid repeating the radius constant in multiple places of the class and even remove the ResourceType from the signature, as e.g. for the wellguy it is always water, and for the miner you can use GetRequiredResType. This makes a nice default function: MapPoint FindPointWithResource() const while for special cases like your addon there is still the function taking 2 arguments in the base class. Finally: For the wellguy you can even name that new, parameterless function FindPointWithWater or similar to reflect its implementation


/// maximum quantity for ores
constexpr unsigned MAX_ORE_QUANTITY = 7u;

/// Konstante für die Pfadrichtung bei einer Schiffsverbindung
constexpr unsigned char SHIP_DIR = 100;
Expand Down
Loading