Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 11 additions & 24 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Copyright (C) 2005 - 2025 Settlers Freaks <sf-team at siedler25.org>
# Copyright (C) 2005 - 2026 Settlers Freaks <sf-team at siedler25.org>
#
# SPDX-License-Identifier: GPL-2.0-or-later

name: Create Release
permissions:
contents: write

on:
push:
Expand All @@ -18,7 +20,7 @@ jobs:
name: Create Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Extract tag name
id: get_tag
run: echo "::set-output name=tag::${GITHUB_REF#refs/tags/}"
Expand Down Expand Up @@ -60,34 +62,19 @@ jobs:
fi
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
name: Release ${{ github.ref }}
body: |
Return To The Roots (Settlers II(R) Clone)
${{ env.TAG_MSG }}
- ${{steps.filenames.outputs.src}} contains all source files including the submodules
- ${{steps.filenames.outputs.devTools}} contains optional binaries for development. Extract over the source folder if required
draft: false
prerelease: false
- name: Upload source distribution
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./${{steps.filenames.outputs.src}}
asset_name: ${{steps.filenames.outputs.src}}
asset_content_type: application/tar.gz
- name: Upload Dev Tools
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./${{steps.filenames.outputs.devTools}}
asset_name: ${{steps.filenames.outputs.devTools}}
asset_content_type: application/tar.gz
files: |
${{steps.filenames.outputs.src}}
${{steps.filenames.outputs.devTools}}
fail_on_unmatched_files: true
12 changes: 7 additions & 5 deletions .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Copyright (C) 2005 - 2025 Settlers Freaks <sf-team at siedler25.org>
# Copyright (C) 2005 - 2026 Settlers Freaks <sf-team at siedler25.org>
#
# SPDX-License-Identifier: GPL-2.0-or-later

name: Static analysis
permissions:
contents: write

on:
push:
Expand All @@ -16,12 +18,12 @@ jobs:
StyleAndFormatting:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- run: git submodule update --init
- name: Validation
run: tools/ci/staticValidation.sh "$GITHUB_WORKSPACE"
- name: Formatting
uses: DoozyX/clang-format-lint-action@v0.18.2
uses: DoozyX/clang-format-lint-action@c71d0bf4e21876ebec3e5647491186f8797fde31 # v0.18.2
with:
source: "extras libs tests external/libendian external/liblobby external/libsiedler2 external/libutil external/mygettext external/s25edit external/s25update"
clangFormatVersion: 10
Expand All @@ -32,7 +34,7 @@ jobs:
-prune -false -o \( -name '*.hpp' -or -name '*.h' \) \
-print0 | xargs -0 -n1 tools/ci/checkIncludeGuards.sh
- name: Lint markdown files
uses: avto-dev/markdown-lint@v1
uses: avto-dev/markdown-lint@04d43ee9191307b50935a753da3b775ab695eceb # v1.5.0
with:
ignore: external data/RTTR/MAPS .
- name: Check licensing
Expand All @@ -47,7 +49,7 @@ jobs:
ADDITIONAL_CMAKE_FLAGS: ""
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- run: git submodule update --init
- name: Install dependencies
run: |
Expand Down
31 changes: 22 additions & 9 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Copyright (C) 2005 - 2025 Settlers Freaks <sf-team at siedler25.org>
# Copyright (C) 2005 - 2026 Settlers Freaks <sf-team at siedler25.org>
#
# SPDX-License-Identifier: GPL-2.0-or-later

name: Unit tests
permissions:
contents: write

on:
push:
Expand Down Expand Up @@ -37,11 +39,11 @@ jobs:
- { os: windows-2022, generator: Visual Studio 17 2022, type: Release, platform: x64}
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
submodules: true
- name: Install boost
uses: MarkusJx/install-boost@6d8df42f57de83c5b326b5b83e7b35d650030103
uses: MarkusJx/install-boost@8ba8b2fac59ef3d91a838bb4aa53ceabd33d1aa3 # v2.5.1
id: install-boost
with:
boost_version: ${{env.BOOST_VERSION}}
Expand Down Expand Up @@ -139,18 +141,18 @@ jobs:
echo "GCOV=$GCOV" >> $GITHUB_ENV

# Coverage collection requires access to history to find merge-base
- uses: actions/checkout@v4
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
if: "!matrix.coverage"
with:
submodules: true
- uses: actions/checkout@v4
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
if: matrix.coverage
with:
submodules: true
fetch-depth: 0 # Full history

- name: Cache dependencies
uses: actions/cache@v4
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
with:
path: ${{env.DEPS_DIR}}
key: ${{matrix.os}}-${{env.BOOST_VERSION}}
Expand Down Expand Up @@ -182,7 +184,7 @@ jobs:
fi

