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

Return-To-The-Roots / s25client / 12454926545

22 Dec 2024 02:06PM UTC coverage: 50.23% (+0.005%) from 50.225%
12454926545

Pull #1681

github

web-flow
Merge 2ae89be01 into 17844c810
Pull Request #1681: Add support for campaign status

57 of 112 new or added lines in 10 files covered. (50.89%)

3 existing lines in 3 files now uncovered.

22360 of 44515 relevant lines covered (50.23%)

35626.14 hits per line

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

96.83
/libs/s25main/lua/LuaInterfaceGame.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 "LuaInterfaceGame.h"
6
#include "EventManager.h"
7
#include "Game.h"
8
#include "Settings.h"
9
#include "WindowManager.h"
10
#include "ai/AIInterface.h"
11
#include "ai/AIPlayer.h"
12
#include "ingameWindows/iwMissionStatement.h"
13
#include "lua/LuaHelpers.h"
14
#include "lua/LuaPlayer.h"
15
#include "lua/LuaWorld.h"
16
#include "network/GameClient.h"
17
#include "postSystem/PostMsg.h"
18
#include "world/GameWorld.h"
19
#include "gameTypes/Resource.h"
20
#include "gameData/CampaignSaveCodes.h"
21
#include "s25util/Serializer.h"
22
#include "s25util/strAlgos.h"
23

24
LuaInterfaceGame::LuaInterfaceGame(Game& gameInstance, ILocalGameState& localGameState)
27✔
25
    : LuaInterfaceGameBase(localGameState), localGameState(localGameState), gw(gameInstance.world_), game(gameInstance)
