How to make Pearl and Whale spawn independent of 'continents'

pokiehl

Moderator
Moderator
Joined
Mar 5, 2017
Messages
4,173
Pearls and whales, as luxury resources, generate tied to a specific continent. This has two problems:

1. It takes the place of a land-based luxury, making that continent's land comparatively less fruitful
2. It leads to massive clumping in the coastal waters around the assigned continent

How can we stop this linkage? Hellblazer's NQ mod appears to accomplish this via importing the Civ 5 AssignStartingPlots lua. I'd like to avoid this solution because I think it's heavy-handed. Here's what I THINK is the relevant part from the ResourceGenerator lua:

Code:
function ResourceGenerator:__PlaceWaterLuxury(eChosenLux, eContinent)
    -- Compute how many to place
    local iNumToPlace = 1;
    if(self.iOccurencesPerFrequency > 1) then
        iNumToPlace = self.iOccurencesPerFrequency;
    end

   
    -- Find the water luxury plots
    for k, v in pairs(self.aaPossibleLuxLocsWater[eChosenLux]) do
        self.aaPossibleLuxLocsWater[eChosenLux][k] = nil;
    end

    coastalPlots = Map.GetContinentCoastalPlots(eContinent, 2);
    for i, plot in ipairs(coastalPlots) do
        local pPlot = Map.GetPlotByIndex(plot);
        local bIce = false;
       
        if(IsAdjacentToIce(pPlot:GetX(), pPlot:GetY()) == true) then
            bIce = true;
        end

Of course, it may be somewhere else in the Lua...Any ideas? I'm stumped.
 
Last edited:
When I look at AssignStartingPlots.lua and other map related files, I'm always wondering if Germany would have won WWII if they had used Firaxis cipher machines instead of Enigma.
 
When I look at AssignStartingPlots.lua and other map related files, I'm always wondering if Germany would have won WWII if they had used Firaxis cipher machines instead of Enigma.

:lol: If a supremely experienced modder like you has trouble understanding their code, it makes me feel a little better about not being able to either!
 
Piggybacking on this topic, I would really like to create a map script that spawned ALL the luxury resources on a single standard-sized or bigger map, with smaller frequencies to compensate. In particular with Amatheria's Resourceful mod, which adds about 15 new resources, it would be very useful to more consistently see them all.
 
The __PlaceWaterLuxury function is accepting a Luxury and a Continent as input, then going thorugh the plots on that continent to place that luxury. __PlaceLuxuryResources does the same thing for land luxuries.

So you don't neccesarily need to change either of those functions, just call them more times to place more luxuries on the same continent.

There's a loop in __GetLuxuryResources (line 212) which goes through each continent, picks a luxury from a shuffled table, removes that luxury from the table so it can't be picked again, then calls one or other of the above functions to place it on the map:
Code:
for _, eContinent in ipairs(continentsInUse) do
  -- Shuffle the table
  --print ("Retrieved plots for continent: " .. tostring(eContinent));
  self:__ValidLuxuryPlots(eContinent);
  -- next find the valid plots for each of the luxuries
  local failed = 0;
  local iI = 1;
  while max >= iI and failed < 2 do
   local eChosenLux = self.aLuxuryType[self.aIndex[index]];
   local isValid = true;
  
   if (isValid == true and #self.aLuxuryType > 0) then
    table.remove(self.aLuxuryType,index);
    if(self:__IsCoastal(eChosenLux)) then
     self:__PlaceWaterLuxury(eChosenLux, eContinent);
    else
     self:__PlaceLuxuryResources(eChosenLux, eContinent);
    end
    index = index + 1;
    iI = iI + 1;
    failed = 0;
   end
   if index > #self.aLuxuryType then
    index = 1;
    failed = failed + 1;
   end
  end
 end

You could change that loop to always add pearls and whales to every continent, in addition to the randomly picked ones.

There's another loop in the same function (line 138) which assembles that list of luxuries in the first place:
Code:
 -- Find the Luxury Resources
 for row = 0, self.iResourcesInDB do
  local index = self.aIndex[row]
  if (self.eResourceClassType[row] == "RESOURCECLASS_LUXURY" and self.iFrequency[index] > 0) then
   local coast = false;
    
   for row2 in GameInfo.Resource_ValidTerrains() do
    if(GameInfo.Resources[row2.ResourceType].Hash == self.eResourceType[index] and row2.TerrainType=="TERRAIN_COAST") then
     coast = true;
    end
   end
   if(coast == true) then 
    table.insert(self.aLuxuryTypeCoast, index);
   end
   if(self.bCoastalBias == true or self.bLandBias == true) then
    if(coast == false) then 
     table.insert(aLandLuxury, index);  
    end
   else
    table.insert(self.aLuxuryType, index);  
   end
  end
 end
You could add an if statement there to stop RESOURCE_PEARLS or RESOURCE_WHALES from being added, thereby preventing them from appearing in the shuffled list later.

As for making all resources appear on the map, I'd probably rewrite the placement loop so that, instead of looping through each continent and adding i resources to it, it loops through each resource and adds it to i continents.
 
That sounds like the right approach to me. Does anyone have interest in working on such a thing with me? I don't know much about lua but trying to learn!
 
Anyone actually succeeded in doing this?

After all my prodding around, I only somehow managed to increase the number of spawned water luxuries, but since they each spawn on only 1 continent, the waters near it are absolutely full of it (over 90% shallow water tiles filled with either pearls or whales, no place left for fish or crabs.. or even harbour for that matter, until my coastal navigation tech or WTH it's named)

I don't know what's firaxis playing at... without AT LEAST a few water resources, the coastal cities are not even worth settling. What I wouldn't five for IGE.... or at least a working world builder....
 
Back
Top Bottom