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

Return-To-The-Roots / s25client / 21283273387

23 Jan 2026 10:39AM UTC coverage: 50.757% (+0.09%) from 50.663%
21283273387

Pull #1679

github

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

94 of 155 new or added lines in 12 files covered. (60.65%)

7 existing lines in 5 files now uncovered.

22798 of 44916 relevant lines covered (50.76%)

41539.59 hits per line

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

29.9
/libs/s25main/ingameWindows/iwAction.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 "iwAction.h"
6
#include "Cheats.h"
7
#include "GameInterface.h"
8
#include "GamePlayer.h"
9
#include "GlobalGameSettings.h"
10
#include "Loader.h"
11
#include "WindowManager.h"
12
#include "addons/const_addons.h"
13
#include "buildings/nobMilitary.h"
14
#include "controls/ctrlBuildingIcon.h"
15
#include "controls/ctrlGroup.h"
16
#include "controls/ctrlOptionGroup.h"
17
#include "controls/ctrlTab.h"
18
#include "drivers/VideoDriverWrapper.h"
19
#include "iwDemolishBuilding.h"
20
#include "iwMilitaryBuilding.h"
21
#include "iwObservate.h"
22
#include "network/GameClient.h"
23
#include "ogl/FontStyle.h"
24
#include "ogl/glFont.h"
25
#include "world/GameWorldBase.h"
26
#include "world/GameWorldView.h"
27
#include "world/GameWorldViewer.h"
28
#include "nodeObjs/noFlag.h"
29
#include "gameData/BuildingConsts.h"
30
#include "gameData/const_gui_ids.h"
31
#include <sstream>
32

33
// Tab - Flags
34
enum TabID
35
{
36
    TAB_BUILD = 1,
37
    TAB_SETFLAG,
38
    TAB_WATCH,
39
    TAB_FLAG,
40
    TAB_CUTROAD,
41
    TAB_ATTACK,
42
    TAB_SEAATTACK,
43
    TAB_CHEAT
44
};
45

46
iwAction::iwAction(GameInterface& gi, GameWorldView& gwv, const Tabs& tabs, MapPoint selectedPt,
2✔
47
                   const DrawPoint& mousePos, Params params, bool military_buildings)
2✔
48
    : IngameWindow(CGI_ACTION, mousePos, Extent(200, 254), _("Activity window"), LOADER.GetImageN("io", 1)), gi(gi),
4✔
49
      gwv(gwv), selectedPt(selectedPt), mousePosAtOpen_(mousePos)
