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

Return-To-The-Roots / s25client / 12744223927

13 Jan 2025 09:26AM UTC coverage: 50.258% (+0.03%) from 50.224%
12744223927

push

github

Flamefire
Fix improved alliances for close start positions

With the addon enabled the territory for the HQ won't be calculated
correctly when they are too close.
The code runs into this condtion that reset the owner for territory
gained by a newly placed HQ:
`ownerOfTriggerBld == oldOwner && oldOwner > 0 && reason == TerritoryChangeReason::Build`
When the HQs are too close the position of the newly placed HQ already
belongs to a player and as ownership wasn't yet set for the position of
the HQ `ownerOfTriggerBld` wrongly refers to that player.

Fix by explicitely handling the case of "building" an HQ by setting
`ownerOfTriggerBld` to the new owner of the point, which is the owner of the HQ.

Fixes #1733

9 of 10 new or added lines in 1 file covered. (90.0%)

4 existing lines in 1 file now uncovered.

22325 of 44421 relevant lines covered (50.26%)

36882.97 hits per line

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

61.9
/libs/s25main/nodeObjs/noMovable.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 "noMovable.h"
6

7
#include "EventManager.h"
8
#include "GameEvent.h"
9
#include "SerializedGameData.h"
10
#include "enum_cast.hpp"
11
#include "network/GameClient.h"
12
#include "world/GameWorld.h"
13
#include "gameData/MapConsts.h"
14
#include "s25util/Log.h"
15

16
EventState::EventState(SerializedGameData& sgd) : elapsed(sgd.PopUnsignedInt()), length(sgd.PopUnsignedInt()) {}
5✔
17

18
noMovable::noMovable(const NodalObjectType nop, const MapPoint pos)
1,082✔
19
    : noCoordBase(nop, pos), curMoveDir(Direction::SouthEast), ascent(0), moving(false), current_ev(nullptr)
1,082✔
20
{}
1,082✔
21

22
void noMovable::Serialize(SerializedGameData& sgd) const
10✔
23
{
24
    noCoordBase::Serialize(sgd);
10✔
25

26
    sgd.PushEnum<uint8_t>(curMoveDir);
10✔
27
    sgd.PushUnsignedChar(ascent);
10✔
28
    sgd.PushEvent(current_ev);
10✔
29
    sgd.PushUnsignedInt(pauseEv.elapsed);
10✔
30
    sgd.PushUnsignedInt(pauseEv.length);
10✔
31
    sgd.PushBool(moving);
10✔
32
}
10✔
33

34
noMovable::noMovable(SerializedGameData& sgd, const unsigned obj_id)
5✔
35
    : noCoordBase(sgd, obj_id), curMoveDir(sgd.Pop<Direction>()), ascent(sgd.PopUnsignedChar())
5✔
36
{
37
    current_ev = sgd.PopEvent();
5✔
38
    pauseEv = EventState(sgd);
5✔
39
    moving = sgd.PopBool();
5✔
40
}
5✔
41

42
void noMovable::Walk()
3,870✔
43
{
44
    moving = false;
3,870✔
45
    const MapPoint oldPos = pos;
3,870✔
46
    pos = world->GetNeighbour(pos, curMoveDir);
3,870✔
47
    world->AddFigure(pos, world->RemoveFigure(oldPos, *this));
3,870✔
48
}
3,870✔
49

50
void noMovable::FaceDir(Direction newDir)
523✔
51
{
52
    curMoveDir = newDir;
523✔
53
}
523✔
54

55
void noMovable::StartMoving(const Direction dir, unsigned gf_length)
4,374✔
56
{
57
    RTTR_Assert(!moving);
4,374✔
58

59
    // Ist das Wesen stehengeblieben mitten aufm Weg?
60
    if(IsStoppedBetweenNodes())
4,374✔
61
    {
62
        // Das Laufevent fortführen
63
        RTTR_Assert(dir == curMoveDir);
1✔
64
        // Avoid setting an event for current gf by increasing the length
65
        if(pauseEv.length == pauseEv.elapsed)
1✔
66
            pauseEv.length++;
×
67
        current_ev = GetEvMgr().AddEvent(this, pauseEv.length, 0, pauseEv.elapsed);
1✔
68
        pauseEv = EventState();
1✔
69
        moving = true;
1✔
70
        return;
1✔
71
    }
72

73
    // Steigung ermitteln, muss entsprechend langsamer (hoch) bzw. schneller (runter) laufen
74
    // runter natürlich nich so viel schneller werden wie langsamer hoch
75
    switch(int(world->GetNeighbourNode(pos, dir).altitude) - int(world->GetNode(pos).altitude))
4,373✔
76
    {
77
        default: ascent = 3; break; // gerade
4,041✔
78
        case 1:
45✔
79
            ascent = 4;
45✔
80
            gf_length += (gf_length / 2);
45✔
81
            break; // leicht hoch
45✔
82
        case 2:
108✔
83
        case 3:
84
            ascent = 5;
108✔
85
            gf_length *= 2;
108✔
86
            break; // mittelsteil hoch
108✔
UNCOV
87
        case 4:
×
88
        case 5:
UNCOV
89
            ascent = 6;
×
UNCOV
90
            gf_length *= 3;
×
UNCOV
91
            break;                  // steil hoch
×
92
        case -1: ascent = 2; break; // leicht runter
70✔
93
        case -2:
109✔
94
        case -3: ascent = 1; break; // mittelsteil runter
109✔
95
        case -4:
×
96
        case -5: ascent = 0; break; // steil runter
×
97
    }
98

99
    current_ev = GetEvMgr().AddEvent(this, gf_length);
4,373✔
100
    this->curMoveDir = dir;
4,373✔
101
    moving = true;
4,373✔
102
}
103

