Quantcast
Channel: Civilization Fanatics' Forums
Viewing all articles
Browse latest Browse all 12856

Lua help needed: AssignStartingPlots:FindStart()

$
0
0
I'm not very familiar with Lua at all and only to a certain extent can I logically figure out what the heck it's doing by staring at it, highlighting things, following the steps of the code, and Googling :crazyeye:. I'd greatly appreciate any help on this from someone more knowledgeable! Okay, where to start...

It's not really a big issue. Within a modded map script of mine, I simply wanted to prevent city start locations on tiles not only two tiles from water, but also three tiles as well. Again, yeah, it's not the end of the world if your city starts in a spot like this since it's the outer most ring and there are more than enough other tiles to work -- it's a bit like getting mountains within your workable radius. But, if all it takes are some simple adjustments, then I think it could be worth it.

A quick (and hopefully somewhat accurate) description:
As far as I can tell, the game currently disqualifies land tiles that are two tiles from water. Within AssignStartingPlots:FindStart(), it searches for and designates tiles throughout the map as candidates. One of its tables is called two_plots_from_ocean, which it labels as disqualified and does nothing with (I think). The function that is called to figure out if the current plot index should be inserted into that table is GenerateNextToCoastalLandDataTables() within MapmakerUtilities.lua (so, I guess that would be MapmakerUtilities:GenerateNextToCoastalLandDataTab les()?). So, once the plotDataIsCoastal table is created and updated, The "NextToCoastal" function above searches for tiles that are neither water or labeled as coastal in the plotDataIsCoastal table, then it searches all adjacent tiles for "coastal" land tiles. If it picks anything up, then the current index is labeled as a "next to coast" land tile.

So, I created a new function called GenerateNearCoastalLandDataTables() by copying GenerateNextToCoastalLandDataTables() and changing variables around. This functions just like the existing function except that it uses the complete "is coastal" (adjacent to water) and "is next to coastal" (2 tiles from water) tables to create another table of plot indexes which lists which tiles are "near to coastal" (3 tiles from water).


My new function, GenerateNearCoastalLandDataTables(), copied from an existing, similar function:
Spoiler:
Code:

-- New function to construct a table of tiles that are 3 tiles from water.
function GenerateNearCoastalLandDataTables()
        -- Set up data table for IsCoastal and IsNextToCoast
        local plotDataIsCoastal = GenerateCoastalLandDataTable()
        local plotDataIsNextToCoast = GenerateNextToCoastalLandDataTables()

        -- Set up data table for NearCoast
        local iW, iH = Map.GetGridSize();
        local plotDataIsNearCoast = {};
        table.fill(plotDataIsNearCoast, false, iW * iH);
        -- When generating a plot data table incrementally, process Y first so that plots go row by row.
        -- Keeping plot data table indices consistent with the main plot database could save you enormous grief.
        -- In this case, accessing an existing table by plot index, it doesn't matter.
        for x = 0, iW - 1 do
                for y = 0, iH - 1 do
                        local i = iW * y + x + 1;
                        local plot = Map.GetPlot(x, y);
                        if plotDataIsCoastal[i] == false and plotDataIsNextToCoast[i] == false and not plot:IsWater() then -- plot is not itself on the coast, or next to coast, or in the water.
                                -- So we will check all adjacent plots to see if any of those are next to the coast.
                                local NEPlot = Map.PlotDirection(x, y, DirectionTypes.DIRECTION_NORTHEAST);
                                local EPlot = Map.PlotDirection(x, y, DirectionTypes.DIRECTION_EAST);
                                local SEPlot = Map.PlotDirection(x, y, DirectionTypes.DIRECTION_SOUTHEAST);
                                local SWPlot = Map.PlotDirection(x, y, DirectionTypes.DIRECTION_SOUTHWEST);
                                local WPlot = Map.PlotDirection(x, y, DirectionTypes.DIRECTION_WEST);
                                local NWPlot = Map.PlotDirection(x, y, DirectionTypes.DIRECTION_NORTHWEST);
                                --
                                -- Check plot to northeast of current plot. This operation accounts for map edge and world wrap.
                                if NEPlot ~= nil then
                                        local adjX = NEPlot:GetX();
                                        local adjY = NEPlot:GetY();
                                        local adjI = iW * adjY + adjX + 1;
                                        if plotDataIsNextToCoast[adjI] == true then
                                                -- The current loop plot is not itself on the coast or next to coast but is "near" the coast (within 3 tiles).
                                                plotDataIsNearCoast[i] = true;
                                        end
                                end
                                -- Check plot to east of current plot.
                                if EPlot ~= nil then
                                        local adjX = EPlot:GetX();
                                        local adjY = EPlot:GetY();
                                        local adjI = iW * adjY + adjX + 1;
                                        if plotDataIsNextToCoast[adjI] == true then
                                                plotDataIsNearCoast[i] = true;
                                        end
                                end
                                -- Check plot to southeast of current plot.
                                if SEPlot ~= nil then
                                        local adjX = SEPlot:GetX();
                                        local adjY = SEPlot:GetY();
                                        local adjI = iW * adjY + adjX + 1;
                                        if plotDataIsNextToCoast[adjI] == true then
                                                plotDataIsNearCoast[i] = true;
                                        end
                                end
                                -- Check plot to southwest of current plot.
                                if SWPlot ~= nil then
                                        local adjX = SWPlot:GetX();
                                        local adjY = SWPlot:GetY();
                                        local adjI = iW * adjY + adjX + 1;
                                        if plotDataIsNextToCoast[adjI] == true then
                                                plotDataIsNearCoast[i] = true;
                                        end
                                end
                                -- Check plot to west of current plot.
                                if WPlot ~= nil then
                                        local adjX = WPlot:GetX();
                                        local adjY = WPlot:GetY();
                                        local adjI = iW * adjY + adjX + 1;
                                        if plotDataIsNextToCoast[adjI] == true then
                                                plotDataIsNearCoast[i] = true;
                                        end
                                end
                                -- Check plot to northwest of current plot.
                                if NWPlot ~= nil then
                                        local adjX = NWPlot:GetX();
                                        local adjY = NWPlot:GetY();
                                        local adjI = iW * adjY + adjX + 1;
                                        if plotDataIsNextToCoast[adjI] == true then
                                                plotDataIsNearCoast[i] = true;
                                        end
                                end
                        end
                end
        end
       
        -- returns tables
        return plotDataIsCoastal, plotDataIsNextToCoast, plotDataIsNearCoast
end



Here is the original GenerateNextToCoastalLandDataTables() I copied off of:
Spoiler:

Code:

