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

Return-To-The-Roots / s25client / 20194965430

13 Dec 2025 04:48PM UTC coverage: 50.052%. First build
20194965430

Pull #1720

github

web-flow
Merge f32c9b7c0 into a8dc3da9a
Pull Request #1720: Add leather addon

312 of 1143 new or added lines in 68 files covered. (27.3%)

22779 of 45511 relevant lines covered (50.05%)

35641.36 hits per line

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

0.0
/libs/s25main/ingameWindows/iwDistribution.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 "iwDistribution.h"
6
#include "AddonHelperFunctions.h"
7
#include "GamePlayer.h"
8
#include "GlobalGameSettings.h"
9
#include "LeatherLoader.h"
10
#include "Loader.h"
11
#include "WindowManager.h"
12
#include "WineLoader.h"
13
#include "addons/const_addons.h"
14
#include "controls/ctrlGroup.h"
15
#include "controls/ctrlProgress.h"
16
#include "controls/ctrlTab.h"
17
#include "iwHelp.h"
18
#include "network/GameClient.h"
19
#include "ogl/FontStyle.h"
20
#include "world/GameWorldBase.h"
21
#include "world/GameWorldViewer.h"
22
#include "gameData/BuildingConsts.h"
23
#include "gameData/GoodConsts.h"
24
#include "gameData/const_gui_ids.h"
25
#include <utility>
26

27
/// Dertermines width of the progress bars: distance to the window borders
28
const unsigned PROGRESS_BORDER_DISTANCE = 20;
29
const unsigned TAB_ICON_SIZE = 36;
30

31
iwDistribution::iwDistribution(const GameWorldViewer& gwv, GameCommandFactory& gcFactory)
×
32
    : TransmitSettingsIgwAdapter(CGI_DISTRIBUTION, IngameWindow::posLastOrCenter, Extent(290, 312),
×
33
                                 _("Distribution of goods"), LOADER.GetImageN("resource", 41)),
×
34
      gwv(gwv), gcFactory(gcFactory)
×
35
{
36
    CreateGroups();
×
37

NEW
38
    Resize(Extent(groups.size() * TAB_ICON_SIZE + TAB_ICON_SIZE / 2 + 20, 312));
×
39

40
    // Tab Control
NEW
41
    ctrlTab* tab = AddTabCtrl(0, DrawPoint(10, 20), groups.size() * TAB_ICON_SIZE + TAB_ICON_SIZE / 2);
×
42
    DrawPoint txtPos(GetSize().x / 2, 60);
×
43
    DrawPoint progPos(PROGRESS_BORDER_DISTANCE - tab->GetPos().x, txtPos.y);
×
44
    const Extent progSize(GetSize().x - 2 * PROGRESS_BORDER_DISTANCE, 20);
×
45

46
    for(unsigned groupId = 0; groupId < groups.size(); groupId++)
×
47
    {
48
        const DistributionGroup& group = groups[groupId];
×
49
        ctrlGroup* tabGrp = tab->AddTab(group.img, group.name, groupId);
×
50
        txtPos.y = progPos.y = 60;
×
51
        unsigned curId = 0;
×
52
        for(const auto& entry : group.entries)
×
53
        {
54
            unsigned txtId = group.entries.size() + curId;
×
55
            tabGrp->AddText(txtId, txtPos, std::get<0>(entry), COLOR_YELLOW, FontStyle::CENTER | FontStyle::BOTTOM,
×
56
                            SmallFont);
×
57
            tabGrp->AddProgress(curId++, progPos, progSize, TextureColor::Grey, 139, 138, 10);
×
58
            txtPos.y = progPos.y += progSize.y * 2;
×
59
        }
60
    }
61

62
    // Gruppe auswählen
63
    tab->SetSelection(0);
×
64

65
    const Extent btSize(32, 32);
×
66
    // "Help" button
67
    AddImageButton(2, DrawPoint(15, GetFullSize().y - 15 - btSize.y), btSize, TextureColor::Grey,
×
68
                   LOADER.GetImageN("io", 225), _("Help"));
×
69
    // "Default" button
70
    AddImageButton(10, GetFullSize() - DrawPoint::all(15) - btSize, btSize, TextureColor::Grey,
×
71
                   LOADER.GetImageN("io", 191), _("Default"));
×
72

73
    iwDistribution::UpdateSettings();
×
74
}
×
75

76
void iwDistribution::TransmitSettings()
×
77
{
78
    if(GAMECLIENT.IsReplayModeOn())
×
79
        return;
×
80
    if(settings_changed)
×
81
    {
82
        // Read values from the progress ctrls to the struct
83
        Distributions newDistribution;
84
        // Set default values for all distributions because groups with only one entry are not shown and will not be set
NEW
85
        std::transform(distributionMap.begin(), distributionMap.end(), newDistribution.begin(),
×
NEW
86
                       [](DistributionMapping const& mapping) { return std::get<2>(mapping); });
×
87

88
        for(unsigned i = 0; i < groups.size(); ++i)
×
89
        {
90
            ctrlGroup* tab = GetCtrl<ctrlTab>(0)->GetGroup(i);
×
91
            const DistributionGroup& group = groups[i];
×
92
            // Werte der Gruppen auslesen
93
            for(unsigned j = 0; j < group.entries.size(); ++j)
×
94
            {
95
                auto value = static_cast<uint8_t>(tab->GetCtrl<ctrlProgress>(j)->GetPosition());
×
96
                newDistribution[std::get<1>(group.entries[j])] = value;
×
97
            }
98
        }
99

100
        // und übermitteln
101
        if(gcFactory.ChangeDistribution(newDistribution))
×
102
        {
103
            GAMECLIENT.visual_settings.distribution = newDistribution;
×
104
            settings_changed = false;
×
105
        }
106
    }
107
}
108

