• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Return-To-The-Roots / s25client / 21218532072

21 Jan 2026 05:04PM UTC coverage: 50.717% (+0.05%) from 50.663%
21218532072

Pull #1679

github

web-flow
Merge 3777db6bb into 12da8bf44
Pull Request #1679: Add all classic S2 cheats and a few more

92 of 168 new or added lines in 12 files covered. (54.76%)

7 existing lines in 5 files now uncovered.

22788 of 44932 relevant lines covered (50.72%)

42042.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.89
/libs/s25main/Cheats.cpp
1
// Copyright (C) 2024 Settlers Freaks (sf-team at siedler25.org)
2
//
3
// SPDX-License-Identifier: GPL-2.0-or-later
4

5
#include "Cheats.h"
6
#include "GameInterface.h"
7
#include "GamePlayer.h"
8
#include "RttrForeachPt.h"
9
#include "buildings/nobHQ.h"
10
#include "factories/BuildingFactory.h"
11
#include "network/GameClient.h"
12
#include "world/GameWorldBase.h"
13

14
Cheats::Cheats(GameWorldBase& world) : world_(world) {}
31✔
15

16
bool Cheats::areCheatsAllowed() const
106✔
17
{
18
    return world_.IsSinglePlayer();
106✔
19
}
20

21
void Cheats::toggleCheatMode()
30✔
22
{
23
    // In S2, if you enabled cheat mode, revealed the map and disabled cheat mode, the map would remain revealed and you
24
    // would be unable to unreveal the map.
25
    // In RTTR, disabling cheat mode turns all cheats off and they have to be turned on again manually.
26
    if(isCheatModeOn_)
30✔
27
        turnAllCheatsOff();
7✔
28

29
    isCheatModeOn_ = !isCheatModeOn_;
30✔
30
}
30✔
31

32
void Cheats::toggleAllVisible()
6✔
33
{
34
    if(isCheatModeOn())
6✔
35
    {
36
        isAllVisible_ = !isAllVisible_;
5✔
37

38
        // In S2, the minimap is not updated immediately.
39
        // In RTTR, the minimap would become messed up if it wasn't updated here.
40
        if(GameInterface* gi = world_.GetGameInterface())
5✔
41
            gi->GI_UpdateMapVisibility();
3✔
42
    }
43
}
6✔
44

45
void Cheats::toggleAllBuildingsEnabled()
10✔
46
{
47
    // In S2, if you enabled cheats you would automatically have all buildings enabled.
48
    // In RTTR, because this may have unintended consequences when playing campaigns, the user must explicitly enable
49
    // all buildings after enabling cheats.
50
    if(isCheatModeOn())
10✔
51
        areAllBuildingsEnabled_ = !areAllBuildingsEnabled_;
9✔
52
}
10✔
53

54
void Cheats::toggleShowEnemyProductivityOverlay()
6✔
55
{
56
    // In S2, if you enabled cheats you would automatically see the enemy productivity overlay - most importantly what
57
    // buildings the enemy intends to build.
58
    // In RTTR, the user must explicitly enable this feature after enabling cheats.
59
    if(isCheatModeOn())
6✔
60
        shouldShowEnemyProductivityOverlay_ = !shouldShowEnemyProductivityOverlay_;
5✔
61
}
6✔
62

63
bool Cheats::canPlaceCheatBuilding(const MapPoint& mp) const
14✔
64
{
65
    if(!isCheatModeOn())
14✔
66
        return false;
3✔
67

68
    // It seems that in the original game you can only build headquarters in unoccupied territory at least 2 nodes
69
    // away from any border markers and that it doesn't need more bq than a hut.
70
    const MapNode& node = world_.GetNode(mp);
11✔
71
    return !node.owner && !world_.IsAnyNeighborOwned(mp) && node.bq >= BuildingQuality::Hut;
11✔
72
}
73