27✔
26
{
27
#pragma region ConstDefs
28
#define ADD_LUA_CONST(name) lua["BLD_" + s25util::toUpper(#name)] = BuildingType::name
29
    ADD_LUA_CONST(Headquarters);
27✔
30
    ADD_LUA_CONST(Barracks);
27✔
31
    ADD_LUA_CONST(Guardhouse);
27✔
32
    ADD_LUA_CONST(Watchtower);
27✔
33
    ADD_LUA_CONST(Fortress);
27✔
34
    ADD_LUA_CONST(GraniteMine);
27✔
35
    ADD_LUA_CONST(CoalMine);
27✔
36
    ADD_LUA_CONST(IronMine);
27✔
37
    ADD_LUA_CONST(GoldMine);
27✔
38
    ADD_LUA_CONST(LookoutTower);
27✔
39
    ADD_LUA_CONST(Catapult);
27✔
40
    ADD_LUA_CONST(Woodcutter);
27✔
41
    ADD_LUA_CONST(Fishery);
27✔
42
    ADD_LUA_CONST(Quarry);
27✔
43
    ADD_LUA_CONST(Forester);
27✔
44
    ADD_LUA_CONST(Slaughterhouse);
27✔
45
    ADD_LUA_CONST(Hunter);
27✔
46
    ADD_LUA_CONST(Brewery);
27✔
47
    ADD_LUA_CONST(Armory);
27✔
48
    ADD_LUA_CONST(Metalworks);
27✔
49
    ADD_LUA_CONST(Ironsmelter);
27✔
50
    ADD_LUA_CONST(Charburner);
27✔
51
    ADD_LUA_CONST(PigFarm);
27✔
52
    ADD_LUA_CONST(Storehouse);
27✔
53
    ADD_LUA_CONST(Mill);
27✔
54
    ADD_LUA_CONST(Bakery);
27✔
55
    ADD_LUA_CONST(Sawmill);
27✔
56
    ADD_LUA_CONST(Mint);
27✔
57
    ADD_LUA_CONST(Well);
27✔
58
    ADD_LUA_CONST(Shipyard);
27✔
59
    ADD_LUA_CONST(Farm);
27✔
60
    ADD_LUA_CONST(DonkeyBreeder);
27✔
61
    ADD_LUA_CONST(HarborBuilding);
27✔
62
    ADD_LUA_CONST(Vineyard);
27✔
63
    ADD_LUA_CONST(Winery);
27✔
64
    ADD_LUA_CONST(Temple);
27✔
65
#undef ADD_LUA_CONST
66

67
#define ADD_LUA_CONST(name) lua["JOB_" + s25util::toUpper(#name)] = Job::name
68
    ADD_LUA_CONST(Helper);
27✔
69
    ADD_LUA_CONST(Woodcutter);
27✔
70
    ADD_LUA_CONST(Fisher);
27✔
71
    ADD_LUA_CONST(Forester);
27✔
72
    ADD_LUA_CONST(Carpenter);
27✔
73
    ADD_LUA_CONST(Stonemason);
27✔
74
    ADD_LUA_CONST(Hunter);
27✔
75
    ADD_LUA_CONST(Farmer);
27✔
76
    ADD_LUA_CONST(Miller);
27✔
77
    ADD_LUA_CONST(Baker);
27✔
78
    ADD_LUA_CONST(Butcher);
27✔
79
    ADD_LUA_CONST(Miner);
27✔
80
    ADD_LUA_CONST(Brewer);
27✔
81
    ADD_LUA_CONST(PigBreeder);
27✔
82
    ADD_LUA_CONST(DonkeyBreeder);
27✔
83
    ADD_LUA_CONST(IronFounder);
27✔
84
    ADD_LUA_CONST(Minter);
27✔
85
    ADD_LUA_CONST(Metalworker);
27✔
86
    ADD_LUA_CONST(Armorer);
27✔
87
    ADD_LUA_CONST(Builder);
27✔
88
    ADD_LUA_CONST(Planer);
27✔
89
    ADD_LUA_CONST(Private);
27✔
90
    ADD_LUA_CONST(PrivateFirstClass);
27✔
91
    ADD_LUA_CONST(Sergeant);
27✔
92
    ADD_LUA_CONST(Officer);
27✔
93
    ADD_LUA_CONST(General);
27✔
94
    ADD_LUA_CONST(Geologist);
27✔
95
    ADD_LUA_CONST(Shipwright);
27✔
96
    ADD_LUA_CONST(Scout);
27✔
97
    ADD_LUA_CONST(PackDonkey);
27✔
98
    ADD_LUA_CONST(BoatCarrier);
27✔
99
    ADD_LUA_CONST(CharBurner);
27✔
100
    ADD_LUA_CONST(Winegrower);
27✔
101
    ADD_LUA_CONST(Vintner);
27✔
102
    ADD_LUA_CONST(TempleServant);
27✔
103
#undef ADD_LUA_CONST
104

105
#define ADD_LUA_CONST(name) lua["STAT_" + s25util::toUpper(#name)] = StatisticType::name
106
    ADD_LUA_CONST(Country);
27✔
107
    ADD_LUA_CONST(Buildings);
27✔
108
    ADD_LUA_CONST(Inhabitants);
27✔
109
    ADD_LUA_CONST(Merchandise);
27✔
110
    ADD_LUA_CONST(Military);
27✔
111
    ADD_LUA_CONST(Gold);
27✔
112
    ADD_LUA_CONST(Productivity);
27✔
113
    ADD_LUA_CONST(Vanquished);
27✔
114
    ADD_LUA_CONST(Tournament);
27✔
115
#undef ADD_LUA_CONST
116

117
#define ADD_LUA_CONST(name) lua["GD_" + s25util::toUpper(#name)] = GoodType::name
118
    ADD_LUA_CONST(Beer);
27✔
119
    ADD_LUA_CONST(Tongs);
27✔
120
    ADD_LUA_CONST(Hammer);
27✔
121
    ADD_LUA_CONST(Axe);
27✔
122
    ADD_LUA_CONST(Saw);
27✔
123
    ADD_LUA_CONST(PickAxe);
27✔
124
    ADD_LUA_CONST(Shovel);
27✔
125
    ADD_LUA_CONST(Crucible);
27✔
126
    ADD_LUA_CONST(RodAndLine);
27✔
127
    ADD_LUA_CONST(Scythe);
27✔
128
    ADD_LUA_CONST(Water);
27✔
129
    ADD_LUA_CONST(Cleaver);
27✔
130
    ADD_LUA_CONST(Rollingpin);
27✔
131
    ADD_LUA_CONST(Bow);
27✔
132
    ADD_LUA_CONST(Boat);
27✔
133
    ADD_LUA_CONST(Sword);
27✔
134
    ADD_LUA_CONST(Iron);
27✔
135
    ADD_LUA_CONST(Flour);
27✔
136
    ADD_LUA_CONST(Fish);
27✔
137
    ADD_LUA_CONST(Bread);
27✔
138
    lua["GD_SHIELD"] = GoodType::ShieldRomans;
27✔
139
    ADD_LUA_CONST(Wood);
27✔
140
    ADD_LUA_CONST(Boards);
27✔
141
    ADD_LUA_CONST(Stones);
27✔
142
    ADD_LUA_CONST(Grain);
27✔
143
    ADD_LUA_CONST(Coins);
27✔
144
    ADD_LUA_CONST(Gold);
27✔
145
    ADD_LUA_CONST(IronOre);
27✔
146
    ADD_LUA_CONST(Coal);
27✔
147
    ADD_LUA_CONST(Meat);
27✔
148
    ADD_LUA_CONST(Ham);
27✔
149
    ADD_LUA_CONST(Grapes);
27✔
150
    ADD_LUA_CONST(Wine);
27✔
151
#undef ADD_LUA_CONST
152

153
#define ADD_LUA_CONST(name) lua["RES_" + s25util::toUpper(#name)] = ResourceType::name
154
    ADD_LUA_CONST(Iron);
27✔
155
    ADD_LUA_CONST(Gold);
27✔
156
    ADD_LUA_CONST(Coal);
27✔
157
    ADD_LUA_CONST(Granite);
27✔
158
    ADD_LUA_CONST(Water);
27✔
159
#undef ADD_LUA_CONST
160

161
#define ADD_LUA_CONST(name) lua[#name] = name
162
    lua["NON_AGGRESSION_PACT"] = PactType::NonAgressionPact;
27✔
163
    lua["TREATY_OF_ALLIANCE"] = PactType::TreatyOfAlliance;
27✔
164
    // infinite pact duration, see GamePlayer::GetRemainingPactTime
165
    ADD_LUA_CONST(DURATION_INFINITE);
27✔
166
#undef ADD_LUA_CONST
167

168
#define ADD_LUA_CONST(name) lua[#name] = iwMissionStatement::name
169
    ADD_LUA_CONST(IM_NONE);
27✔
170
    ADD_LUA_CONST(IM_SWORDSMAN);
27✔
171
    ADD_LUA_CONST(IM_READER);
27✔
172
    ADD_LUA_CONST(IM_RIDER);
27✔
173
    ADD_LUA_CONST(IM_AVATAR1);
27✔
174
    ADD_LUA_CONST(IM_AVATAR2);
27✔
175
    ADD_LUA_CONST(IM_AVATAR3);
27✔
176
    ADD_LUA_CONST(IM_AVATAR4);
27✔
177
    ADD_LUA_CONST(IM_AVATAR5);
27✔
178
    ADD_LUA_CONST(IM_AVATAR6);
27✔
179
    ADD_LUA_CONST(IM_AVATAR7);
27✔
180
    ADD_LUA_CONST(IM_AVATAR8);
27✔
181
    ADD_LUA_CONST(IM_AVATAR9);
27✔
182
    ADD_LUA_CONST(IM_AVATAR10);
27✔
183
    ADD_LUA_CONST(IM_AVATAR11);
27✔
184
    ADD_LUA_CONST(IM_AVATAR12);
27✔
185

186
#undef ADD_LUA_CONST
187
#pragma endregion ConstDefs
188

189
    Register(lua);
27✔
190
    LuaPlayer::Register(lua);
27✔
191
    LuaWorld::Register(lua);
27✔
192

193
    lua["rttr"] = this;
27✔
194
}
27✔
195