6✔
50
{
51
    /*
52
        TAB_FLAG    1 = Land road
53
        TAB_FLAG    2 = Waterway
54
        TAB_FLAG    3 = Pull down flag
55
        TAB_FLAG    4 = Send geologist
56
        TAB_FLAG    5 = Send scout
57

58
        TAB_CUTROAD 1 = Cut Road
59

60
        TAB_BUILD   100-108, 200-212, 300-303, 400-403 = Buildings
61

62
        TAB_SETFLAG 1 = Erect flag
63

64
        TAB_WATCH   1 =
65
        TAB_WATCH   2 =
66
        TAB_WATCH   3 = zum HQ
67
        TAB_WATCH        4 = notify allies of location
68

69
        TAB_ATTACK  1 = Less soldiers
70
        TAB_ATTACK  2 = More soldiers
71
        TAB_ATTACK  3 = Option group: Better/Weaker
72
        TAB_ATTACK  4 = Angriff
73
        TAB_ATTACK  10-14 = Direktauswahl Anzahl
74

75
        TAB_CHEAT   1 = Place cheat building
76
    */
77

78
    const GamePlayer& player = gwv.GetViewer().GetPlayer();
2✔
79

80
    /// Haupttab
81
    ctrlTab* main_tab = AddTabCtrl(0, DrawPoint(10, 20), 180);
2✔
82

83
    // Bau-main_tab
84
    if(tabs.build)
2✔
85
    {
86
        ctrlGroup* group = main_tab->AddTab(LOADER.GetImageN("io", 18), _("-> Build house"), TAB_BUILD);
2✔
87

88
        ctrlTab* build_tab = group->AddTabCtrl(1, DrawPoint(0, 45), 180);
1✔
89

90
        // Building tabs
91
        if(tabs.build_tabs == BuildTab::Mine) // mines
1✔
92
            build_tab->AddTab(LOADER.GetImageN("io", 76), _("-> Dig mines"), int(BuildTab::Mine));
×
93
        else
94
        {
95
            build_tab->AddTab(LOADER.GetImageN("io", 67), _("-> Build hut"), int(BuildTab::Hut));
2✔
96
            if(tabs.build_tabs >= BuildTab::House)
1✔
97
                build_tab->AddTab(LOADER.GetImageN("io", 68), _("-> Build house"), int(BuildTab::House));
2✔
98
            if(tabs.build_tabs >= BuildTab::Castle) // castle & harbor
1✔
99
                build_tab->AddTab(LOADER.GetImageN("io", 69), _("-> Build castle"), int(BuildTab::Castle));
2✔
100
        }
101

102
        // add building icons to TabCtrl. Note: None for BuildTab::Harbor (last)
103
        const helpers::EnumArray<std::vector<BuildingType>, BuildTab> building_icons = {
104
          // Linebreak
105
          {{BuildingType::Woodcutter, BuildingType::Forester, BuildingType::Quarry, BuildingType::Fishery,
106
            BuildingType::Hunter, BuildingType::Barracks, BuildingType::Guardhouse, BuildingType::LookoutTower,
107
            BuildingType::Well},
108
           {BuildingType::Sawmill, BuildingType::Slaughterhouse, BuildingType::Mill, BuildingType::Bakery,
109
            BuildingType::Ironsmelter, BuildingType::Metalworks, BuildingType::Armory, BuildingType::Mint,
110
            BuildingType::Shipyard, BuildingType::Brewery, BuildingType::Winery, BuildingType::Storehouse,
111
            BuildingType::Watchtower, BuildingType::Catapult},
112
           {BuildingType::Farm, BuildingType::PigFarm, BuildingType::DonkeyBreeder, BuildingType::Charburner,
113
            BuildingType::Vineyard, BuildingType::Temple, BuildingType::Fortress, BuildingType::HarborBuilding},
114
           {BuildingType::GoldMine, BuildingType::IronMine, BuildingType::CoalMine, BuildingType::GraniteMine}}};
2✔
115

116
        /// Flexible what-buildings-are-available handling
117
        helpers::EnumArray<bool, BuildingType> building_available;
118

119
        // First enable all buildings
120
        for(const auto bld : helpers::enumRange<BuildingType>())
84✔
121
            building_available[bld] = player.IsBuildingEnabled(bld);
40✔
122

123
        // Now deactivate those we don't want
124

125
        if(tabs.build_tabs != BuildTab::Harbor)
1✔
126
            building_available[BuildingType::HarborBuilding] = false;
1✔
127

128
        if(!military_buildings)
1✔
129
        {
130
            building_available[BuildingType::Barracks] = false;
×
131
            building_available[BuildingType::Guardhouse] = false;
×
132
            building_available[BuildingType::Watchtower] = false;
×
133
            building_available[BuildingType::Fortress] = false;
×
134
        }
135

136
        if(gwv.GetWorld().GetGGS().isEnabled(AddonId::CHANGE_GOLD_DEPOSITS))
1✔
137
        {
138
            building_available[BuildingType::GoldMine] = false;
×
139
            building_available[BuildingType::Mint] = false;
×
140
        }
141

142
        if(!player.CanBuildCatapult())
1✔
143
            building_available[BuildingType::Catapult] = false;
×
144

145
        if(!gwv.GetWorld().GetGGS().isEnabled(AddonId::CHARBURNER))
1✔
146
            building_available[BuildingType::Charburner] = false;
1✔
147

148
        if(!gwv.GetWorld().GetGGS().isEnabled(AddonId::WINE))
1✔
149
        {
150
            building_available[BuildingType::Vineyard] = false;
1✔
151
            building_available[BuildingType::Winery] = false;
1✔
152
            building_available[BuildingType::Temple] = false;
1✔
153
        }
154

155
        constexpr helpers::EnumArray<unsigned, BuildTab> NUM_TABS = {1, 2, 3, 1, 3};
1✔
156

157
        for(unsigned char i = 0; i < NUM_TABS[tabs.build_tabs]; ++i)
4✔
158
        {
159
            unsigned char k = 0;
3✔
160
            const BuildTab bt = (tabs.build_tabs == BuildTab::Mine) ? BuildTab::Mine : BuildTab(i);
3✔
161

162
            for(const BuildingType bld : building_icons[bt])
34✔
163
            {
164
                if(!building_available[bld])
31✔
165
                    continue;
5✔
166

167
                // Baukosten im Tooltip mit anzeigen
168
                std::stringstream tooltip;
26✔
169
                tooltip << _(BUILDING_NAMES[bld]);
26✔
170

171
                tooltip << _("\nCosts: ");
26✔
172
                if(BUILDING_COSTS[bld].boards > 0)
26✔
173
                    tooltip << (int)BUILDING_COSTS[bld].boards << _(" boards");
26✔
174
                if(BUILDING_COSTS[bld].stones > 0)
26✔
175
                {
176
                    if(BUILDING_COSTS[bld].boards > 0)
18✔
177
                        tooltip << ", ";
18✔
178
                    tooltip << (int)BUILDING_COSTS[bld].stones << _(" stones");
18✔
179
                }
180

181
                DrawPoint iconPos((k % 5) * 36, (k / 5) * 36 + 45);
26✔
182
                build_tab->GetGroup(static_cast<int>(bt))
26✔
183
                  ->AddBuildingIcon(k, iconPos, bld, player.nation, 36, tooltip.str());
26✔
184

185
                ++k;
26✔
186
            }
187

188
            building_tab_heights[static_cast<int>(bt)] = (k / 5 + ((k % 5 != 0) ? 1 : 0)) * 36 + 150;
3✔
189
        }
190

191
        build_tab->SetSelection(0, true);
1✔
192
    }
193

194
    // Wenn es einen Flaggen-main_tab gibt, dann entsprechend die Buttons anordnen, wie sie gebraucht werden
195
    if(tabs.flag)
2✔
196
    {
197
        ctrlGroup* group = main_tab->AddTab(LOADER.GetImageN("io", 70), _("Erect flag"), TAB_FLAG);
×
198

199
        switch(get<FlagType>(params))
×
200
        {
201
            case FlagType::Normal:
×
202
            {
203
                group->AddImageButton(1, DrawPoint(0, 45), Extent(45, 36), TextureColor::Grey,
×
204
                                      LOADER.GetImageN("io", 65), _("Build road"));
×
205
                group->AddImageButton(3, DrawPoint(45, 45), Extent(45, 36), TextureColor::Grey,
×
206
                                      LOADER.GetImageN("io", 118), _("Pull down flag"));
×
207
                group->AddImageButton(4, DrawPoint(90, 45), Extent(45, 36), TextureColor::Grey,
×
208
                                      LOADER.GetImageN("io", 20), _("Call in geologist"));
×
209
                group->AddImageButton(5, DrawPoint(135, 45), Extent(45, 36), TextureColor::Grey,
×
210
                                      LOADER.GetImageN("io", 96), _("Send out scout"));
×
211
            }
212
            break;
×
213
            case FlagType::WaterFlag:
×
214
            {
215
                group->AddImageButton(1, DrawPoint(0, 45), Extent(36, 36), TextureColor::Grey,
×
216
                                      LOADER.GetImageN("io", 65), _("Build road"));
×
217
                group->AddImageButton(2, DrawPoint(36, 45), Extent(36, 36), TextureColor::Grey,
×
218
                                      LOADER.GetImageN("io", 95), _("Build waterway"));
×
219
                group->AddImageButton(3, DrawPoint(72, 45), Extent(36, 36), TextureColor::Grey,
×
220
                                      LOADER.GetImageN("io", 118), _("Pull down flag"));
×
221
                group->AddImageButton(4, DrawPoint(108, 45), Extent(36, 36), TextureColor::Grey,
×
222
                                      LOADER.GetImageN("io", 20), _("Call in geologist"));
×
223
                group->AddImageButton(5, DrawPoint(144, 45), Extent(36, 36), TextureColor::Grey,
×
224
                                      LOADER.GetImageN("io", 96), _("Send out scout"));
×
225
            }
226
            break;
×
227
            case FlagType::HQ:
×
228
            {
229
                group->AddImageButton(1, DrawPoint(0, 45), Extent(180, 36), TextureColor::Grey,
×
230
                                      LOADER.GetImageN("io", 65), _("Build road"));
×
231
            }
232
            break;
×
233
            case FlagType::Storehouse:
×
234
            {
235
                group->AddImageButton(1, DrawPoint(0, 45), Extent(90, 36), TextureColor::Grey,
×
236
                                      LOADER.GetImageN("io", 65), _("Build road"));
×
237
                group->AddImageButton(3, DrawPoint(90, 45), Extent(90, 36), TextureColor::Grey,
×
238
                                      LOADER.GetImageN("io", 118), _("Demolish house"));
×
239
            }
240
            break;
×
241
        }
242
    }
243

244
    // Flagge Setzen-main_tab
245
    if(tabs.setflag)
2✔
246
    {
247
        ctrlGroup* group = main_tab->AddTab(LOADER.GetImageN("io", 45), _("Erect flag"), TAB_SETFLAG);
2✔
248

249
        unsigned nr = 70;
1✔
250
        if(get<FlagType>(params) == FlagType::WaterFlag)
1✔
251
            nr = 94;
×
252

253
        // Straße aufwerten ggf anzeigen
254
        Extent btSize(180, 36);
1✔
255
        unsigned btPosX = 90;
1✔
256
        AddUpgradeRoad(group, btPosX, btSize.x);
1✔
257

258
        group->AddImageButton(1, DrawPoint(0, 45), btSize, TextureColor::Grey, LOADER.GetImageN("io", nr),
3✔
259
                              _("Erect flag"));
1✔
260
    }
261

262
    // Cut-main_tab
263
    if(tabs.cutroad)
2✔
264
    {
265
        ctrlGroup* group = main_tab->AddTab(LOADER.GetImageN("io", 19), _("Dig up road"), TAB_CUTROAD);
×
266

267
        // Straße aufwerten ggf anzeigen
268
        Extent btSize(180, 36);
×
269
        unsigned btPosX = 0;
×
270
        if(tabs.upgradeRoad)
×
271
            AddUpgradeRoad(group, btPosX, btSize.x);
×
272

273
        group->AddImageButton(1, DrawPoint(btPosX, 45), btSize, TextureColor::Grey, LOADER.GetImageN("io", 32),
×
274
                              _("Dig up road"));
275
    }
276

277
    if(tabs.attack)
2✔
278
    {
279
        ctrlGroup* group = main_tab->AddTab(LOADER.GetImageN("io", 98), _("Attack options"), TAB_ATTACK);
×
280
        available_soldiers_count = get<SoldierCount>(params);
×
281
        AddAttackControls(group, available_soldiers_count);
×
282
        selected_soldiers_count = 1;
×
283
    }
284

285
    if(tabs.sea_attack)
2✔
286
    {
287
        ctrlGroup* group = main_tab->AddTab(LOADER.GetImageN("io", 177), _("Attack options"), TAB_SEAATTACK);
×
288

289
        selected_soldiers_count_sea = 1;
×
290
        available_soldiers_count_sea = gwv.GetViewer().GetNumSoldiersForSeaAttack(selectedPt);
×
291

292
        AddAttackControls(group, available_soldiers_count_sea);
×
293
    }
294

295
    // Beobachten-main_tab
296
    if(tabs.watch)
2✔
297
    {
298
        if(gi.GI_GetCheats().canPlaceCheatBuilding(selectedPt))
1✔
299
        {
NEW
300
            constexpr auto buildImgId = 18;
×
NEW
301
            auto* buildImg = LOADER.GetImageN("io", buildImgId);
×
NEW
302
            ctrlGroup* group = main_tab->AddTab(buildImg, _("Build headquarters"), TAB_CHEAT);
×
NEW
303
            group->AddImageButton(1, DrawPoint{0, 45}, Extent{180, 36}, TextureColor::Grey, buildImg,
×
NEW
304
                                  _("Build headquarters"));
×
305
        }
306

307
        ctrlGroup* group = main_tab->AddTab(LOADER.GetImageN("io", 36), _("Display options"), TAB_WATCH);
2✔
308
        const Extent btSize(45, 36);
1✔
309
        DrawPoint curPos(0, 45);
1✔
310
        group->AddImageButton(1, curPos, btSize, TextureColor::Grey, LOADER.GetImageN("io", 108),
2✔
311
                              _("Observation window"));
312
        curPos.x += btSize.x;
1✔
313
        group->AddImageButton(2, curPos, btSize, TextureColor::Grey, LOADER.GetImageN("io", 179), _("House names"));
2✔
314
        curPos.x += btSize.x;
1✔
315
        group->AddImageButton(3, curPos, btSize, TextureColor::Grey, LOADER.GetImageN("io", 180),
2✔
316
                              _("Go to headquarters"));
317
        curPos.x += btSize.x;
1✔
318
        group->AddImageButton(4, curPos, btSize, TextureColor::Grey, LOADER.GetImageN("io", 107),
2✔
319
                              _("Notify allies of this location"));
320
    }
321

322
    main_tab->SetSelection(0, true);
2✔
323

324
    DrawPoint adjPos = GetPos();
2✔
325
    DrawPoint outerPt = GetPos() + GetSize();
2✔
326
    if(outerPt.x > static_cast<int>(VIDEODRIVER.GetRenderSize().x))
2✔
327
        adjPos.x = mousePos.x - GetSize().x - 40;
×
328
    if(outerPt.y > static_cast<int>(VIDEODRIVER.GetRenderSize().y))
2✔
329
        adjPos.y = mousePos.y - GetSize().y - 40;
×
330
    if(adjPos != GetPos())
2✔
331
        SetPos(adjPos);
×
332

333
    VIDEODRIVER.SetMousePos(GetDrawPos() + DrawPoint(20, 75));
2✔
334
}
2✔
335