109
void iwDistribution::Msg_Group_ProgressChange(const unsigned /*group_id*/, const unsigned /*ctrl_id*/,
×
110
                                              const unsigned short /*position*/)
111
{
112
    settings_changed = true;
×
113
}
×
114

115
void iwDistribution::UpdateSettings(const Distributions& distribution)
×
116
{
117
    if(GAMECLIENT.IsReplayModeOn())
×
118
        gwv.GetPlayer().FillVisualSettings(GAMECLIENT.visual_settings);
×
119

120
    for(unsigned g = 0; g < groups.size(); ++g)
×
121
    {
122
        // Look for correct group
123
        const DistributionGroup& group = groups[g];
×
124
        ctrlGroup* tab = GetCtrl<ctrlTab>(0)->GetGroup(g);
×
125
        // And correct entry
126
        for(unsigned i = 0; i < group.entries.size(); ++i)
×
127
            tab->GetCtrl<ctrlProgress>(i)->SetPosition(distribution[std::get<1>(group.entries[i])]);
×
128
    }
129
}
×
130

131
void iwDistribution::UpdateSettings()
×
132
{
133
    UpdateSettings(GAMECLIENT.visual_settings.distribution);
×
134
}
×
135

136
void iwDistribution::Msg_ButtonClick(const unsigned ctrl_id)
×
137
{
138
    if(GAMECLIENT.IsReplayModeOn())
×
139
        return;
×
140
    switch(ctrl_id)
×
141
    {
142
        default: return;
×
143

144
        case 2:
×
145
        {
146
            WINDOWMANAGER.ReplaceWindow(
×
147
              std::make_unique<iwHelp>(_("The priority of goods for the individual buildings can be set here. "
×
148
                                         "The higher the value, the quicker the required goods are delivered "
149
                                         "to the building concerned.")));
×
150
        }
151
        break;
×
152
        // Default button
153
        case 10:
×
154
        {
155
            UpdateSettings(GAMECLIENT.default_settings.distribution);
×
156
            settings_changed = true;
×
157
        }
158
        break;
×
159
    }
160
}
161

162
void iwDistribution::CreateGroups()
×
163
{
164
    if(!groups.empty())
×
165
        return;
×
166

167
    GoodType lastGood = GoodType::Nothing;
×
168
    unsigned pos = 0;
×
169
    for(const DistributionMapping& mapping : distributionMap)
×
170
    {
171
        // New group?
172
        if(lastGood != std::get<0>(mapping))
×
173
        {
174
            lastGood = std::get<0>(mapping);
×
175
            // Fish = all foodstuff
176
            std::string name = lastGood == GoodType::Fish ? gettext_noop("Foodstuff") : WARE_NAMES[lastGood];
×
177
            glArchivItem_Bitmap* img = nullptr;
×
178
            switch(lastGood)
×
179
            {
180
                case GoodType::Fish: img = LOADER.GetImageN("io", 80); break;
×
181
                case GoodType::Grain: img = LOADER.GetImageN("io", 90); break;
×
182
                case GoodType::Iron: img = LOADER.GetImageN("io", 81); break;
×
183
                case GoodType::Coal: img = LOADER.GetImageN("io", 91); break;
×
184
                case GoodType::Wood: img = LOADER.GetImageN("io", 89); break;
×
185
                case GoodType::Boards: img = LOADER.GetImageN("io", 82); break;
×
186
                case GoodType::Water: img = LOADER.GetImageN("io", 92); break;
×
NEW
187
                case GoodType::Ham:
×
NEW
188
                    img = LOADER.GetImageN("leather_bobs",
×
NEW
189
                                           leatheraddon::bobIndex[leatheraddon::BobType::DistributionOfPigsIcon]);
×
NEW
190
                    break;
×
191
                default: break;
×
192
            }
193
            if(!img)
×
194
                throw std::runtime_error("Unexpected good in distribution");
×
195

196
            groups.push_back(DistributionGroup(_(name), img));
×
197
        }
198
        // HQ = Construction
199
        std::string name = std::get<1>(mapping) == BuildingType::Headquarters ? gettext_noop("Construction") :
×
200
                                                                                BUILDING_NAMES[std::get<1>(mapping)];
×
201
        groups.back().entries.push_back(std::tuple(_(name), pos));
×
202
        pos++;
×
203
    }
204

205
    auto isUnused = [&](std::tuple<std::string, unsigned> const& bts) {
×
206
        const BuildingType buildingType = std::get<1>(distributionMap[std::get<1>(bts)]);
×
NEW
207
        return makeIsUnusedBuilding(gwv.GetWorld().GetGGS())(buildingType);
×
208
    };
×
209
    for(auto& group : groups)
×
210
        helpers::erase_if(group.entries, isUnused);
×
211

NEW
212
    helpers::erase_if(groups, [](DistributionGroup& group) { return group.entries.size() == 1; });
×
213
}
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