196
LuaInterfaceGame::~LuaInterfaceGame() = default;
54✔
197

198
KAGUYA_MEMBER_FUNCTION_OVERLOADS(SetMissionGoalWrapper, LuaInterfaceGame, SetMissionGoal, 1, 2)
60✔
199

200
void LuaInterfaceGame::Register(kaguya::State& state)
27✔
201
{
202
    state["RTTRGame"].setClass(
27✔
203
      kaguya::UserdataMetatable<LuaInterfaceGame, LuaInterfaceGameBase>()
54✔
204
        .addFunction("ClearResources", &LuaInterfaceGame::ClearResources)
27✔
205
        .addFunction("GetGF", &LuaInterfaceGame::GetGF)
27✔
206
        .addFunction("FormatNumGFs", &LuaInterfaceGame::FormatNumGFs)
27✔
207
        .addFunction("GetGameFrame", &LuaInterfaceGame::GetGF)
27✔
208
        .addFunction("GetNumPlayers", &LuaInterfaceGame::GetNumPlayers)
27✔
209
        .addFunction("Chat", &LuaInterfaceGame::Chat)
27✔
210
        .addOverloadedFunctions("MissionStatement", &LuaInterfaceGame::MissionStatement,
211
                                &LuaInterfaceGame::MissionStatement2, &LuaInterfaceGame::MissionStatement3)
27✔
212
        .addFunction("SetMissionGoal", SetMissionGoalWrapper())
54✔
213
        .addFunction("PostMessage", &LuaInterfaceGame::PostMessageLua)
27✔
214
        .addFunction("PostMessageWithLocation", &LuaInterfaceGame::PostMessageWithLocation)
27✔
215
        .addFunction("EnableCampaignChapter", &LuaInterfaceGame::EnableCampaignChapter)
27✔
216
        .addFunction("SetCampaignChapterCompleted", &LuaInterfaceGame::SetCampaignChapterCompleted)
27✔
217
        .addFunction("SetCampaignCompleted", &LuaInterfaceGame::SetCampaignCompleted)
27✔
218
        .addFunction("GetPlayer", &LuaInterfaceGame::GetPlayer)
27✔
219
        .addFunction("GetWorld", &LuaInterfaceGame::GetWorld)
27✔
220
        // Old name
221
        .addFunction("GetPlayerCount", &LuaInterfaceGame::GetNumPlayers));
27✔
222
    state["RTTR_Serializer"].setClass(kaguya::UserdataMetatable<Serializer>()
54✔
223
                                        .addFunction("PushInt", &Serializer::PushSignedInt)
27✔
224
                                        .addFunction("PopInt", &Serializer::PopSignedInt)
27✔
225
                                        .addFunction("PushBool", &Serializer::PushBool)
27✔
226
                                        .addFunction("PopBool", &Serializer::PopBool)
27✔
227
                                        .addFunction("PushString", &Serializer::PushString)
27✔
228
                                        .addFunction("PopString", &Serializer::PopString));
27✔
229
}
27✔
230