104
DrawPoint noMovable::CalcRelative(DrawPoint curPt, DrawPoint nextPt) const
×
105
{
106
    if(current_ev)
×
107
    {
108
        RTTR_Assert(current_ev->length > 0);
×
109
        if(current_ev->length == 0)
×
110
        {
111
            LOG.write("WARNING: Bug detected (GF: %u). Please report this with the savegame and replay. "
×
112
                      "noMovable::CalcRelative: "
113
                      "current_ev->gf_length = 0!\n")
114
              % GetEvMgr().GetCurrentGF();
×
115
            return Position(0, 0);
×
116
        }
117
    }
118

119
    RTTR_Assert(IsMoving() || IsStoppedBetweenNodes());
×
120

121
    using milliseconds_i32_t = std::chrono::duration<int32_t, std::milli>;
122

123
    // Wenn wir mittem aufm Weg stehen geblieben sind, die gemerkten Werte jeweils nehmen
124
    EventState curState;
×
125
    milliseconds_i32_t frame_time;
126
    if(current_ev)
×
127
    {
128
        curState.elapsed = GetEvMgr().GetCurrentGF() - current_ev->startGF;
×
129
        curState.length = current_ev->length;
×
130
        frame_time = GAMECLIENT.GetFrameTime();
×
131
    } else
132
    {
133
        curState = pauseEv;
×
134
        frame_time = milliseconds_i32_t::zero();
×
135
    }
136

137
    // Convert to real world time
138
    const milliseconds_i32_t gfLength = GAMECLIENT.GetGFLength();
×
139
    // Time since the start of the event
140
    milliseconds_i32_t curTimePassed = curState.elapsed * gfLength + frame_time;
×
141
    // Duration of the event
142
    milliseconds_i32_t duration = curState.length * gfLength;
×
143

144
    // We are in that event
145
    RTTR_Assert(curTimePassed <= duration);
×
146

147
    // Check for map border crossing
148
    const Position mapDrawSize = world->GetSize() * Position(TR_W, TR_H);
×
149
    if(std::abs(nextPt.x - curPt.x) >= mapDrawSize.x / 2)
×
150
    {
151
        // So we need to get closer to nextPt
152
        if(curPt.x > nextPt.x)
×
153
            curPt.x -= mapDrawSize.x;
×
154
        else
155
            curPt.x += mapDrawSize.x;
×
156
    }
157
    if(std::abs(curPt.y - nextPt.y) >= mapDrawSize.y / 2)
×
158
    {
159
        if(curPt.y > nextPt.y)
×
160
            curPt.y -= mapDrawSize.y;
×
161
        else
162
            curPt.y += mapDrawSize.y;
×
163
    }
164

165
    return ((nextPt - curPt) * curTimePassed.count()) / duration.count();
×
166
}
167

168
/// Interpoliert fürs Laufen zwischen zwei Kartenpunkten
169
DrawPoint noMovable::CalcWalkingRelative() const
×
170
{
171
    Position curPt = world->GetNodePos(pos);
×
172
    Position nextPt = world->GetNodePos(world->GetNeighbour(pos, curMoveDir));
×
173

174
    return CalcRelative(curPt, nextPt);
×
175
}
176

177
void noMovable::PauseWalking()
1✔
178
{
179
    RTTR_Assert(IsMoving());
1✔
180
    // Frames festhalten, bis zu denen wir gekommen sind
181
    pauseEv = EventState(GetEvMgr().GetCurrentGF() - current_ev->startGF, current_ev->length);
1✔
182
    // Event abmelden
183
    GetEvMgr().RemoveEvent(current_ev);
1✔
184
    moving = false;
1✔
185
}
1✔
186

187
/// Gibt zurück, ob sich das angegebene Objekt zwischen zwei Punkten bewegt
188
bool noMovable::IsMoving() const
609✔
189
{
190
    return current_ev && (current_ev->id == 0);
609✔
191
}
192

193
/// Gibt die Position zurück, wo wir uns hinbewegen (selbe Position, wenn Schiff steht)
194
MapPoint noMovable::GetDestinationForCurrentMove() const
246✔
195
{
196
    // Bewegt sich das Ding gerade?
197
    if(IsMoving())
246✔
198
        // Dann unsere Zielrichtung zur Berechnung verwenden
199
        return world->GetNeighbour(pos, curMoveDir);
186✔
200

201
    return pos;
60✔
202
}
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