336
void iwAction::AddUpgradeRoad(ctrlGroup* group, unsigned& /*x*/, unsigned& width)
1✔
337
{
338
    RTTR_Assert(group);
1✔
339

340
    if(gwv.GetWorld().GetGGS().isEnabled(AddonId::MANUAL_ROAD_ENLARGEMENT))
1✔
341
    {
342
        width = 90;
×
343
        group->AddImageButton(2, DrawPoint(90, 45), Extent(width, 36), TextureColor::Grey, LOADER.GetImageN("io", 44),
×
344
                              _("Upgrade to donkey road"));
×
345
    }
346
}
1✔
347

348
bool iwAction::DoUpgradeRoad()
×
349
{
350
    Direction flag_dir;
351
    const noFlag* flag = gwv.GetWorld().GetRoadFlag(selectedPt, flag_dir);
×
352
    if(flag)
×
353
        return GAMECLIENT.UpgradeRoad(flag->GetPos(), flag_dir);
×
354
    else
355
        return true;
×
356
}
357

358
/// Fügt Angriffs-Steuerelemente für bestimmte Gruppe hinzu
359
void iwAction::AddAttackControls(ctrlGroup* group, const unsigned attackers_count)
×
360
{
361
    // Verfügbare Soldatenzahl steht in params, wenns keine gibt, einfach Meldung anzeigen: "Angriff nicht möglich!"
362
    if(attackers_count == 0)
×
363
    {
364
        // Angriff nicht  möglich!
365
        group->AddText(1, DrawPoint(90, 56), _("Attack not possible."), COLOR_YELLOW, FontStyle::CENTER, NormalFont);
×
366
    } else
367
    {
368
        selected_soldiers_count = 1;
×
369

370
        // Minus und Plus - Button
371
        group->AddImageButton(1, DrawPoint(3, 49), Extent(26, 32), TextureColor::Grey, LOADER.GetImageN("io", 139),
×
372
                              _("Less attackers"));
×
373
        group->AddImageButton(2, DrawPoint(89, 49), Extent(26, 32), TextureColor::Grey, LOADER.GetImageN("io", 138),
×
374
                              _("More attackers"));
×
375

376
        // Starke/Schwache Soldaten
377
        ctrlOptionGroup* ogroup = group->AddOptionGroup(3, GroupSelectType::Illuminate);
×
378
        ogroup->AddImageButton(0, DrawPoint(146, 49), Extent(30, 33), TextureColor::Grey, LOADER.GetImageN("io", 31),
×
379
                               _("Weak attackers"));
×
380
        ogroup->AddImageButton(1, DrawPoint(117, 49), Extent(30, 33), TextureColor::Grey, LOADER.GetImageN("io", 30),
×
381
                               _("Strong attackers"));
×
382
        // standardmäßig starke Soldaten
383
        ogroup->SetSelection(1);
×
384

385
        // Schnellauswahl-Buttons
386
        unsigned buttons_count = (attackers_count > 3) ? 4 : attackers_count;
×
387
        unsigned short button_width = 112 / buttons_count;
×
388

389
        for(unsigned i = 0; i < buttons_count; ++i)
×
390
            group->AddImageButton(10 + i, DrawPoint(3 + i * button_width, 83), Extent(button_width, 32),
×
391
                                  TextureColor::Grey, LOADER.GetImageN("io", 204 + i), _("Number of attackers"));
×
392

393
        // Angriffsbutton
394
        group->AddImageButton(4, DrawPoint(117, 83), Extent(59, 32), TextureColor::Red1, LOADER.GetImageN("io", 25),
×
395
                              _("Attack!"));
×
396
    }
397
}
×
398

