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

Return-To-The-Roots / s25client / 23110533123

15 Mar 2026 12:38PM UTC coverage: 50.337% (+0.001%) from 50.336%
23110533123

push

github

Flow86
Rename `harbor_pos` to `harborData`

25 of 31 new or added lines in 4 files covered. (80.65%)

9 existing lines in 3 files now uncovered.

23053 of 45797 relevant lines covered (50.34%)

43269.92 hits per line

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

64.71
/libs/s25main/world/MapSerializer.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 "world/MapSerializer.h"
6
#include "CatapultStone.h"
7
#include "Game.h"
8
#include "SerializedGameData.h"
9
#include "buildings/noBuildingSite.h"
10
#include "helpers/Range.h"
11
#include "lua/GameDataLoader.h"
12
#include "world/GameWorldBase.h"
13
#include "s25util/warningSuppression.h"
14
#include <mygettext/mygettext.h>
15

16
void MapSerializer::Serialize(const GameWorldBase& world, SerializedGameData& sgd)
6✔
17
{
18
    // Headinformationen
19
    helpers::pushPoint(sgd, world.GetSize());
6✔
20
    sgd.PushString(world.GetDescription().get(world.GetLandscapeType()).name);
6✔
21

22
    sgd.PushUnsignedInt(GameObject::GetObjIDCounter());
6✔
23

24
    // Alle Weltpunkte serialisieren
25
    const unsigned numPlayers = world.GetNumPlayers();
6✔
26
    for(const auto& node : world.nodes)
5,366✔
27
    {
28
        node.Serialize(sgd, numPlayers, world.GetDescription());
5,360✔
29
    }
30

31
    // Katapultsteine serialisieren
32
    sgd.PushObjectContainer(world.catapult_stones, true);
6✔
33
    // Meeresinformationen serialisieren
34
    sgd.PushUnsignedInt(world.seas.size());
6✔
35
    for(const auto& sea : world.seas)
6✔
36
    {
37
        sgd.PushUnsignedInt(sea.nodes_count);
×
38
    }
39
    // Hafenpositionen serialisieren
40
    sgd.PushUnsignedInt(world.harborData.size());
6✔
41
    for(const auto& curHarborPos : world.harborData)
6✔
42
    {
43
        helpers::pushPoint(sgd, curHarborPos.pos);
×
44
        helpers::pushContainer(sgd, curHarborPos.seaIds);
×
45
        for(const auto& curNeighbors : curHarborPos.neighbors)
×
46
        {
47
            sgd.PushUnsignedInt(curNeighbors.size());
×
48

49
            for(const auto& c : curNeighbors)
×
50
            {
51
                sgd.PushUnsignedInt(c.id.value());
×
52
                sgd.PushUnsignedInt(c.distance);
×
53
            }
54
        }
55
    }
56

57
    sgd.PushObjectContainer(world.harbor_building_sites_from_sea, true);
6✔
58

59
    if(!world.HasLua())
6✔
60
        sgd.PushLongString("");
4✔
61
    else
62
    {
63
        sgd.PushLongString(world.GetLua().getScript());
2✔
64
        Serializer luaSaveState;
4✔
65
        try
66
        {
67
            if(!world.GetLua().Serialize(luaSaveState))
2✔
68
                throw SerializedGameData::Error(_("Failed to save lua state!"));
×
69
        } catch(const std::exception& e)
×
70
        {
71
            throw SerializedGameData::Error(std::string(_("Failed to save lua state!")) + _("Error: ") + e.what());
×
72
        }
73
        sgd.PushUnsignedInt(0xC0DEBA5E); // Start Lua identifier
2✔
74
        sgd.PushUnsignedInt(luaSaveState.GetLength());
2✔
75
        sgd.PushRawData(luaSaveState.GetData(), luaSaveState.GetLength());
2✔
76
        sgd.PushUnsignedInt(0xC001C0DE); // End Lua identifier
2✔
77
    }
78
}
6✔
79

80
void MapSerializer::Deserialize(GameWorldBase& world, SerializedGameData& sgd, Game& game,
3✔
81
                                ILocalGameState& localgameState)
