99#include " GlobalGameSettings.h"
1010#include " PointOutput.h"
1111#include " RttrForeachPt.h"
12+ #include " addons/const_addons.h"
1213#include " buildings/nobHQ.h"
1314#include " factories/BuildingFactory.h"
1415#include " helpers/IdRange.h"
16+ #include " helpers/Range.h"
17+ #include " helpers/containerUtils.h"
18+ #include " helpers/mathFuncs.h"
1519#include " lua/GameDataLoader.h"
1620#include " pathfinding/PathConditionShip.h"
1721#include " random/Random.h"
@@ -106,6 +110,105 @@ bool MapLoader::PlaceHQs(bool addStartWares)
106110 return PlaceHQs (world_, hqPositions, addStartWares);
107111}
108112
113+ void MapLoader::SetupResources (GameWorldBase& world, const bool fixFish)
114+ {
115+ ResourceType target;
116+ switch (world.GetGGS ().getSelection (AddonId::CHANGE_GOLD_DEPOSITS ))
117+ {
118+ case 0 :
119+ default : target = ResourceType::Gold; break ;
120+ case 1 : target = ResourceType::Nothing; break ;
121+ case 2 : target = ResourceType::Iron; break ;
122+ case 3 : target = ResourceType::Coal; break ;
123+ case 4 : target = ResourceType::Granite; break ;
124+ }
125+ ConvertMineResourceTypes (world, ResourceType::Gold, target);
126+ PlaceAndFixWater (world);
127+ if (fixFish)
128+ RemoveUnusableFishResources (world);
129+ }
130+
131+ void MapLoader::ConvertMineResourceTypes (GameWorldBase& world, ResourceType from, ResourceType to)
132+ {
133+ // LOG.write(("Convert map resources from %i to %i\n", from, to);
134+ if (from == to)
135+ return ;
136+
137+ RTTR_FOREACH_PT (MapPoint, world.GetSize ())
138+ {
139+ Resource resources = world.GetNode (pt).resources ;
140+ // Gibt es Ressourcen dieses Typs?
141+ // Wenn ja, dann umwandeln bzw löschen
142+ if (resources.getType () == from)
143+ {
144+ resources.setType (to);
145+ world.SetResource (pt, resources);
146+ }
147+ }
148+ }
149+
150+ void MapLoader::PlaceAndFixWater (GameWorldBase& world)
151+ {
152+ const bool waterEverywhere = world.GetGGS ().getSelection (AddonId::EXHAUSTIBLE_WATER ) == 1 ;
153+
154+ RTTR_FOREACH_PT (MapPoint, world.GetSize ())
155+ {
156+ Resource curNodeResource = world.GetNode (pt).resources ;
157+
158+ if (curNodeResource.getType () == ResourceType::Nothing)
159+ {
160+ if (!waterEverywhere)
161+ continue ;
162+ } else if (curNodeResource.getType () != ResourceType::Water)
163+ continue ; // do not override maps resource.
164+
165+ uint8_t minHumidity = 100 ;
166+ for (const DescIdx<TerrainDesc> tIdx : world.GetTerrainsAround (pt))
167+ {
168+ const uint8_t curHumidity = world.GetDescription ().get (tIdx).humidity ;
169+ if (curHumidity < minHumidity)
170+ {
171+ minHumidity = curHumidity;
172+ if (minHumidity == 0 )
173+ break ;
174+ }
175+ }
176+ if (minHumidity)
177+ {
178+ curNodeResource =
179+ Resource (ResourceType::Water, waterEverywhere ? 7 : helpers::iround<uint8_t >(minHumidity * 7 . / 100 .));
180+ } else
181+ curNodeResource = Resource (ResourceType::Nothing, 0 );
182+
183+ world.SetResource (pt, curNodeResource);
184+ }
185+ }
186+
187+ void MapLoader::RemoveUnusableFishResources (GameWorldBase& world)
188+ {
189+ const auto isWaterPoint = [&world](const MapPoint nb) { return world.IsWaterPoint (nb); };
190+ for (const MapCoord y : helpers::range (world.GetHeight ()))
191+ {
192+ // Optimization: When there was fish on the previous node (in the same row)
193+ // we do not need to check for isolated water points, as there is at least that water point
194+ bool previousHasFish = false ;
195+ for (const MapCoord x : helpers::range (world.GetWidth ()))
196+ {
197+ const MapPoint pt (x, y);
198+ bool hasFish = false ;
199+
200+ if (world.GetNode (pt).resources .has (ResourceType::Fish))
201+ {
202+ if (isWaterPoint (pt) && (previousHasFish || helpers::contains_if (world.GetNeighbours (pt), isWaterPoint)))
203+ hasFish = true ;
204+ else
205+ world.SetResource (pt, Resource (ResourceType::Nothing, 0 ));
206+ }
207+ previousHasFish = hasFish;
208+ }
209+ }
210+ }
211+
109212void MapLoader::InitShadows (World& world)
110213{
111214 RTTR_FOREACH_PT (MapPoint, world.GetSize ())
@@ -117,7 +220,7 @@ void MapLoader::SetMapExplored(World& world)
117220 RTTR_FOREACH_PT (MapPoint, world.GetSize ())
118221 {
119222 // For every player
120- for (unsigned i = 0 ; i < MAX_PLAYERS ; ++i )
223+ for (const auto i : helpers::range ( MAX_PLAYERS ) )
121224 {
122225 // If we have FoW here, save it
123226 if (world.GetNode (pt).fow [i].visibility == Visibility::FogOfWar)
0 commit comments