Skip to content

Commit 70b841f

Browse files
Merge branch 'master' into sidequest/ignore-isolated-fish-resources
2 parents b812545 + 64b706b commit 70b841f

13 files changed

Lines changed: 249 additions & 45 deletions

libs/s25main/GlobalGameSettings.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,11 @@ void GlobalGameSettings::registerAllAddons()
104104
AddonWine,
105105
AddonLeather,
106106
AddonNoArmorDefault,
107-
AddonArmorCapturedBld
107+
AddonArmorCapturedBld,
108+
AddonForesterFarmFieldAvoidance,
109+
AddonForesterReachRadius,
110+
AddonWoodcutterReachRadius,
111+
AddonStonemasonReachRadius
108112
>;
109113
// clang-format on
110114
using namespace boost::mp11;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (C) 2005 - 2026 Settlers Freaks (sf-team at siedler25.org)
2+
//
3+
// SPDX-License-Identifier: GPL-2.0-or-later
4+
5+
#pragma once
6+
7+
#include "AddonBool.h"
8+
#include "mygettext/mygettext.h"
9+
10+
class AddonForesterFarmFieldAvoidance : public AddonBool
11+
{
12+
public:
13+
AddonForesterFarmFieldAvoidance()
14+
: AddonBool(AddonId::FORESTER_FARM_FIELD_AVOIDANCE, AddonGroup::GamePlay | AddonGroup::Economy,
15+
_("Foresters avoid farm field spots"),
16+
_("Prevents foresters from planting trees on spots that own farms could use for new fields."))
17+
{}
18+
};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (C) 2005 - 2026 Settlers Freaks (sf-team at siedler25.org)
2+
//
3+
// SPDX-License-Identifier: GPL-2.0-or-later
4+
5+
#pragma once
6+
7+
#include "AddonList.h"
8+
#include "mygettext/mygettext.h"
9+
10+
const std::array<unsigned, 6> foresterRadiusValues = {
11+
6, // Default
12+
8, // +33%
13+
10, // +66%
14+
12, // +100%
15+
15, // +150%
16+
18 // +200%
17+
};
18+
19+
class AddonForesterReachRadius : public AddonList
20+
{
21+
public:
22+
AddonForesterReachRadius()
23+
: AddonList(AddonId::FORESTER_REACH_RADIUS, AddonGroup::GamePlay, _("Adjust forester's range"),
24+
_("Increase the radius in which the forester plants trees."),
25+
{_("Default"), _("+33%"), _("+66%"), _("+100%"), _("+150%"), _("+200%")})
26+
{}
27+
};
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright (C) 2005 - 2026 Settlers Freaks (sf-team at siedler25.org)
2+
//
3+
// SPDX-License-Identifier: GPL-2.0-or-later
4+
5+
#pragma once
6+
7+
#include "AddonList.h"
8+
#include "mygettext/mygettext.h"
9+
10+
const std::array<unsigned, 7> stonemasonRadiusValues = {
11+
8, // Default
12+
10, // +25%
13+
12, // +50%
14+
14, // +75%
15+
16, // +100%
16+
20, // +150%
17+
24 // +200%
18+
};
19+
20+
class AddonStonemasonReachRadius : public AddonList
21+
{
22+
public:
23+
AddonStonemasonReachRadius()
24+
: AddonList(AddonId::STONEMASON_REACH_RADIUS, AddonGroup::GamePlay, _("Adjust stonemason's range"),
25+
_("Increase the radius in which the stonemason searches for stone."),
26+
{
27+
_("Default"),
28+
_("+25%"),
29+
_("+50%"),
30+
_("+75%"),
31+
_("+100%"),
32+
_("+150%"),
33+
_("+200%"),
34+
})
35+
{}
36+
};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (C) 2005 - 2026 Settlers Freaks (sf-team at siedler25.org)
2+
//
3+
// SPDX-License-Identifier: GPL-2.0-or-later
4+
5+
#pragma once
6+
7+
#include "AddonList.h"
8+
#include "mygettext/mygettext.h"
9+
10+
const std::array<unsigned, 6> woodcutterRadiusValues = {
11+
6, // Default
12+
8, // +33%
13+
10, // +66%
14+
12, // +100%
15+
15, // +150%
16+
18 // +200%
17+
};
18+
19+
class AddonWoodcutterReachRadius : public AddonList
20+
{
21+
public:
22+
AddonWoodcutterReachRadius()
23+
: AddonList(AddonId::WOODCUTTER_REACH_RADIUS, AddonGroup::GamePlay, _("Adjust woodcutter's range"),
24+
_("Increase the radius in which the woodcutter searches for trees."),
25+
{_("Default"), _("+33%"), _("+66%"), _("+100%"), _("+150%"), _("+200%")})
26+
{}
27+
};

