-
Notifications
You must be signed in to change notification settings - Fork 94
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 all 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,18 @@ | ||
| // 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, _("Dangerous: Add limited extra harbor spots"), | ||
| _("Advanced option. Adds only a small deterministic set of suitable coastal castle sites as extra " | ||
| "harbor spots. May alter intended map seafaring design.")) | ||
| {} | ||
| }; |
| 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,7 +422,52 @@ 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; | ||
| } | ||
|
|
||
| bool isFarEnoughFromHarbors(const World& world, const MapPoint pt, const std::vector<MapPoint>& generatedHarbors) | ||
| { | ||
| 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. Similar as above: If you have a single vector of all harbor points this is much faster and shorter |
||
| { | ||
| if(world.CalcDistance(pt, world.GetHarborPoint(harborId)) < MapLoader::MIN_GENERATED_HARBOR_DISTANCE) | ||
| return false; | ||
| } | ||
| for(const MapPoint generatedHarbor : generatedHarbors) | ||
| { | ||
| if(world.CalcDistance(pt, generatedHarbor) < MapLoader::MIN_GENERATED_HARBOR_DISTANCE) | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| 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 | ||
| && isFarEnoughFromHarbors(world, pt, generatedHarbors)) | ||
| { | ||
| generatedHarbors.push_back(pt); | ||
| if(generatedHarbors.size() == MapLoader::MAX_GENERATED_HARBOR_SPOTS) | ||
| return generatedHarbors; | ||
| } | ||
| } | ||
| 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)); | ||
|
|
@@ -446,6 +493,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();) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The 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