-
Notifications
You must be signed in to change notification settings - Fork 93
Add limited extra harbor spots addon #1921
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 2 commits
31aec23
7eb7728
676ed66
49cd227
dfa8907
6d9f758
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| // Copyright (C) 2005 - 2026 Settlers Freaks (sf-team at siedler25.org) | ||
| // | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| #pragma once | ||
|
|
||
| #include "AddonBool.h" | ||
| #include "mygettext/mygettext.h" | ||
|
|
||
| class AddonFreeHarborSpots : public AddonBool | ||
| { | ||
| public: | ||
| AddonFreeHarborSpots() | ||
| : AddonBool(AddonId::FREE_HARBOR_SPOTS, AddonGroup::GamePlay, _("Build harbors without map markers"), | ||
| _("Allows harbors on suitable coastal castle sites even if the map does not define harbor spots.")) | ||
| {} | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,13 +10,16 @@ | |
|
|
||
| struct BQCalculator | ||
| { | ||
| BQCalculator(const World& world) : world(world) {} | ||
| BQCalculator(const World& world, const bool allowFreeHarborSpots = false) | ||
|
DevOpsOfChaos marked this conversation as resolved.
Outdated
|
||
| : world(world), allowFreeHarborSpots(allowFreeHarborSpots) | ||
| {} | ||
|
|
||
| template<typename T_IsOnRoad> | ||
| BuildingQuality operator()(MapPoint pt, T_IsOnRoad isOnRoad, bool flagOnly = false) const; | ||
|
|
||
| private: | ||
| const World& world; | ||
| bool allowFreeHarborSpots; | ||
| }; | ||
|
|
||
| template<typename T_IsOnRoad> | ||
|
|
@@ -219,8 +222,24 @@ BuildingQuality BQCalculator::operator()(const MapPoint pt, T_IsOnRoad isOnRoad, | |
| } | ||
|
|
||
| // If we can build a castle and this is a harbor point -> Allow harbor | ||
| if(curBQ == BuildingQuality::Castle && world.GetNode(pt).harborId) | ||
| curBQ = BuildingQuality::Harbor; | ||
| if(curBQ == BuildingQuality::Castle) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should not be in here as it slows down processing during the game. This can be fully done at the place where this information is required and it makes the "keep in sync" part easier as both will be in the same file |
||
| { | ||
| bool isHarborPoint = world.GetNode(pt).harborId.isValid(); | ||
| if(!isHarborPoint && allowFreeHarborSpots) | ||
|
DevOpsOfChaos marked this conversation as resolved.
Outdated
|
||
| { | ||
| for(const auto dir : helpers::EnumRange<Direction>{}) | ||
| { | ||
| // Keep this in sync with harbor initialization: NW-only coasts are rejected there. | ||
| if(dir != Direction::NorthWest && world.GetSeaFromCoastalPoint(neighbours[dir])) | ||
| { | ||
| isHarborPoint = true; | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| if(isHarborPoint) | ||
| curBQ = BuildingQuality::Harbor; | ||
| } | ||
|
|
||
| ////////////////////////////////////////////////////////////////////////// | ||
| // At this point we can still build a building/mine | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,12 +3,14 @@ | |
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| #include "world/MapLoader.h" | ||
| #include "BQCalculator.h" | ||
| #include "Game.h" | ||
| #include "GamePlayer.h" | ||
| #include "GameWorldBase.h" | ||
| #include "GlobalGameSettings.h" | ||
| #include "PointOutput.h" | ||
| #include "RttrForeachPt.h" | ||
| #include "addons/const_addons.h" | ||
| #include "buildings/nobHQ.h" | ||
| #include "factories/BuildingFactory.h" | ||
| #include "helpers/IdRange.h" | ||
|
|
@@ -53,7 +55,7 @@ bool MapLoader::Load(const libsiedler2::ArchivItem_Map& map, Exploration explora | |
| return false; | ||
| PlaceObjects(map); | ||
| PlaceAnimals(map); | ||
| if(!InitSeasAndHarbors(world_)) | ||
| if(!InitSeasAndHarbors(world_, std::vector<MapPoint>(), world_.GetGGS().isEnabled(AddonId::FREE_HARBOR_SPOTS))) | ||
| return false; | ||
|
|
||
| /// Schatten | ||
|
|
@@ -420,10 +422,39 @@ bool MapLoader::PlaceHQs(GameWorldBase& world, const std::vector<MapPoint>& hqPo | |
| return true; | ||
| } | ||
|
|
||
| bool MapLoader::InitSeasAndHarbors(World& world, const std::vector<MapPoint>& additionalHarbors) | ||
| namespace { | ||
| bool hasHarborAt(const World& world, const MapPoint pt) | ||
| { | ||
| for(const auto harborId : helpers::idRange<HarborId>(world.GetNumHarborPoints())) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This might be unnecessarily slow: You can simply collect all harbor positions in a vector and use |
||
| { | ||
| if(world.GetHarborPoint(harborId) == pt) | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| std::vector<MapPoint> getGeneratedHarbors(const World& world) | ||
| { | ||
| std::vector<MapPoint> generatedHarbors; | ||
| BQCalculator calcBQ(world, true); | ||
| RTTR_FOREACH_PT(MapPoint, world.GetSize()) | ||
| { | ||
| if(!hasHarborAt(world, pt) | ||
| && calcBQ(pt, [](const MapPoint&) { return false; }) == BuildingQuality::Harbor) | ||
| generatedHarbors.push_back(pt); | ||
| } | ||
| return generatedHarbors; | ||
| } | ||
| } // namespace | ||
|
|
||
| bool MapLoader::InitSeasAndHarbors(World& world, const std::vector<MapPoint>& additionalHarbors, | ||
| const bool generateHarborSpots) | ||
| { | ||
| for(MapPoint pt : additionalHarbors) | ||
| world.harborData.push_back(HarborPos(pt)); | ||
| { | ||
| if(!hasHarborAt(world, pt)) | ||
| world.harborData.push_back(HarborPos(pt)); | ||
| } | ||
| // Clear current harbors and seas | ||
| RTTR_FOREACH_PT(MapPoint, world.GetSize()) //-V807 | ||
| { | ||
|
|
@@ -446,6 +477,12 @@ bool MapLoader::InitSeasAndHarbors(World& world, const std::vector<MapPoint>& ad | |
| } | ||
| } | ||
|
|
||
| if(generateHarborSpots) | ||
| { | ||
| for(MapPoint pt : getGeneratedHarbors(world)) | ||
| world.harborData.push_back(HarborPos(pt)); | ||
| } | ||
|
|
||
| /// Determine seas adjacent to the harbor places | ||
| HarborId curHarborId(1); | ||
| for(auto it = world.harborData.begin(); it != world.harborData.end();) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.