74
void Cheats::placeCheatBuilding(const MapPoint& mp, const GamePlayer& player)
7✔
75
{
76
    if(!canPlaceCheatBuilding(mp))
7✔
77
        return;
1✔
78

79
    // The new HQ will have default resources.
80
    // In the original game, new HQs created in the Roman campaign had no resources.
81
    constexpr auto checkExists = false;
6✔
82
    world_.DestroyNO(mp, checkExists); // if CanPlaceCheatBuilding is true then this must be safe to destroy
6✔
83
    auto* hq =
84
      BuildingFactory::CreateBuilding(world_, BuildingType::Headquarters, mp, player.GetPlayerId(), player.nation);
6✔
85
    static_cast<nobHQ*>(hq)->SetIsTent(player.IsHQTent());
6✔
86
}
87

88
void Cheats::setGameSpeed(uint8_t speedIndex) // NOLINT(readability-make-member-function-const)
1✔
89
{
90
    if(!isCheatModeOn())
1✔
91
        return;
1✔
92

NEW
93
    constexpr auto gfLengthInMs = 50;
×
NEW
94
    GAMECLIENT.SetNewSpeed(FramesInfo::milliseconds32_t{gfLengthInMs >> speedIndex});
×
95
    // 50 -> 25 -> 12 -> 6 -> 3 -> 1
96
}
97

98
void Cheats::toggleHumanAIPlayer()
1✔
99
{
100
    if(isCheatModeOn() && !GAMECLIENT.IsReplayModeOn())
1✔
101
    {
102
        GAMECLIENT.ToggleHumanAIPlayer(AI::Info{AI::Type::Default, AI::Level::Easy});
×
103
        isHumanAIPlayer_ = !isHumanAIPlayer_;
×
104
    }
105
}
1✔
106

NEW
107
void Cheats::armageddon() // NOLINT(readability-make-member-function-const)
×
108
{
109
    if(isCheatModeOn())
×
110
        GAMECLIENT.CheatArmageddon();
×
111
}
×
112

113
Cheats::ResourceRevealMode Cheats::getResourceRevealMode() const
9✔
114
{
115
    return isCheatModeOn() ? resourceRevealMode_ : ResourceRevealMode::Nothing;
9✔
116
}
117

118
void Cheats::toggleResourceRevealMode()
6✔
119
{
120
    switch(resourceRevealMode_)
6✔
121
    {
122
        case ResourceRevealMode::Nothing: resourceRevealMode_ = ResourceRevealMode::Ores; break;
2✔
123
        case ResourceRevealMode::Ores: resourceRevealMode_ = ResourceRevealMode::Fish; break;
2✔
124
        case ResourceRevealMode::Fish: resourceRevealMode_ = ResourceRevealMode::Water; break;
1✔
125
        default: resourceRevealMode_ = ResourceRevealMode::Nothing; break;
1✔
126
    }
127
}
6✔
128

129
void Cheats::destroyBuildings(const PlayerIDSet& playerIds)
4✔
130
{
131
    if(!isCheatModeOn())
4✔
132
        return;
1✔
133

134
    RTTR_FOREACH_PT(MapPoint, world_.GetSize())
12,483✔
135
    {
136
        if(world_.GetNO(pt)->GetType() == NodalObjectType::Building && playerIds.count(world_.GetNode(pt).owner - 1))
12,288✔
137
            world_.DestroyNO(pt);
5✔
138
    }
139
}
140

141
void Cheats::destroyAllAIBuildings()
2✔
142
{
143
    if(!isCheatModeOn())
2✔
144
        return;
1✔
145

146
    PlayerIDSet ais;
2✔
147
    for(auto i = 0u; i < world_.GetNumPlayers(); ++i)
4✔
148
    {
149
        if(!world_.GetPlayer(i).isHuman())
3✔
150
            ais.insert(i);
2✔
151
    }
152
    destroyBuildings(ais);
1✔
153
}
154

155
void Cheats::turnAllCheatsOff()
7✔
156
{
157
    if(isAllVisible_)
7✔
158
        toggleAllVisible();
1✔
159
    if(areAllBuildingsEnabled_)
7✔
160
        toggleAllBuildingsEnabled();
2✔
161
    if(shouldShowEnemyProductivityOverlay_)
7✔
162
        toggleShowEnemyProductivityOverlay();
1✔
163
    if(isHumanAIPlayer_)
7✔
164
        toggleHumanAIPlayer();
×
165
}
7✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc