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

Return-To-The-Roots / s25client / 12323492039

13 Dec 2024 09:44PM UTC coverage: 50.144% (-0.02%) from 50.166%
12323492039

Pull #1683

github

web-flow
Merge 9ea584aa0 into 77372c5a4
Pull Request #1683: Lua: Allow setting number of players, and placing HQs. Then fix the mission on map "The snake"

9 of 40 new or added lines in 8 files covered. (22.5%)

4 existing lines in 1 file now uncovered.

22270 of 44412 relevant lines covered (50.14%)

34410.75 hits per line

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

96.5
/libs/s25main/lua/LuaInterfaceSettings.cpp
1
// Copyright (C) 2005 - 2021 Settlers Freaks (sf-team at siedler25.org)
2
//
3
// SPDX-License-Identifier: GPL-2.0-or-later
4

5
#include "LuaInterfaceSettings.h"
6
#include "GlobalGameSettings.h"
7
#include "LuaServerPlayer.h"
8
#include "addons/const_addons.h"
9
#include "helpers/containerUtils.h"
10
#include "lua/LuaHelpers.h"
11
#include "lua/SafeEnum.h"
12
#include "network/IGameLobbyController.h"
13
#include "gameTypes/GameSettingTypes.h"
14
#include "s25util/Log.h"
15
#include "s25util/strAlgos.h"
16

17
/// Wrapper used to make sure LUA can only return on of the predefined values
18
struct AddonIdWrapper
19
{
20
    AddonId value;
21
    constexpr operator AddonId() const { return value; }
7✔
22
};
23

24
LuaInterfaceSettings::LuaInterfaceSettings(IGameLobbyController& lobbyServerController,
5✔
25
                                           const ILocalGameState& localGameState)
5✔
26
    : LuaInterfaceGameBase(localGameState), lobbyServerController_(lobbyServerController)
5✔
27
{
28
    Register(lua);
5✔
29
    LuaServerPlayer::Register(lua);
5✔
30
    lua["rttr"] = this;
5✔
31
}
5✔
32

33
LuaInterfaceSettings::~LuaInterfaceSettings() = default;
5✔
34

35
void LuaInterfaceSettings::Register(kaguya::State& state)
5✔
36
{
37
    state["RTTRSettings"].setClass(
5✔
38
      kaguya::UserdataMetatable<LuaInterfaceSettings, LuaInterfaceGameBase>()
10✔
39
        .addFunction("GetNumPlayers", &LuaInterfaceSettings::GetNumPlayers)
5✔
40
        .addFunction("GetPlayer", &LuaInterfaceSettings::GetPlayer)
5✔
41
        .addOverloadedFunctions("SetAddon", &LuaInterfaceSettings::SetAddon, &LuaInterfaceSettings::SetBoolAddon)
5✔
42
        .addFunction("ResetAddons", &LuaInterfaceSettings::ResetAddons)
5✔
43
        .addFunction("ResetGameSettings", &LuaInterfaceSettings::ResetGameSettings)
5✔
44
        .addFunction("SetGameSettings", &LuaInterfaceSettings::SetGameSettings)
5✔
45
        // Old name
46
        .addFunction("GetPlayerCount", &LuaInterfaceSettings::GetNumPlayers));
5✔
47

48
    state["AddonId"].setClass(kaguya::UserdataMetatable<AddonIdWrapper>());
5✔
49

50
    for(AddonId id : rttrEnum::EnumData<AddonId>::values)
215✔
51
    {
52
        state[std::string("ADDON_") + rttrEnum::toString(id)] = AddonIdWrapper{id};
210✔
53
    }
54

55
#pragma region ConstDefs
56
#define ADD_LUA_CONST(name) state["GS_" + s25util::toUpper(#name)] = GameSpeed::name
57
    ADD_LUA_CONST(VerySlow);
5✔
58
    ADD_LUA_CONST(Slow);
5✔
59
    ADD_LUA_CONST(Normal);
5✔
60
    ADD_LUA_CONST(Fast);
5✔
61
    ADD_LUA_CONST(VeryFast);
5✔
62
#undef ADD_LUA_CONST
63

64
#define ADD_LUA_CONST(name) state["GO_" + s25util::toUpper(#name)] = GameObjective::name
65
    ADD_LUA_CONST(None);
5✔
66
    ADD_LUA_CONST(Conquer3_4);
5✔
67
    ADD_LUA_CONST(TotalDomination);
5✔
68
#undef ADD_LUA_CONST
69

70
#define ADD_LUA_CONST(name) state["SWR_" + s25util::toUpper(#name)] = StartWares::name
71
    ADD_LUA_CONST(VLow);
5✔
72
    ADD_LUA_CONST(Low);
5✔
73
    ADD_LUA_CONST(Normal);
5✔
74
    ADD_LUA_CONST(ALot);
5✔
75
#undef ADD_LUA_CONST
76

77
#define ADD_LUA_CONST(name) state["EXP_" + s25util::toUpper(#name)] = Exploration::name
78
    ADD_LUA_CONST(Disabled);
5✔
79
    ADD_LUA_CONST(Classic);
5✔
80
    ADD_LUA_CONST(FogOfWar);
5✔
81
    ADD_LUA_CONST(FogOfWarExplored);
5✔
82
    state["EXP_FOGOFWARE_EXPLORED"] = Exploration::FogOfWarExplored; // Legacy alias (mind the typo)
5✔
83
#undef ADD_LUA_CONST
84
#pragma endregion ConstDefs
85
}
5✔
86

87
unsigned LuaInterfaceSettings::GetNumPlayers() const
6✔
88
{
89
    return lobbyServerController_.GetMaxNumPlayers();
6✔
90
}
91

92
LuaServerPlayer LuaInterfaceSettings::GetPlayer(int idx)
7✔
93
{
94
    lua::assertTrue(idx >= 0 && static_cast<unsigned>(idx) < GetNumPlayers(), "Invalid player idx");
9✔
95
    return LuaServerPlayer(lobbyServerController_, static_cast<unsigned>(idx));
5✔
96
}
97

98
void LuaInterfaceSettings::SetAddon(AddonIdWrapper id, unsigned value)
4✔
99
{
100
    GlobalGameSettings ggs = lobbyServerController_.GetGGS();
8✔
101
    ggs.setSelection(id, value);
4✔
102
    lobbyServerController_.ChangeGlobalGameSettings(ggs);
4✔
103
}
4✔
104

105
void LuaInterfaceSettings::SetBoolAddon(AddonIdWrapper id, bool value)
2✔
106
{
107
    SetAddon(id, value ? 1 : 0);
2✔
108
}
2✔
109

110
void LuaInterfaceSettings::ResetAddons()
1✔
111
{
112
    GlobalGameSettings ggs = lobbyServerController_.GetGGS();
2✔
113
    ggs.resetAddons();
1✔
114
    lobbyServerController_.ChangeGlobalGameSettings(ggs);
1✔
115
}
1✔
116

117
void LuaInterfaceSettings::ResetGameSettings()
1✔
118
{
119
    // Simply create a new instance
120
    lobbyServerController_.ChangeGlobalGameSettings(GlobalGameSettings());
1✔
121
}
1✔
122

123
void LuaInterfaceSettings::SetGameSettings(const kaguya::LuaTable& settings)
16✔
124
{
125
    GlobalGameSettings ggs = lobbyServerController_.GetGGS();
32✔
126
    std::vector<std::string> keys = settings.keys<std::string>();
32✔
127

128
    if(helpers::contains(keys, "speed"))
16✔
129
    {
130
        const lua::SafeEnum<GameSpeed> speed = settings.getField("speed");
3✔
131
        ggs.speed = speed;
3✔
132
    }
133

134
    if(helpers::contains(keys, "objective"))
16✔
135
    {
136
        const lua::SafeEnum<GameObjective> objective = settings.getField("objective");
2✔
137
        ggs.objective = objective;
2✔
138
    }
139

140
    if(helpers::contains(keys, "startWares"))
16✔
141
    {
142
        const lua::SafeEnum<StartWares> wares = settings.getField("startWares");
2✔
143
        ggs.startWares = wares;
2✔
144
    }
145

146
    if(helpers::contains(keys, "fow"))
16✔
147
    {
148
        const lua::SafeEnum<Exploration> fow = settings.getField("fow");
4✔
149
        ggs.exploration = fow;
4✔
150
    }
151

152
    if(helpers::contains(keys, "lockedTeams"))
16✔
153
        ggs.lockedTeams = settings.getField("lockedTeams");
3✔
154

155
    if(helpers::contains(keys, "teamView"))
16✔
156
        ggs.teamView = settings.getField("teamView");
2✔
157

158
    if(helpers::contains(keys, "randomStartPosition"))
16✔
159
        ggs.randomStartPosition = settings.getField("randomStartPosition");
2✔
160

161
    lobbyServerController_.ChangeGlobalGameSettings(ggs);
16✔
162
}
16✔
163