399
void iwAction::Close()
1✔
400
{
401
    if(ShouldBeClosed())
1✔
402
        return;
×
403
    IngameWindow::Close();
1✔
404
    if(mousePosAtOpen_.isValid())
1✔
405
        VIDEODRIVER.SetMousePos(mousePosAtOpen_);
1✔
406
}
407

408
void iwAction::Msg_Group_ButtonClick(const unsigned /*group_id*/, const unsigned ctrl_id)
×
409
{
410
    switch(GetCtrl<ctrlTab>(0)->GetCurrentTab())
×
411
    {
412
        default: break;
×
413

414
        case TAB_ATTACK:
×
415
        {
416
            Msg_ButtonClick_TabAttack(ctrl_id);
×
417
        }
418
        break;
×
419
        case TAB_SEAATTACK:
×
420
        {
421
            Msg_ButtonClick_TabSeaAttack(ctrl_id);
×
422
        }
423
        break;
×
424

425
        case TAB_FLAG:
×
426
        {
427
            Msg_ButtonClick_TabFlag(ctrl_id);
×
428
        }
429
        break;
×
430

431
        case TAB_BUILD:
×
432
        {
433
            Msg_ButtonClick_TabBuild(ctrl_id);
×
434
        }
435
        break;
×
436

437
        case TAB_SETFLAG:
×
438
        {
439
            Msg_ButtonClick_TabSetFlag(ctrl_id);
×
440
        }
441
        break;
×
442

443
        case TAB_CUTROAD:
×
444
        {
445
            Msg_ButtonClick_TabCutRoad(ctrl_id);
×
446
        }
447
        break;
×
448

449
        case TAB_WATCH:
×
450
        {
451
            Msg_ButtonClick_TabWatch(ctrl_id);
×
452
        }
453
        break;
×
454

NEW
455
        case TAB_CHEAT:
×
456
        {
NEW
457
            Msg_ButtonClick_TabCheat(ctrl_id);
×
458
        }
NEW
459
        break;
×
460
    }
461
}
×
462

463
void iwAction::Msg_TabChange(const unsigned ctrl_id, const unsigned short tab_id)
1✔
464
{
465
    switch(ctrl_id)
1✔
466
    {
467
        case 0: // Haupttabs
1✔
468
        {
469
            unsigned short height = 0;
1✔
470
            switch(tab_id)
1✔
471
            {
472
                case TAB_FLAG:
×
473
                case TAB_CUTROAD:
474
                case TAB_SETFLAG:
475
                case TAB_CHEAT:
UNCOV
476
                case TAB_WATCH: height = 138; break;
×
477
                case TAB_BUILD:
1✔
478
                {
479
                    height = building_tab_heights
1✔
480
                      [GetCtrl<ctrlTab>(0)->GetGroup(TAB_BUILD)->GetCtrl<ctrlTab>(1)->GetCurrentTab()];
1✔
481
                }
482
                break;
1✔
483
                case TAB_ATTACK:
×
484
                {
485
                    if(available_soldiers_count > 0)
×
486
                        height = 178;
×
487
                    else
488
                        height = 130;
×
489
                }
490
                break;
×
491
                case TAB_SEAATTACK:
×
492
                {
493
                    if(available_soldiers_count_sea > 0)
×
494
                        height = 178;
×
495
                    else
496
                        height = 130;
×
497
                }
498
                break;
×
499
            }
500

501
            SetHeight(height);
1✔
502
        }
503
        break;
1✔
504
    }
505
}
1✔
506

507
void iwAction::Msg_Group_TabChange(const unsigned /*group_id*/, const unsigned ctrl_id, const unsigned short tab_id)
1✔
508
{
509
    switch(ctrl_id)
1✔
510
    {
511
        case 1: // Gebäudetabs
1✔
512
        {
513
            SetHeight(building_tab_heights[tab_id]);
1✔
514
        }
515
        break;
1✔
516
    }
517
}
1✔
518

519
void iwAction::Msg_PaintAfter()
1✔
520
{
521
    IngameWindow::Msg_PaintAfter();
1✔
522
    auto* tab = GetCtrl<ctrlTab>(0);
1✔
523
    if(tab)
1✔
524
    {
525
        static boost::format fmt("%u/%u");
1✔
526
        // Anzeige Soldaten/mögliche Soldatenanzahl bei Angriffstab
527
        if(tab->GetCurrentTab() == TAB_ATTACK && available_soldiers_count > 0)
1✔
528
        {
529
            fmt % selected_soldiers_count % available_soldiers_count;
×
530
            LargeFont->Draw(GetDrawPos() + DrawPoint(67, 79), fmt.str(), FontStyle::CENTER, COLOR_YELLOW);
×
531
        } else if(tab->GetCurrentTab() == TAB_SEAATTACK && available_soldiers_count_sea > 0)
1✔
532
        {
533
            fmt % selected_soldiers_count_sea % available_soldiers_count_sea;
×
534
            LargeFont->Draw(GetDrawPos() + DrawPoint(67, 79), fmt.str(), FontStyle::CENTER, COLOR_YELLOW);
×
535
        }
536
    }
537
}
1✔
538