function GenerateNextToCoastalLandDataTables()
        -- Set up data table for IsCoastal
        local plotDataIsCoastal = GenerateCoastalLandDataTable()

        -- Set up data table for IsNextToCoast
        local iW, iH = Map.GetGridSize();
        local plotDataIsNextToCoast = {};
        table.fill(plotDataIsNextToCoast, false, iW * iH);
        -- When generating a plot data table incrementally, process Y first so that plots go row by row.
        -- Keeping plot data table indices consistent with the main plot database could save you enormous grief.
        -- In this case, accessing an existing table by plot index, it doesn't matter.
        for x = 0, iW - 1 do
                for y = 0, iH - 1 do
                        local i = iW * y + x + 1;
                        local plot = Map.GetPlot(x, y);
                        if plotDataIsCoastal[i] == false and not plot:IsWater() then -- plot is not itself on the coast or in the water.
                                -- So we will check all adjacent plots to see if any of those are on the coast.
                                local NEPlot = Map.PlotDirection(x, y, DirectionTypes.DIRECTION_NORTHEAST);
                                local EPlot = Map.PlotDirection(x, y, DirectionTypes.DIRECTION_EAST);
                                local SEPlot = Map.PlotDirection(x, y, DirectionTypes.DIRECTION_SOUTHEAST);
                                local SWPlot = Map.PlotDirection(x, y, DirectionTypes.DIRECTION_SOUTHWEST);
                                local WPlot = Map.PlotDirection(x, y, DirectionTypes.DIRECTION_WEST);
                                local NWPlot = Map.PlotDirection(x, y, DirectionTypes.DIRECTION_NORTHWEST);
                                --
                                -- Check plot to northeast of current plot. This operation accounts for map edge and world wrap.
                                if NEPlot ~= nil then
                                        local adjX = NEPlot:GetX();
                                        local adjY = NEPlot:GetY();
                                        local adjI = iW * adjY + adjX + 1;
                                        if plotDataIsCoastal[adjI] == true then
                                                -- The current loop plot is not itself on the coast but is next to a plot that is on the coast.
                                                plotDataIsNextToCoast[i] = true;
                                        end
                                end
                                -- Check plot to east of current plot.
                                if EPlot ~= nil then
                                        local adjX = EPlot:GetX();
                                        local adjY = EPlot:GetY();
                                        local adjI = iW * adjY + adjX + 1;
                                        if plotDataIsCoastal[adjI] == true then
                                                plotDataIsNextToCoast[i] = true;
                                        end
                                end
                                -- Check plot to southeast of current plot.
                                if SEPlot ~= nil then
                                        local adjX = SEPlot:GetX();
                                        local adjY = SEPlot:GetY();
                                        local adjI = iW * adjY + adjX + 1;
                                        if plotDataIsCoastal[adjI] == true then
                                                plotDataIsNextToCoast[i] = true;
                                        end
                                end
                                -- Check plot to southwest of current plot.
                                if SWPlot ~= nil then
                                        local adjX = SWPlot:GetX();
                                        local adjY = SWPlot:GetY();
                                        local adjI = iW * adjY + adjX + 1;
                                        if plotDataIsCoastal[adjI] == true then
                                                plotDataIsNextToCoast[i] = true;
                                        end
                                end
                                -- Check plot to west of current plot.
                                if WPlot ~= nil then
                                        local adjX = WPlot:GetX();
                                        local adjY = WPlot:GetY();
                                        local adjI = iW * adjY + adjX + 1;
                                        if plotDataIsCoastal[adjI] == true then
                                                plotDataIsNextToCoast[i] = true;
                                        end
                                end
                                -- Check plot to northwest of current plot.
                                if NWPlot ~= nil then
                                        local adjX = NWPlot:GetX();
                                        local adjY = NWPlot:GetY();
                                        local adjI = iW * adjY + adjX + 1;
                                        if plotDataIsCoastal[adjI] == true then
                                                plotDataIsNextToCoast[i] = true;
                                        end
                                end
                        end
                end
        end
       
        -- returns table, table
        return plotDataIsCoastal, plotDataIsNextToCoast
end



This is my modified AssignStartingPlots:FindStart() with modifications highlighted in red:
Spoiler:

Code:

-- Modified to also disqualify land tiles that are 3 tiles from water for potential starting city locations.
function AssignStartingPlots:FindStart(region_number)
        -- This function attempts to choose a start position for a single region.
        -- This function returns two boolean flags, indicating the success level of the operation.
        local bSuccessFlag = false; -- Returns true when a start is placed, false when process fails.
        local bForcedPlacementFlag = false; -- Returns true if this region had no eligible starts and one was forced to occur.
       
        -- Obtain data needed to process this region.
        local iW, iH = Map.GetGridSize();
        local region_data_table = self.regionData[region_number];
        local iWestX = region_data_table[1];
        local iSouthY = region_data_table[2];
        local iWidth = region_data_table[3];
        local iHeight = region_data_table[4];
        local iAreaID = region_data_table[5];
        local iMembershipEastX = iWestX + iWidth - 1;
        local iMembershipNorthY = iSouthY + iHeight - 1;
        --
        local terrainCounts = self.regionTerrainCounts[region_number];
        --
        local region_type = self.regionTypes[region_number];
        -- Done setting up region data.
        -- Set up contingency.
        local fallback_plots = {};
       
        -- Establish scope of center bias.
        local fCenterWidth = (self.centerBias / 100) * iWidth;
        local iNonCenterWidth = math.floor((iWidth - fCenterWidth) / 2)
        local iCenterWidth = iWidth - (iNonCenterWidth * 2);
        local iCenterWestX = (iWestX + iNonCenterWidth) % iW; -- Modulo math to synch coordinate to actual map in case of world wrap.
        local iCenterTestWestX = (iWestX + iNonCenterWidth); -- "Test" values ignore world wrap for easier membership testing.
        local iCenterTestEastX = (iCenterWestX + iCenterWidth - 1);

        local fCenterHeight = (self.centerBias / 100) * iHeight;
        local iNonCenterHeight = math.floor((iHeight - fCenterHeight) / 2)
        local iCenterHeight = iHeight - (iNonCenterHeight * 2);
        local iCenterSouthY = (iSouthY + iNonCenterHeight) % iH;
        local iCenterTestSouthY = (iSouthY + iNonCenterHeight);
        local iCenterTestNorthY = (iCenterTestSouthY + iCenterHeight - 1);

        -- Establish scope of "middle donut", outside the center but inside the outer.
        local fMiddleWidth = (self.middleBias / 100) * iWidth;
        local iOuterWidth = math.floor((iWidth - fMiddleWidth) / 2)
        local iMiddleWidth = iWidth - (iOuterWidth * 2);
        local iMiddleWestX = (iWestX + iOuterWidth) % iW;
        local iMiddleTestWestX = (iWestX + iOuterWidth);
        local iMiddleTestEastX = (iMiddleTestWestX + iMiddleWidth - 1);

        local fMiddleHeight = (self.middleBias / 100) * iHeight;
        local iOuterHeight = math.floor((iHeight - fMiddleHeight) / 2)
        local iMiddleHeight = iHeight - (iOuterHeight * 2);
        local iMiddleSouthY = (iSouthY + iOuterHeight) % iH;
        local iMiddleTestSouthY = (iSouthY + iOuterHeight);
        local iMiddleTestNorthY = (iMiddleTestSouthY + iMiddleHeight - 1);

        -- Assemble candidates lists.
        local three_plots_from_ocean = {};                -- MOD
        local two_plots_from_ocean = {};
        local center_candidates = {};
        local center_river = {};
        local center_coastal = {};
        local center_inland_dry = {};
        local middle_candidates = {};
        local middle_river = {};
        local middle_coastal = {};
        local middle_inland_dry = {};
        local outer_plots = {};
       
        -- Identify candidate plots.
        for region_y = 0, iHeight - 1 do -- When handling global plot indices, process Y first.
                for region_x = 0, iWidth - 1 do
                        local x = (region_x + iWestX) % iW; -- Actual coords, adjusted for world wrap, if any.
                        local y = (region_y + iSouthY) % iH; --
                        local plotIndex = y * iW + x + 1;
                        local plot = Map.GetPlot(x, y);
                        local plotType = plot:GetPlotType()
                        if plotType == PlotTypes.PLOT_HILLS or plotType == PlotTypes.PLOT_LAND then -- Could host a city.
                                -- Check if plot is two away from salt water.
                                if self.plotDataIsNextToCoast[plotIndex] == true then
                                        table.insert(two_plots_from_ocean, plotIndex);
                                elseif self.plotDataIsNearCoast[plotIndex] == true then                -- MOD
                                        table.insert(three_plots_from_ocean, plotIndex);                -- MOD

                                else
                                        local area_of_plot = plot:GetArea();
                                        if area_of_plot == iAreaID or iAreaID == -1 then -- This plot is a member, so it goes on at least one candidate list.
                                                --
                                                -- Test whether plot is in center bias, middle donut, or outer donut.
                                                --
                                                local test_x = region_x + iWestX; -- "Test" coords, ignoring any world wrap and
                                                local test_y = region_y + iSouthY; -- reaching in to virtual space if necessary.
                                                if (test_x >= iCenterTestWestX and test_x <= iCenterTestEastX) and
                                                  (test_y >= iCenterTestSouthY and test_y <= iCenterTestNorthY) then -- Center Bias.
                                                        table.insert(center_candidates, plotIndex);
                                                        if plot:IsRiverSide() then
                                                                table.insert(center_river, plotIndex);
                                                        elseif plot:IsFreshWater() or self.plotDataIsCoastal[plotIndex] == true then
                                                                table.insert(center_coastal, plotIndex);
                                                        else
                                                                table.insert(center_inland_dry, plotIndex);
                                                        end
                                                elseif (test_x >= iMiddleTestWestX and test_x <= iMiddleTestEastX) and
                                                      (test_y >= iMiddleTestSouthY and test_y <= iMiddleTestNorthY) then
                                                        table.insert(middle_candidates, plotIndex);
                                                        if plot:IsRiverSide() then
                                                                table.insert(middle_river, plotIndex);
                                                        elseif plot:IsFreshWater() or self.plotDataIsCoastal[plotIndex] == true then
                                                                table.insert(middle_coastal, plotIndex);
                                                        else
                                                                table.insert(middle_inland_dry, plotIndex);
                                                        end
                                                else
                                                        table.insert(outer_plots, plotIndex);
                                                end
                                        end
                                end
                        end
                end
        end

        -- Check how many plots landed on each list.
        local iNumDisqualified = table.maxn(two_plots_from_ocean) + table.maxn(three_plots_from_ocean);                -- MOD
        local iNumCenter = table.maxn(center_candidates);
        local iNumCenterRiver = table.maxn(center_river);
        local iNumCenterCoastLake = table.maxn(center_coastal);
        local iNumCenterInlandDry = table.maxn(center_inland_dry);
        local iNumMiddle = table.maxn(middle_candidates);
        local iNumMiddleRiver = table.maxn(middle_river);
        local iNumMiddleCoastLake = table.maxn(middle_coastal);
        local iNumMiddleInlandDry = table.maxn(middle_inland_dry);
        local iNumOuter = table.maxn(outer_plots);
       
        --[[ Debug printout.
        print("-");
        print("--- Number of Candidate Plots in Region #", region_number, " - Region Type:", region_type, " ---");
        print("-");
        print("Candidates in Center Bias area: ", iNumCenter);
        print("Which are next to river: ", iNumCenterRiver);
        print("Which are next to lake or sea: ", iNumCenterCoastLake);
        print("Which are inland and dry: ", iNumCenterInlandDry);
        print("-");
        print("Candidates in Middle Donut area: ", iNumMiddle);
        print("Which are next to river: ", iNumMiddleRiver);
        print("Which are next to lake or sea: ", iNumMiddleCoastLake);
        print("Which are inland and dry: ", iNumMiddleInlandDry);
        print("-");
        print("Candidate Plots in Outer area: ", iNumOuter);
        print("-");
        print("Disqualified, two plots away from salt water: ", iNumDisqualified);
        print("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
        ]]--
       
        -- Process lists of candidate plots.
        if iNumCenter + iNumMiddle > 0 then
                local candidate_lists = {};
                if iNumCenterRiver > 0 then -- Process center bias river plots.
                        table.insert(candidate_lists, center_river);
                end
                if iNumCenterCoastLake > 0 then -- Process center bias lake or coastal plots.
                        table.insert(candidate_lists, center_coastal);
                end
                if iNumCenterInlandDry > 0 then -- Process center bias inland dry plots.
                        table.insert(candidate_lists, center_inland_dry);
                end
                if iNumMiddleRiver > 0 then -- Process middle donut river plots.
                        table.insert(candidate_lists, middle_river);
                end
                if iNumMiddleCoastLake > 0 then -- Process middle donut lake or coastal plots.
                        table.insert(candidate_lists, middle_coastal);
                end
                if iNumMiddleInlandDry > 0 then -- Process middle donut inland dry plots.
                        table.insert(candidate_lists, middle_inland_dry);
                end
                --
                for loop, plot_list in ipairs(candidate_lists) do -- Up to six plot lists, processed by priority.
                        local election_returns = self:IterateThroughCandidatePlotList(plot_list, region_type)
                        -- If any candidates are eligible, choose one.
                        local found_eligible = election_returns[1];
                        if found_eligible then
                                local bestPlotScore = election_returns[2];
                                local bestPlotIndex = election_returns[3];
                                local x = (bestPlotIndex - 1) % iW;
                                local y = (bestPlotIndex - x - 1) / iW;
                                self.startingPlots[region_number] = {x, y, bestPlotScore};
                                self:PlaceImpactAndRipples(x, y)
                                return true, false
                        end
                        -- If none eligible, check for fallback plot.
                        local found_fallback = election_returns[4];
                        if found_fallback then
                                local bestFallbackScore = election_returns[5];
                                local bestFallbackIndex = election_returns[6];
                                local x = (bestFallbackIndex - 1) % iW;
                                local y = (bestFallbackIndex - x - 1) / iW;
                                table.insert(fallback_plots, {x, y, bestFallbackScore});
                        end
                end
        end
        -- Reaching this point means no eligible sites in center bias or middle donut subregions!
       
        -- Process candidates from Outer subregion, if any.
        if iNumOuter > 0 then
                local outer_eligible_list = {};
                local found_eligible = false;
                local found_fallback = false;
                local bestFallbackScore = -50;
                local bestFallbackIndex;
                -- Process list of candidate plots.
                for loop, plotIndex in ipairs(outer_plots) do
                        local score, meets_minimums = self:EvaluateCandidatePlot(plotIndex, region_type)
                        -- Test current plot against best known plot.
                        if meets_minimums == true then
                                found_eligible = true;
                                table.insert(outer_eligible_list, plotIndex);
                        else
                                found_fallback = true;
                                if score > bestFallbackScore then
                                        bestFallbackScore = score;
                                        bestFallbackIndex = plotIndex;
                                end
                        end
                end
                if found_eligible then -- Iterate through eligible plots and choose the one closest to the center of the region.
                        local closestPlot;
                        local closestDistance = math.max(iW, iH);
                        local bullseyeX = iWestX + (iWidth / 2);
                        if bullseyeX < iWestX then -- wrapped around: un-wrap it for test purposes.
                                bullseyeX = bullseyeX + iW;
                        end
                        local bullseyeY = iSouthY + (iHeight / 2);
                        if bullseyeY < iSouthY then -- wrapped around: un-wrap it for test purposes.
                                bullseyeY = bullseyeY + iH;
                        end
                        if bullseyeY / 2 ~= math.floor(bullseyeY / 2) then -- Y coord is odd, add .5 to X coord for hex-shift.
                                bullseyeX = bullseyeX + 0.5;
                        end
                       
                        for loop, plotIndex in ipairs(outer_eligible_list) do
                                local x = (plotIndex - 1) % iW;
                                local y = (plotIndex - x - 1) / iW;
                                local adjusted_x = x;
                                local adjusted_y = y;
                                if y / 2 ~= math.floor(y / 2) then -- Y coord is odd, add .5 to X coord for hex-shift.
                                        adjusted_x = x + 0.5;
                                end
                               
                                if x < iWestX then -- wrapped around: un-wrap it for test purposes.
                                        adjusted_x = adjusted_x + iW;
                                end
                                if y < iSouthY then -- wrapped around: un-wrap it for test purposes.
                                        adjusted_y = y + iH;
                                end
                                local fDistance = math.sqrt( (adjusted_x - bullseyeX)^2 + (adjusted_y - bullseyeY)^2 );
                                if fDistance < closestDistance then -- Found new "closer" plot.
                                        closestPlot = plotIndex;
                                        closestDistance = fDistance;
                                end
                        end
                        -- Assign the closest eligible plot as the start point.
                        local x = (closestPlot - 1) % iW;
                        local y = (closestPlot - x - 1) / iW;
                        -- Re-get plot score for inclusion in start plot data.
                        local score, meets_minimums = self:EvaluateCandidatePlot(closestPlot, region_type)
                        -- Assign this plot as the start for this region.
                        self.startingPlots[region_number] = {x, y, score};
                        self:PlaceImpactAndRipples(x, y)
                        return true, false
                end
                -- Add the fallback plot (best scored plot) from the Outer region to the fallback list.
                if found_fallback then
                        local x = (bestFallbackIndex - 1) % iW;
                        local y = (bestFallbackIndex - x - 1) / iW;
                        table.insert(fallback_plots, {x, y, bestFallbackScore});
                end
        end
        -- Reaching here means no plot in the entire region met the minimum standards for selection.
       
        -- The fallback plot contains the best-scored plots from each test area in this region.
        -- We will compare all the fallback plots and choose the best to be the start plot.
        local iNumFallbacks = table.maxn(fallback_plots);
        if iNumFallbacks > 0 then
                local best_fallback_score = 0
                local best_fallback_x;
                local best_fallback_y;
                for loop, plotData in ipairs(fallback_plots) do
                        local score = plotData[3];
                        if score > best_fallback_score then
                                best_fallback_score = score;
                                best_fallback_x = plotData[1];
                                best_fallback_y = plotData[2];
                        end
                end
                -- Assign the start for this region.
                self.startingPlots[region_number] = {best_fallback_x, best_fallback_y, best_fallback_score};
                self:PlaceImpactAndRipples(best_fallback_x, best_fallback_y)
                bSuccessFlag = true;
        else
                -- This region cannot have a start and something has gone way wrong.
                -- We'll force a one tile grass island in the SW corner of the region and put the start there.
                local forcePlot = Map.GetPlot(iWestX, iSouthY);
                bSuccessFlag = true;
                bForcedPlacementFlag = true;
                forcePlot:SetPlotType(PlotTypes.PLOT_LAND, false, true);
                forcePlot:SetTerrainType(TerrainTypes.TERRAIN_GRASS, false, true);
                forcePlot:SetFeatureType(FeatureTypes.NO_FEATURE, -1);
                self.startingPlots[region_number] = {iWestX, iSouthY, 0};
                self:PlaceImpactAndRipples(iWestX, iSouthY)
        end

        return bSuccessFlag, bForcedPlacementFlag
end



I must have missed something or did something incorrectly because once a game begins, it immediately ends as a loss because the map isn't generated correctly. :lol: I have the two functions in a new Small Continents Deluxe script I'm working on. It worked perfectly until I added these two functions.

I believe these are the Lua errors within the log, if it helps:
Code:

[16921.631] Runtime Error: [string "Small_Continents_Deluxe.lua"]:370: attempt to index field 'plotDataIsNearCoast' (a nil value)
stack traceback:
        [string "Small_Continents_Deluxe.lua"]:370: in function 'FindStart'
        [string "Assets\DLC\Expansion\Gameplay\Lua\AssignSta..."]:3437: in function 'ChooseLocations'
        [string "Small_Continents_Deluxe.lua"]:913: in function 'StartPlotSystem'
        [string "Assets\DLC\Expansion\Gameplay\Lua\MapGenera..."]:815: in function <[string "Assets\DLC\Expansion\Gameplay\Lua\MapGenera..."]:779>
        [C]: ?

Also, attached are the two functions in a Lua file if one prefers to view it there (probably easier).

Attached Files
File Type: zip code in lua.zip (4.3 KB)

Viewing all articles
Browse latest Browse all 12856

Latest Images

Trending Articles



Latest Images