libs/s25main/addons/Addons.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@
6262
#include "addons/AddonAutoFlags.h"
6363

6464
#include "addons/AddonArmorCapturedBld.h"
65+
#include "addons/AddonForesterFarmFieldAvoidance.h"
6566
#include "addons/AddonLeather.h"
6667
#include "addons/AddonNoArmorDefault.h"
6768
#include "addons/AddonWine.h"
69+
70+
#include "addons/AddonForesterReachRadius.h"
71+
#include "addons/AddonStonemasonReachRadius.h"
72+
#include "addons/AddonWoodcutterReachRadius.h"

libs/s25main/addons/const_addons.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
// 00E Jonathan
2727
// 00F Jarno
2828
// 010 aztimh
29+
// 011 DevOpsOfChaos
30+
// 012 MichalLabuda
2931

3032
// Do not forget to add your Addon to GlobalGameSettings::registerAllAddons @ GlobalGameSettings.cpp!
3133
// Never use a number twice!
@@ -75,7 +77,12 @@ ENUM_WITH_STRING(AddonId, LIMIT_CATAPULTS = 0x00000000, INEXHAUSTIBLE_MINES = 0x
7577
AUTOFLAGS = 0x00F00000,
7678

7779
WINE = 0x01000000, LEATHER = 0x01000001, NO_ARMOR_DEFAULT = 0x01000002,
78-
ARMOR_CAPTURED_BLD = 0x01000003)
80+
ARMOR_CAPTURED_BLD = 0x01000003,
81+
82+
FORESTER_FARM_FIELD_AVOIDANCE = 0x01100000,
83+
84+
FORESTER_REACH_RADIUS = 0x01200000, WOODCUTTER_REACH_RADIUS = 0x01200001,
85+
STONEMASON_REACH_RADIUS = 0x01200002)
7986
//-V:AddonId:801
8087

8188
enum class AddonGroup : unsigned

libs/s25main/figures/nofFarmer.cpp

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,36 @@ unsigned short nofFarmer::GetCarryID() const
5757
return 71;
5858
}
5959