539
void iwAction::Msg_ButtonClick_TabAttack(const unsigned ctrl_id)
×
540
{
541
    switch(ctrl_id)
×
542
    {
543
        case 1: // 1 Soldat weniger
×
544
        {
545
            if(selected_soldiers_count > 1)
×
546
                --selected_soldiers_count;
×
547
        }
548
        break;
×
549
        case 2: // 1 Soldat mehr
×
550
        {
551
            if(selected_soldiers_count < available_soldiers_count)
×
552
                ++selected_soldiers_count;
×
553
        }
554
        break;
×
555
        case 10: // auf bestimmte Anzahl setzen
×
556
        case 11:
557
        case 12:
558
        case 13:
559
        {
560
            if(available_soldiers_count > 4)
×
561
                selected_soldiers_count = (ctrl_id - 9) * available_soldiers_count / 4;
×
562
            else
563
                selected_soldiers_count = ctrl_id - 9;
×
564
        }
565
        break;
×
566
        case 4: // Angriff!
×
567
        {
568
            auto* ogroup = GetCtrl<ctrlTab>(0)->GetGroup(TAB_ATTACK)->GetCtrl<ctrlOptionGroup>(3);
×
569
            if(GAMECLIENT.Attack(selectedPt, selected_soldiers_count, (ogroup->GetSelection() == 1)))
×
570
                Close();
×
571
        }
572
        break;
×
573
    }
574
}
×
575

576
void iwAction::Msg_ButtonClick_TabSeaAttack(const unsigned ctrl_id)
×
577
{
578
    switch(ctrl_id)
×
579
    {
580
        case 1: // 1 Soldat weniger
×
581
        {
582
            if(selected_soldiers_count_sea > 1)
×
583
                --selected_soldiers_count_sea;
×
584
        }
585
        break;
×
586
        case 2: // 1 Soldat mehr
×
587
        {
588
            if(selected_soldiers_count_sea < available_soldiers_count_sea)
×
589
                ++selected_soldiers_count_sea;
×
590
        }
591
        break;
×
592
        case 10: // auf bestimmte Anzahl setzen
×
593
        case 11:
594
        case 12:
595
        case 13:
596
        {
597
            if(available_soldiers_count_sea > 4)
×
598
                selected_soldiers_count_sea = (ctrl_id - 9) * available_soldiers_count_sea / 4;
×
599
            else
600
                selected_soldiers_count_sea = ctrl_id - 9;
×
601
        }
602
        break;
×
603
        case 4: // Angriff!
×
604
        {
605
            auto* ogroup = GetCtrl<ctrlTab>(0)->GetGroup(TAB_SEAATTACK)->GetCtrl<ctrlOptionGroup>(3);
×
606
            if(GAMECLIENT.SeaAttack(selectedPt, selected_soldiers_count_sea, (ogroup->GetSelection() == 1)))
×
607
                Close();
×
608
        }
609
        break;
×
610
    }
611
}
×
612

613
void iwAction::Msg_ButtonClick_TabFlag(const unsigned ctrl_id)
×
614
{
615
    switch(ctrl_id)
×
616
    {
617
        case 1: // Straße bauen
×
618
        {
619
            gi.GI_StartRoadBuilding(selectedPt, false);
×
620
            Close();
×
621
        }
622
        break;
×
623
        case 2: // Wasserstraße bauen
×
624
        {
625
            gi.GI_StartRoadBuilding(selectedPt, true);
×
626
            Close();
×
627
        }
628
        break;
×
629
        case 3: // Flagge abreißen
×
630
        {
631
            const GameWorldBase& world = gwv.GetWorld();
×
632
            NodalObjectType nop = (world.GetNO(world.GetNeighbour(selectedPt, Direction::NorthWest)))->GetType();
×
633
            // Haben wir ne Baustelle/Gebäude dran?
634
            if(nop == NodalObjectType::Building || nop == NodalObjectType::Buildingsite)
×
635
            {
636
                // Abreißen?
637
                const auto* building =
638
                  world.GetSpecObj<noBaseBuilding>(world.GetNeighbour(selectedPt, Direction::NorthWest));
×
639

640
                // Militärgebäude?
641
                if(building->GetGOT() == GO_Type::NobMilitary)
×
642
                {
643
                    // Darf das Gebäude abgerissen werden?
644
                    if(!static_cast<const nobMilitary*>(building)->IsDemolitionAllowed())
×
645
                    {
646
                        // Nein, dann Messagebox anzeigen
647
                        iwMilitaryBuilding::DemolitionNotAllowed(world.GetGGS());
×
648
                        break;
×
649
                    }
650
                }
651

652
                WINDOWMANAGER.Show(std::make_unique<iwDemolishBuilding>(gwv, building, true));
×
653
                DisableMousePosResetOnClose();
×
654
                Close();
×
655
            } else
656
            {
657
                if(GAMECLIENT.DestroyFlag(selectedPt))
×
658
                    Close();
×
659
            }
660
        }
661
        break;
×
662
        case 4: // Geologen rufen
×
663
        {
664
            if(GAMECLIENT.CallSpecialist(selectedPt, Job::Geologist))
×
665
                Close();
×
666
        }
667
        break;
×
668
        case 5: // Späher rufen
×
669
        {
670
            if(GAMECLIENT.CallSpecialist(selectedPt, Job::Scout))
×
671
                Close();
×
672
        }
673
        break;
×
674
    }
675
}
×
676