231
bool LuaInterfaceGame::Serialize(Serializer& luaSaveState)
7✔
232
{
233
    kaguya::LuaRef save = lua["onSave"];
14✔
234
    if(save.type() == LUA_TFUNCTION)
7✔
235
    {
236
        clearErrorOccured();
4✔
237
        if(save.call<bool>(kaguya::standard::ref(luaSaveState)) && !hasErrorOccurred())
4✔
238
            return true;
1✔
239
        else
240
        {
241
            luaSaveState.Clear();
2✔
242
            return false;
2✔
243
        }
244
    } else
245
        return true;
3✔
246
}
247

248
bool LuaInterfaceGame::Deserialize(Serializer& luaSaveState)
5✔
249
{
250
    kaguya::LuaRef load = lua["onLoad"];
10✔
251
    if(load.type() == LUA_TFUNCTION)
5✔
252
    {
253
        clearErrorOccured();
3✔
254
        return load.call<bool>(kaguya::standard::ref(luaSaveState)) && !hasErrorOccurred();
3✔
255
    } else
256
        return true;
2✔
257
}
258

259
void LuaInterfaceGame::ClearResources()
1✔
260
{
261
    for(unsigned p = 0; p < gw.GetNumPlayers(); p++)
4✔
262
        GetPlayer(p).ClearResources();
3✔
263
}
1✔
264