60+
nofFarmhand::PointQuality nofFarmer::GetNewFieldPointQuality(const GameWorld& world, const MapPoint pt)
61+
{
62+
// Nicht auf Straßen bauen!
63+
for(const auto dir : helpers::EnumRange<Direction>{})
64+
{
65+
if(world.GetPointRoad(pt, dir) != PointRoad::None)
66+
return PointQuality::NotPossible;
67+
}
68+
69+
// Terrain untersuchen
70+
if(!world.IsOfTerrain(pt, [](const auto& desc) { return desc.IsVital(); }))
71+
return PointQuality::NotPossible;
72+
73+
// Ist Platz frei?
74+
NodalObjectType noType = world.GetNO(pt)->GetType();
75+
if(noType != NodalObjectType::Environment && noType != NodalObjectType::Nothing)
76+
return PointQuality::NotPossible;
77+
78+
for(const MapPoint nb : world.GetNeighbours(pt))
79+
{
80+
// Nicht direkt neben andere Getreidefelder und Gebäude setzen!
81+
noType = world.GetNO(nb)->GetType();
82+
if(noType == NodalObjectType::Grainfield || noType == NodalObjectType::Grapefield
83+
|| noType == NodalObjectType::Building || noType == NodalObjectType::Buildingsite)
84+
return PointQuality::NotPossible;
85+
}
86+
87+
return PointQuality::Class2;
88+
}
89+
6090
/// Abgeleitete Klasse informieren, wenn sie anfängt zu arbeiten (Vorbereitungen)
6191
void nofFarmer::WorkStarted()
6292
{
@@ -123,34 +153,7 @@ nofFarmhand::PointQuality nofFarmer::GetPointQuality(const MapPoint pt, bool /*
123153
}
124154
// oder einen freien Platz, wo wir ein neues sähen können
125155
else
126-
{
127-
// Nicht auf Straßen bauen!
128-
for(const auto dir : helpers::EnumRange<Direction>{})
129-
{
130-
if(world->GetPointRoad(pt, dir) != PointRoad::None)
131-
return PointQuality::NotPossible;
132-
}
133-
134-
// Terrain untersuchen
135-
if(!world->IsOfTerrain(pt, [](const auto& desc) { return desc.IsVital(); }))
136-
return PointQuality::NotPossible;
137-
138-
// Ist Platz frei?
139-
NodalObjectType noType = world->GetNO(pt)->GetType();
140-
if(noType != NodalObjectType::Environment && noType != NodalObjectType::Nothing)
141-
return PointQuality::NotPossible;
142-
143-
for(const MapPoint nb : world->GetNeighbours(pt))
144-
{
145-
// Nicht direkt neben andere Getreidefelder und Gebäude setzen!
146-
noType = world->GetNO(nb)->GetType();
147-
if(noType == NodalObjectType::Grainfield || noType == NodalObjectType::Grapefield
148-
|| noType == NodalObjectType::Building || noType == NodalObjectType::Buildingsite)
149-
return PointQuality::NotPossible;
150-
}
151-
152-
return PointQuality::Class2;
153-
}
156+
return GetNewFieldPointQuality(*world, pt);
154157
}
155158

156159
void nofFarmer::WorkAborted()

libs/s25main/figures/nofFarmer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#pragma once
66

77
#include "nofFarmhand.h"
8+
class GameWorld;
89
class SerializedGameData;
910
class nobUsual;
1011

@@ -34,6 +35,8 @@ class nofFarmer : public nofFarmhand
3435
nofFarmer(MapPoint pos, unsigned char player, nobUsual* workplace);
3536
nofFarmer(SerializedGameData& sgd, unsigned obj_id);
3637

38+
static nofFarmhand::PointQuality GetNewFieldPointQuality(const GameWorld& world, MapPoint pt);
39+
3740
void Serialize(SerializedGameData& sgd) const override;
3841

3942
GO_Type GetGOT() const final { return GO_Type::NofFarmer; }

libs/s25main/figures/nofFarmhand.cpp

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
#include "world/GameWorld.h"
1313
#include "gameData/JobConsts.h"
1414

15+
#include "GlobalGameSettings.h"
16+
#include "addons/AddonForesterReachRadius.h"
17+
#include "addons/AddonStonemasonReachRadius.h"
18+
#include "addons/AddonWoodcutterReachRadius.h"
19+
1520
nofFarmhand::nofFarmhand(const Job job, const MapPoint pos, const unsigned char player, nobUsual* workplace)
1621
: nofBuildingWorker(job, pos, player, workplace), dest(0, 0)
1722
{}
@@ -27,6 +32,35 @@ nofFarmhand::nofFarmhand(SerializedGameData& sgd, const unsigned obj_id)
2732
: nofBuildingWorker(sgd, obj_id), dest(sgd.PopMapPoint())
2833
{}
2934

35+
unsigned nofFarmhand::GetWorkRadius(const Job job)
36+
{
37+
switch(job)
38+
{
39+
case Job::Carpenter: return 0;
40+
case Job::Hunter:
41+
case Job::Farmer:
42+
case Job::Winegrower: return 2;
43+
case Job::CharBurner: return 3;
44+
case Job::Woodcutter:
45+
{
46+
const unsigned sel = world->GetGGS().getSelection(AddonId::WOODCUTTER_REACH_RADIUS);
47+
return woodcutterRadiusValues[sel];
48+
}
49+
case Job::Forester:
50+
{
51+
const unsigned sel = world->GetGGS().getSelection(AddonId::FORESTER_REACH_RADIUS);
52+
return foresterRadiusValues[sel];
53+
}
54+
case Job::Fisher: return 7;
55+
case Job::Stonemason:
56+
{
57+
const unsigned sel = world->GetGGS().getSelection(AddonId::STONEMASON_REACH_RADIUS);
58+
return stonemasonRadiusValues[sel];
59+
}
60+
default: throw std::logic_error("Invalid job");
61+
}
62+
}
63+
3064
void nofFarmhand::WalkedDerived()
3165
{
3266
switch(state)
@@ -59,21 +93,7 @@ void nofFarmhand::HandleDerivedEvent(const unsigned /*id*/)
5993
{
6094
// Start working after the initial wait period
6195
// Work radius
62-
const unsigned max_radius = [](Job job) {
63-
switch(job)
64-
{
65-
case Job::Carpenter: return 0;
66-
case Job::Hunter:
67-
case Job::Farmer:
68-
case Job::Winegrower: return 2;
69-
case Job::CharBurner: return 3;
70-
case Job::Woodcutter:
71-
case Job::Forester: return 6;
72-
case Job::Fisher: return 7;
73-
case Job::Stonemason: return 8;
74-
default: throw std::logic_error("Invalid job");
75-
}
76-
}(job_);
96+
const unsigned max_radius = GetWorkRadius(job_);
7797
// Number of additional radii in which points should be found
7898
// I.e. 0 => Don't search for points further away than ones already found
7999
const unsigned additionalRadiiToFind = [](Job job) {

0 commit comments

Comments
 (0)