164
kaguya::LuaRef LuaInterfaceSettings::GetAllowedChanges()
5✔
165
{
166
    kaguya::LuaRef getGeneralConfig = lua["getAllowedChanges"];
10✔
167
    if(getGeneralConfig.type() == LUA_TFUNCTION)
5✔
168
    {
169
        auto cfg = getGeneralConfig.call<kaguya::LuaRef>();
3✔
170
        if(cfg.type() == LUA_TTABLE)
3✔
171
            return cfg;
3✔
172
    }
173
    return kaguya::LuaRef();
2✔
174
}
175

176
bool LuaInterfaceSettings::EventSettingsInit(bool isSinglePlayer, bool isSavegame)
3✔
177
{
178
    kaguya::LuaRef func = lua["onSettingsInit"];
6✔
179
    if(func.type() == LUA_TFUNCTION)
3✔
180
        return func.call<bool>(isSinglePlayer, isSavegame);
2✔
181
    else
182
        return true;
1✔
183
}
184

185
void LuaInterfaceSettings::EventSettingsReady()
2✔
186
{
187
    kaguya::LuaRef func = lua["onSettingsReady"];
4✔
188
    if(func.type() == LUA_TFUNCTION)
2✔
189
        func.call<void>();
1✔
190
}
2✔
191

192
void LuaInterfaceSettings::EventPlayerJoined(unsigned playerIdx)
2✔
193
{
194
    kaguya::LuaRef func = lua["onPlayerJoined"];
4✔
195
    if(func.type() == LUA_TFUNCTION)
2✔
196
        func.call<void>(playerIdx);
1✔
197
}
2✔
198

199
void LuaInterfaceSettings::EventPlayerLeft(unsigned playerIdx)
2✔
200
{
201
    kaguya::LuaRef func = lua["onPlayerLeft"];
4✔
202
    if(func.type() == LUA_TFUNCTION)
2✔
203
        func.call<void>(playerIdx);
1✔
204
}
2✔
205

206
void LuaInterfaceSettings::EventPlayerReady(unsigned playerIdx)
2✔
207
{
208
    kaguya::LuaRef func = lua["onPlayerReady"];
4✔
209
    if(func.type() == LUA_TFUNCTION)
2✔
210
        func.call<void>(playerIdx);
1✔
211
}
2✔
212

213
bool LuaInterfaceSettings::IsChangeAllowed(const std::string& name, const bool defaultVal /* = false*/)
5✔
214
{
215
    kaguya::LuaRef cfg = GetAllowedChanges();
10✔
216
    if(cfg.isNilref())
5✔
217
        return defaultVal;
2✔
218
    cfg = cfg.getField(name);
3✔
219
    if(cfg.typeTest<bool>())
3✔
220
        return cfg;
2✔
221
    else
222
        return defaultVal;
1✔
223
}
224

225
std::vector<AddonId> LuaInterfaceSettings::GetAllowedAddons()
4✔
226
{
227
    kaguya::LuaRef getAllowedAddons = lua["getAllowedAddons"];
8✔
228
    if(getAllowedAddons.type() == LUA_TFUNCTION)
4✔
229
    {
230
        kaguya::LuaRef addons = getAllowedAddons();
3✔
231
        if(addons.typeTest<std::vector<AddonIdWrapper>>())
3✔
232
        {
233
            const std::vector<AddonIdWrapper> wrappers = addons;
1✔
234
            return {wrappers.begin(), wrappers.end()};
1✔
235
        } else
236
            LOG.write("Invalid type returned by getAllowedAddons");
2✔
237
    }
238
    return std::vector<AddonId>();
3✔
239
}
240

241
bool LuaInterfaceSettings::IsMapPreviewEnabled()
3✔
242
{
243
    kaguya::LuaRef func = lua["isMapPreviewEnabled"];
6✔
244
    if(func.type() == LUA_TFUNCTION)
3✔
245
    {
246
        return func.call<bool>();
2✔
247
    }
248
    return true;
1✔
249
}
250

NEW
251
unsigned LuaInterfaceSettings::GetNumPlayersFromScript()
×
252
{
NEW
253
    kaguya::LuaRef func = lua["getNumPlayers"];
×
NEW
254
    if(func.type() == LUA_TFUNCTION)
×
255
    {
NEW
256
        return func.call<unsigned>();
×
257
    }
NEW
258
    return 0;
×
259
}
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