265
unsigned LuaInterfaceGame::GetGF() const
2✔
266
{
267
    return gw.GetEvMgr().GetCurrentGF();
2✔
268
}
269

270
std::string LuaInterfaceGame::FormatNumGFs(unsigned numGFs) const
1✔
271
{
272
    return localGameState.FormatGFTime(numGFs);
1✔
273
}
274

275
unsigned LuaInterfaceGame::GetNumPlayers() const
1✔
276
{
277
    return gw.GetNumPlayers();
1✔
278
}
279

280
void LuaInterfaceGame::Chat(int playerIdx, const std::string& msg)
3✔
281
{
282
    if(playerIdx >= 0 && localGameState.GetPlayerId() != unsigned(playerIdx))
3✔
283
        return;
1✔
284

285
    localGameState.SystemChat(msg);
2✔
286
}
287

288
void LuaInterfaceGame::MissionStatement(int playerIdx, const std::string& title, const std::string& msg)
4✔
289
{
290
    MissionStatement2(playerIdx, title, msg, iwMissionStatement::IM_SWORDSMAN);
4✔
291
}
4✔
292

293
void LuaInterfaceGame::MissionStatement2(int playerIdx, const std::string& title, const std::string& msg,
7✔
294
                                         unsigned imgIdx)
295
{
296
    MissionStatement3(playerIdx, title, msg, imgIdx, true);
7✔
297
}
7✔
298

299
void LuaInterfaceGame::MissionStatement3(int playerIdx, const std::string& title, const std::string& msg,
7✔
300
                                         unsigned imgIdx, bool pause)
301
{
302
    if(playerIdx >= 0 && localGameState.GetPlayerId() != unsigned(playerIdx))
7✔
303
        return;
2✔
304

305
    WINDOWMANAGER.Show(std::make_unique<iwMissionStatement>(_(title), msg, gw.IsSinglePlayer() && pause,
15✔
306
                                                            iwMissionStatement::HelpImage(imgIdx)));
15✔
307
}
308

309
void LuaInterfaceGame::SetMissionGoal(int playerIdx, const std::string& newGoal)
6✔
310
{
311
    gw.GetPostMgr().SetMissionGoal(playerIdx, newGoal);
6✔
312
}
6✔
313

314
// Must not be PostMessage as this is a windows define :(
315
void LuaInterfaceGame::PostMessageLua(int playerIdx, const std::string& msg)
3✔
316
{
317
    lua::assertTrue(playerIdx >= 0, "Invalid player idx");
5✔
318
    gw.GetPostMgr().SendMsg(static_cast<unsigned>(playerIdx),
4✔
319
                            std::make_unique<PostMsg>(gw.GetEvMgr().GetCurrentGF(), msg, PostCategory::General));
4✔
320
}
2✔
321

322
void LuaInterfaceGame::PostMessageWithLocation(int playerIdx, const std::string& msg, int x, int y)
1✔
323
{
324
    lua::assertTrue(playerIdx >= 0, "Invalid player idx");
1✔
325
    gw.GetPostMgr().SendMsg(static_cast<unsigned>(playerIdx),
2✔
326
                            std::make_unique<PostMsg>(gw.GetEvMgr().GetCurrentGF(), msg, PostCategory::General,
2✔
327
                                                      gw.MakeMapPoint(Position(x, y))));
1✔
328
}
1✔
329