82
{
83
    // Initialisierungen
84
    GameDataLoader gdLoader(world.GetDescriptionWriteable());
6✔
85
    if(!gdLoader.Load())
3✔
86
        throw SerializedGameData::Error(_("Failed to load game data!"));
×
87

88
    // Headinformationen
89
    const auto size = helpers::popPoint<MapExtent>(sgd);
3✔
90
    DescIdx<LandscapeDesc> lt;
3✔
91
    if(sgd.GetGameDataVersion() < 3)
3✔
92
    {
93
        uint8_t gfxSet = sgd.PopUnsignedChar();
×
94
        lt = world.GetDescription().landscapes.find([gfxSet](const LandscapeDesc& l) { return l.s2Id == gfxSet; });
×
95
    } else
96
    {
97
        std::string sLandscape = sgd.PopString();
6✔
98
        lt = world.GetDescription().landscapes.getIndex(sLandscape);
3✔
99
        if(!lt)
3✔
100
            throw SerializedGameData::Error(std::string("Invalid landscape: ") + sLandscape);
×
101
    }
102
    world.Init(size, lt);
3✔
103
    GameObject::ResetCounters(sgd.PopUnsignedInt());
3✔
104

105
    std::vector<DescIdx<TerrainDesc>> landscapeTerrains;
6✔
106
    if(sgd.GetGameDataVersion() < 3)
3✔
107
    {
108
        // Assumes the order of the terrain in the description file is the same as in the prior RTTR versions
109
        landscapeTerrains =
110
          world.GetDescription().terrain.findAll([lt](const TerrainDesc& t) { return t.landscape == lt; });
×
111
    }
112
    // Alle Weltpunkte
113
    MapPoint curPos(0, 0);
3✔
114
    const unsigned numPlayers = world.GetNumPlayers();
3✔
115
    for(auto& node : world.nodes)
2,683✔
116
    {
117
        node.Deserialize(sgd, numPlayers, world.GetDescription(), landscapeTerrains);
2,680✔
118
        curPos.x++;
2,680✔
119
        if(curPos.x >= world.GetWidth())
2,680✔
120
        {
121
            curPos.x = 0;
74✔
122
            curPos.y++;
74✔
123
        }
124
    }
125

126
    sgd.PopObjectContainer(world.catapult_stones, GO_Type::Catapultstone);
3✔
127

128
    world.seas.resize(sgd.PopUnsignedInt());
3✔
129
    for(auto& sea : world.seas)
3✔
130
        sea.nodes_count = sgd.PopUnsignedInt();
×
131

132
    // Deserialize harbor data
133
    const unsigned numHarborPositions = sgd.PopUnsignedInt();
3✔
134
    world.harborData.clear();
3✔
135
    world.harborData.reserve(numHarborPositions);
3✔
136
    for(const auto i : helpers::range<unsigned>(numHarborPositions))
12✔
137
    {
138
        RTTR_UNUSED(i);
NEW
139
        world.harborData.emplace_back(sgd.PopMapPoint());
×
NEW
140
        auto& curHarborPos = world.harborData.back();
×
141
        helpers::popContainer(sgd, curHarborPos.seaIds);
×
142
        for(auto& neighbor : curHarborPos.neighbors)
×
143
        {
144
            const unsigned numNeighbors = sgd.PopUnsignedInt();
×
145
            neighbor.reserve(numNeighbors);
×
146
            for(const auto j : helpers::range<unsigned>(numNeighbors))
×
147
            {
148
                RTTR_UNUSED(j);
149
                const auto id = HarborId(sgd.PopUnsignedInt());
×
150
                const auto distance = sgd.PopUnsignedInt();
×
151
                neighbor.emplace_back(id, distance);
×
152
            }
153
        }
154
    }
155
    if(sgd.GetGameDataVersion() < 13 && !world.harborData.empty())
3✔
156
    {
157
        // Workaround for save games without increased game data version after introducing the change
NEW
158
        if(!world.harborData.front().pos.isValid())
×
NEW
159
            world.harborData.erase(world.harborData.begin());
×
160
    }
161

162
    sgd.PopObjectContainer(world.harbor_building_sites_from_sea, GO_Type::Buildingsite);
3✔
163

164
    const std::string luaScript = sgd.PopLongString();
6✔
165
    if(!luaScript.empty())
3✔
166
    {
167
        if(sgd.PopUnsignedInt() != 0xC0DEBA5E)
1✔
UNCOV
168
            throw SerializedGameData::Error(_("Invalid id for lua data"));
×
169
        // If there is a script, there is also save data. Store reference to that
170
        const auto luaSaveSize = sgd.PopUnsignedInt();
1✔
171
        Serializer luaSaveState(sgd.PopAndDiscard(luaSaveSize), luaSaveSize);
2✔
172
        if(sgd.PopUnsignedInt() != 0xC001C0DE)
1✔
UNCOV
173
            throw SerializedGameData::Error(_("Invalid end-id for lua data"));
×
174

175
        // Now init and load lua
176
        auto lua = std::make_unique<LuaInterfaceGame>(game, localgameState);
1✔
177
        if(!lua->loadScriptString(luaScript))
1✔
UNCOV
178
            throw SerializedGameData::Error(_("Lua script failed to load."));
×
179
        if(!lua->CheckScriptVersion())
1✔
180
            throw SerializedGameData::Error(_("Wrong version for lua script."));
×
181
        try
182
        {
183
            if(!lua->Deserialize(luaSaveState))
1✔
UNCOV
184
                throw SerializedGameData::Error(_("Lua load callback returned failure!"));
×
UNCOV
185
        } catch(const std::exception& e)
×
186
        {
UNCOV
187
            throw SerializedGameData::Error(std::string(_("Failed to load lua state!")) + _("Error: ") + e.what());
×
188
        }
189
        game.SetLua(std::move(lua));
1✔
190
    }
191
    world.CreateTradeGraphs();
3✔
192
}
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