677
void iwAction::Msg_ButtonClick_TabBuild(const unsigned ctrl_id)
×
678
{
679
    // Klick auf Gebäudebauicon
680
    if(GAMECLIENT.SetBuildingSite(selectedPt, GetCtrl<ctrlTab>(0)
×
681
                                                ->GetGroup(TAB_BUILD)
×
682
                                                ->GetCtrl<ctrlTab>(1)
683
                                                ->GetCurrentGroup()
×
684
                                                ->GetCtrl<ctrlBuildingIcon>(ctrl_id)
685
                                                ->GetType()))
686
    {
687
        // Fenster schließen
688
        Close();
×
689
    }
690
}
×
691

692
void iwAction::Msg_ButtonClick_TabSetFlag(const unsigned ctrl_id)
×
693
{
694
    bool success = false;
×
695
    switch(ctrl_id)
×
696
    {
697
        case 1: // Flagge setzen
×
698
            success = GAMECLIENT.SetFlag(selectedPt);
×
699
            break;
×
700
        case 2: // Weg aufwerten
×
701
            success = DoUpgradeRoad();
×
702
            break;
×
703
    }
704

705
    if(success)
×
706
        Close();
×
707
}
×
708

709
void iwAction::Msg_ButtonClick_TabCutRoad(const unsigned ctrl_id)
×
710
{
711
    bool success = true;
×
712
    switch(ctrl_id)
×
713
    {
714
        case 1: // Straße abreißen
×
715
        {
716
            Direction flag_dir;
717
            const noFlag* flag = gwv.GetWorld().GetRoadFlag(selectedPt, flag_dir);
×
718
            if(flag)
×
719
                success = GAMECLIENT.DestroyRoad(flag->GetPos(), flag_dir);
×
720
        }
721
        break;
×
722
        case 2: // Straße aufwerten
×
723
            success = DoUpgradeRoad();
×
724
            break;
×
725
    }
726

727
    if(success)
×
728
        Close();
×
729
}
×
730

731
void iwAction::Msg_ButtonClick_TabWatch(const unsigned ctrl_id)
×
732
{
733
    switch(ctrl_id)
×
734
    {
735
        case 1:
×
736
            // TODO: bestimen, was an der position selected ist
737
            WINDOWMANAGER.Show(std::make_unique<iwObservate>(gwv, selectedPt));
×
738
            DisableMousePosResetOnClose();
×
739
            Close();
×
740
            break;
×
741
        case 2: // Häusernamen/Prozent anmachen
×
742
            gwv.ToggleShowNamesAndProductivity();
×
743
            Close();
×
744
            break;
×
745
        case 3: // zum HQ
×
746
            gwv.MoveToMapPt(gwv.GetViewer().GetPlayer().GetHQPos());
×
747
            DisableMousePosResetOnClose();
×
748
            Close();
×
749
            break;
×
750
        case 4:
×
751
            if(GAMECLIENT.NotifyAlliesOfLocation(selectedPt))
×
752
                Close();
×
753
            break;
×
754
    }
755
}
×
756

NEW
757
void iwAction::Msg_ButtonClick_TabCheat(const unsigned ctrl_id)
×
758
{
NEW
759
    switch(ctrl_id)
×
760
    {
NEW
761
        case 1:
×
NEW
762
            gi.GI_GetCheats().placeCheatBuilding(selectedPt, gwv.GetViewer().GetPlayer());
×
NEW
763
            Close();
×
NEW
764
            break;
×
765
    }
NEW
766
}
×
767

UNCOV
768
void iwAction::DisableMousePosResetOnClose()
×
769
{
770
    mousePosAtOpen_ = DrawPoint::Invalid();
×
771
}
×
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