330
namespace {
331
void MarkCampaignChapter(const std::string& campaignUid, unsigned char chapter, char code)
6✔
332
{
333
    if(chapter < 1)
6✔
334
        return;
2✔
335

336
    auto& saveData = SETTINGS.campaigns.saveData[campaignUid];
4✔
337

338
    if(saveData.length() < chapter)
4✔
339
        saveData.resize(chapter);
2✔
340

341
    auto& chapterSaveData = saveData[chapter - 1];
4✔
342

343
    if(chapterSaveData == CampaignSaveCodes::chapterCompleted)
4✔
344
        return;
1✔
345

346
    chapterSaveData = code;
3✔
347
}
348
} // namespace
349

350
void LuaInterfaceGame::EnableCampaignChapter(const std::string& campaignUid, unsigned char chapter)
3✔
351
{
352
    MarkCampaignChapter(campaignUid, chapter, CampaignSaveCodes::chapterEnabled);
3✔
353
}
3✔
354

355
void LuaInterfaceGame::SetCampaignChapterCompleted(const std::string& campaignUid, unsigned char chapter)
3✔
356
{
357
    MarkCampaignChapter(campaignUid, chapter, CampaignSaveCodes::chapterCompleted);
3✔
358
    GAMECLIENT.SetCampaignChapterCompleted(chapter);
3✔
359
}
3✔
360

NEW
361
void LuaInterfaceGame::SetCampaignCompleted(const std::string& /* campaignUid */)
×
362
{
NEW
363
    GAMECLIENT.SetCampaignCompleted(true);
×
NEW
364
}
×
365

366
LuaPlayer LuaInterfaceGame::GetPlayer(int playerIdx)
21✔
367
{
368
    lua::assertTrue(playerIdx >= 0 && static_cast<unsigned>(playerIdx) < gw.GetNumPlayers(), "Invalid player idx");
23✔
369
    return LuaPlayer(game, gw.GetPlayer(static_cast<unsigned>(playerIdx)));
19✔
370
}
371

372
LuaWorld LuaInterfaceGame::GetWorld()
10✔
373
{
374
    return LuaWorld(gw);
10✔
375
}
376

377
void LuaInterfaceGame::EventExplored(unsigned player, const MapPoint pt, unsigned char owner)
13,107✔
378
{
379
    kaguya::LuaRef onExplored = lua["onExplored"];
26,214✔
380
    if(onExplored.type() == LUA_TFUNCTION)
13,107✔
381
    {
382
        if(owner == 0)
938✔
383
        {
384
            // No owner? Pass nil value to Lua.
385
            onExplored.call<void>(player, pt.x, pt.y, kaguya::NilValue());
347✔
386
        } else
387
        {
388
            // Adapt owner to be comparable with the player index
389
            onExplored.call<void>(player, pt.x, pt.y, owner - 1);
591✔
390
        }
391
    }
392
}
13,107✔
393

394
void LuaInterfaceGame::EventOccupied(unsigned player, const MapPoint pt)
7,589✔
395
{
396
    kaguya::LuaRef onOccupied = lua["onOccupied"];
15,178✔
397
    if(onOccupied.type() == LUA_TFUNCTION)
7,589✔
398
        onOccupied.call<void>(player, pt.x, pt.y);
542✔
399
}
7,589✔
400

401
void LuaInterfaceGame::EventAttack(unsigned char attackerPlayerId, unsigned char defenderPlayerId,
2✔
402
                                   unsigned attackerCount)
403
{
404
    kaguya::LuaRef onAttack = lua["onAttack"];
4✔
405
    if(onAttack.type() == LUA_TFUNCTION)
2✔
406
        onAttack.call<void>(attackerPlayerId, defenderPlayerId, attackerCount);
1✔
407
}
2✔
408

409
void LuaInterfaceGame::EventStart(bool isFirstStart)
3✔
410
{
411
    kaguya::LuaRef onStart = lua["onStart"];
6✔
412
    if(onStart.type() == LUA_TFUNCTION)
3✔
413
        onStart.call<void>(isFirstStart);
2✔
414
}
3✔
415