- name: Setup CCache
uses: hendrikmuhs/ccache-action@v1
uses: hendrikmuhs/ccache-action@33522472633dbd32578e909b315f5ee43ba878ce # v1.2.22
with:
key: ${{matrix.os}}-${{matrix.compiler}}-${{matrix.type}}-${{matrix.boost}}
max-size: 200M
Expand Down Expand Up @@ -210,15 +212,26 @@ jobs:
- name: Test
run: tools/ci/test.sh

- run: tools/ci/collectCoverageData.sh && external/libutil/tools/ci/uploadCoverageData.sh
- run: tools/ci/collectCoverageData.sh
if: matrix.coverage && success()

- run: tools/ci/checkTestCoverage.sh
if: matrix.coverage && success()

- name: Upload coverage (Codecov)
if: matrix.coverage && success()
uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0
with:
fail_ci_if_error: true
disable_search: true
files: coverage.info
name: Github Actions
token: ${{secrets.CODECOV_TOKEN}}
verbose: true

- name: Upload coverage (Coveralls)
if: matrix.coverage && success()
uses: coverallsapp/github-action@master
uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e # v2.3.7
with:
github-token: ${{secrets.GITHUB_TOKEN}}
path-to-lcov: srccov.info
13 changes: 11 additions & 2 deletions libs/common/include/helpers/containerUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,15 @@ size_t count_if(const T& container, T_Predicate&& predicate)
return static_cast<std::make_unsigned_t<decltype(result)>>(result);
}

/// Sort collection with optional predicate
template<class T, class T_Predicate = std::less<>>
void sort(T& container, T_Predicate&& predicate = T_Predicate{})
{
using std::begin;
using std::end;
std::sort(begin(container), end(container), std::forward<T_Predicate>(predicate));
}

/// Remove duplicate values from the given sorted container
template<class T>
void makeUniqueSorted(T& container)
Expand All @@ -139,13 +148,13 @@ void makeUniqueSorted(T& container)
template<class T>
void makeUnique(T& container)
{
std::sort(begin(container), end(container));
sort(container);
makeUniqueSorted(container);
}
template<class T, class T_Predicate>
void makeUnique(T& container, T_Predicate&& predicate)
{
std::sort(begin(container), end(container), std::forward<T_Predicate>(predicate));
sort(container, std::forward<T_Predicate>(predicate));
makeUniqueSorted(container);
}
/// Remove duplicate values from the given container without changing the order
Expand Down
3 changes: 2 additions & 1 deletion libs/libGamedata/lua/CheckedLuaTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later

#include "CheckedLuaTable.h"
#include "helpers/containerUtils.h"
#include "s25util/Log.h"
#include <boost/algorithm/string/join.hpp>
#include <algorithm>
Expand All @@ -22,7 +23,7 @@ void CheckedLuaTable::checkUnused()
checkEnabled = false;

std::vector<std::string> tableKeys = table.keys<std::string>();
std::sort(tableKeys.begin(), tableKeys.end());
helpers::sort(tableKeys);
std::vector<std::string> unusedKeys;
std::set_difference(tableKeys.begin(), tableKeys.end(), accessedKeys_.begin(), accessedKeys_.end(),
std::back_inserter(unusedKeys));
Expand Down
6 changes: 2 additions & 4 deletions libs/s25main/Cheats.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024-2026 Settlers Freaks (sf-team at siedler25.org)
// Copyright (C) 2024 - 2026 Settlers Freaks (sf-team at siedler25.org)
//
// SPDX-License-Identifier: GPL-2.0-or-later

Expand Down Expand Up @@ -77,12 +77,10 @@ void Cheats::placeCheatBuilding(const MapPoint& mp, const GamePlayer& player)
if(!canPlaceCheatBuilding(mp))
return;

// The new HQ will have default resources.
// In the original game, new HQs created in the Roman campaign had no resources.
world_.DestroyNO(mp, false); // if CanPlaceCheatBuilding is true then this must be safe to destroy
auto* hq =
BuildingFactory::CreateBuilding(world_, BuildingType::Headquarters, mp, player.GetPlayerId(), player.nation);
static_cast<nobHQ*>(hq)->SetIsTent(player.IsHQTent());
checkedCast<nobHQ*>(hq)->SetIsTent(player.IsHQTent());
}

void Cheats::toggleHumanAIPlayer()
Expand Down
22 changes: 13 additions & 9 deletions libs/s25main/GamePlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ void GamePlayer::RemoveBuilding(noBuilding* bld, BuildingType bldType)
{ // Schiffen Bescheid sagen
for(noShip* ship : ships)
ship->HarborDestroyed(static_cast<nobHarborBuilding*>(bld));
} else if(bldType == BuildingType::Headquarters)
} else if(bldType == BuildingType::Headquarters && bld->GetPos() == hqPos)
{
hqPos = MapPoint::Invalid();
for(const noBaseBuilding* bld : buildings.GetStorehouses())
Expand Down Expand Up @@ -1022,7 +1022,7 @@ struct ClientForWare
: bld(bld), estimate(estimate), points(points)
{}

bool operator<(const ClientForWare& b) const
bool operator<(const ClientForWare& b) const noexcept
{
// use estimate, points and object id (as tie breaker) for sorting
if(estimate != b.estimate)
Expand Down Expand Up @@ -1118,7 +1118,7 @@ noBaseBuilding* GamePlayer::FindClientForWare(const Ware& ware)
}

// sort our clients, highest score first
std::sort(possibleClients.begin(), possibleClients.end());
helpers::sort(possibleClients);

noBaseBuilding* lastBld = nullptr;
noBaseBuilding* bestBld = nullptr;
Expand Down Expand Up @@ -1497,10 +1497,14 @@ void GamePlayer::TestDefeat()
Surrender();
}

nobHQ* GamePlayer::GetHQ() const
const nobHQ* GamePlayer::GetHQ() const
{
return hqPos.isValid() ? GetGameWorld().GetSpecObj<nobHQ>(hqPos) : nullptr;
}

nobHQ* GamePlayer::GetHQ()
{
const MapPoint& hqPos = GetHQPos();
return const_cast<nobHQ*>(hqPos.isValid() ? GetGameWorld().GetSpecObj<nobHQ>(hqPos) : nullptr);
return const_cast<nobHQ*>(std::as_const(*this).GetHQ());
}

void GamePlayer::Surrender()
Expand Down Expand Up @@ -1899,7 +1903,7 @@ struct ShipForHarbor

ShipForHarbor(noShip* ship, uint32_t estimate) : ship(ship), estimate(estimate) {}

bool operator<(const ShipForHarbor& b) const
bool operator<(const ShipForHarbor& b) const noexcept
{
return (estimate < b.estimate) || (estimate == b.estimate && ship->GetObjId() < b.ship->GetObjId());
}
Expand Down Expand Up @@ -1930,7 +1934,7 @@ bool GamePlayer::OrderShip(nobHarborBuilding& hb)
}
}

std::sort(sfh.begin(), sfh.end());
helpers::sort(sfh);

noShip* best_ship = nullptr;
uint32_t best_distance = std::numeric_limits<uint32_t>::max();
Expand Down Expand Up @@ -2309,7 +2313,7 @@ void GamePlayer::Trade(nobBaseWarehouse* goalWh, const boost_variant2<GoodType,
const MapPoint goalFlagPos = goalWh->GetFlagPos();

std::vector<nobBaseWarehouse*> whs(buildings.GetStorehouses().begin(), buildings.GetStorehouses().end());
std::sort(whs.begin(), whs.end(), WarehouseDistanceComparator(*goalWh, world));
helpers::sort(whs, WarehouseDistanceComparator(*goalWh, world));
TradePathCache& tradePathCache = world.GetTradePathCache();
for(nobBaseWarehouse* wh : whs)
{
Expand Down
3 changes: 2 additions & 1 deletion libs/s25main/GamePlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ class GamePlayer : public GamePlayerInfo
const GameWorld& GetGameWorld() const { return world; }

const MapPoint& GetHQPos() const { return hqPos; }
const nobHQ* GetHQ() const;
nobHQ* GetHQ();
bool IsHQTent() const;
void SetHQIsTent(bool isTent);

Expand Down Expand Up @@ -444,7 +446,6 @@ class GamePlayer : public GamePlayerInfo

/// Prüft, ob der Spieler besiegt wurde
void TestDefeat();
nobHQ* GetHQ() const;

//////////////////////////////////////////////////////////////////////////
/// Unsynchronized state (e.g. lua, gui...)
Expand Down
3 changes: 2 additions & 1 deletion libs/s25main/ListDir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later

#include "ListDir.h"
#include "helpers/containerUtils.h"
#include "s25util/strAlgos.h"
#include <boost/filesystem.hpp>
#include <algorithm>
Expand Down Expand Up @@ -41,6 +42,6 @@ std::vector<bfs::path> ListDir(const bfs::path& path, std::string extension, boo
result.emplace_back(std::move(curPath));
}

std::sort(result.begin(), result.end());
helpers::sort(result);
return result;
}
5 changes: 3 additions & 2 deletions libs/s25main/SerializedGameData.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2005 - 2024 Settlers Freaks (sf-team at siedler25.org)
// Copyright (C) 2005 - 2026 Settlers Freaks (sf-team at siedler25.org)
//
// SPDX-License-Identifier: GPL-2.0-or-later

Expand Down Expand Up @@ -107,7 +107,8 @@
/// 11: wineaddon added, three new building types and two new goods
/// 12: leatheraddon added, three new building types and three new goods
/// 13: SeaId & HarborId: World::harborData w/o dummy entry at 0
static const unsigned currentGameDataVersion = 13;
/// 14: Remove "age" field in nobBaseMilitary
static const unsigned currentGameDataVersion = 14;
// clang-format on

std::unique_ptr<GameObject> SerializedGameData::Create_GameObject(const GO_Type got, const unsigned obj_id)
Expand Down
Loading
Loading