NEW
416
void LuaInterfaceGame::EventHumanWinner()
×
417
{
NEW
418
    kaguya::LuaRef onStart = lua["onHumanWinner"];
×
NEW
419
    if(onStart.type() == LUA_TFUNCTION)
×
NEW
420
        onStart.call<void>();
×
NEW
421
}
×
422

423
void LuaInterfaceGame::EventGameFrame(unsigned nr)
3✔
424
{
425
    kaguya::LuaRef onGameFrame = lua["onGameFrame"];
6✔
426
    if(onGameFrame.type() == LUA_TFUNCTION)
3✔
427
        onGameFrame.call<void>(nr);
2✔
428
}
3✔
429

430
void LuaInterfaceGame::EventResourceFound(unsigned char player, const MapPoint pt, ResourceType type,
6✔
431
                                          unsigned char quantity)
432
{
433
    kaguya::LuaRef onResourceFound = lua["onResourceFound"];
12✔
434
    if(onResourceFound.type() == LUA_TFUNCTION)
6✔
435
        onResourceFound.call<void>(player, pt.x, pt.y, type, quantity);
5✔
436
}
6✔
437

438
bool LuaInterfaceGame::EventCancelPactRequest(PactType pt, unsigned char canceledByPlayerId,
1✔
439
                                              unsigned char targetPlayerId)
440
{
441
    kaguya::LuaRef onPactCancel = lua["onCancelPactRequest"];
2✔
442
    if(onPactCancel.type() == LUA_TFUNCTION)
1✔
443
        return onPactCancel.call<bool>(pt, canceledByPlayerId, targetPlayerId);
1✔
444
    return true; // always accept pact cancel if there is no handler
×
445
}
446

447
void LuaInterfaceGame::EventSuggestPact(const PactType pt, unsigned char suggestedByPlayerId,
2✔
448
                                        unsigned char targetPlayerId, const unsigned duration)
449
{
450
    AIPlayer* ai = game.GetAIPlayer(targetPlayerId);
2✔
451
    if(ai != nullptr)
2✔
452
    {
453
        kaguya::LuaRef onPactCancel = lua["onSuggestPact"];
4✔
454
        if(onPactCancel.type() == LUA_TFUNCTION)
2✔
455
        {
456
            AIInterface& aii = ai->getAIInterface();
2✔
457
            auto luaResult = onPactCancel.call<bool>(pt, suggestedByPlayerId, targetPlayerId, duration);
2✔
458
            if(luaResult)
2✔
459
                aii.AcceptPact(gw.GetEvMgr().GetCurrentGF(), pt, suggestedByPlayerId);
2✔
460
            else
461
                aii.CancelPact(pt, suggestedByPlayerId);
×
462
        }
463
    }
464
}
2✔
465

466
void LuaInterfaceGame::EventPactCanceled(const PactType pt, unsigned char canceledByPlayerId,
2✔
467
                                         unsigned char targetPlayerId)
468
{
469
    kaguya::LuaRef onPactCanceled = lua["onPactCanceled"];
4✔
470
    if(onPactCanceled.type() == LUA_TFUNCTION)
2✔
471
    {
472
        onPactCanceled.call<void>(pt, canceledByPlayerId, targetPlayerId);
2✔
473
    }
474
}
2✔
475

476
void LuaInterfaceGame::EventPactCreated(const PactType pt, unsigned char suggestedByPlayerId,
3✔
477
                                        unsigned char targetPlayerId, const unsigned duration)
478
{
479
    kaguya::LuaRef onPactCreated = lua["onPactCreated"];
6✔
480
    if(onPactCreated.type() == LUA_TFUNCTION)
3✔
481
    {
482
        onPactCreated.call<void>(pt, suggestedByPlayerId, targetPlayerId, duration);
3✔
483
    }
484
}
3✔
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