Oops... any way to allow a first turn settler?

luckybutjinxed

Chieftain
Joined
May 2, 2017
Messages
20
So I'm making a mod for Venice and I finally got a way to replace the settler with another unit. Said unit doesn't found cities, but is supposed to do something else (It doesn't, but I'll worry about that problem later).

Just one problem... now my first turn settler is that unit too, and it can't found my starting city.

Is there anyway I can put back the settler for the first turn? Or force the new unit to only be able to settle the first city? Or should I ditch the idea entirely?
 
Could use a lua script to create a settler on turn 0 which could be used to found that first city. I believe when you call the CreateUnit method in Lua it will not convert it to your new unit type.
 
I'm working on a mod similar to Venice, and needed to spawn more Settlers straight off the bat.

Would spawning a new settler solve your issue? If so it's quite easy:

<MajorStartingUnits>
<Row Era="ERA_ANCIENT" Unit="UNIT_SETTLER" NotStartTile="true"/>
<Row Era="ERA_ANCIENT" Unit="UNIT_SETTLER" NotStartTile="true"/>
<Row Era="ERA_ANCIENT" Unit="UNIT_SETTLER" NotStartTile="true"/>
</MajorStartingUnits>

This would spawn 3 extra settlers (not including the default one).

EDIT:

Scratch that, just tried it on multi and everyone spawned with the units for some reason.
 
Last edited:
I'm working on a mod similar to Venice, and needed to spawn more Settlers straight off the bat.

Would spawning a new settler solve your issue? If so it's quite easy:

<MajorStartingUnits>
<Row Era="ERA_ANCIENT" Unit="UNIT_SETTLER" NotStartTile="true"/>
<Row Era="ERA_ANCIENT" Unit="UNIT_SETTLER" NotStartTile="true"/>
<Row Era="ERA_ANCIENT" Unit="UNIT_SETTLER" NotStartTile="true"/>
</MajorStartingUnits>

This would spawn 3 extra settlers (not including the default one).
Just tried it. The unit protocol to replace all settlers forces the game to give me 2 Merchants of Venice instead.
 
Could use a lua script to create a settler on turn 0 which could be used to found that first city. I believe when you call the CreateUnit method in Lua it will not convert it to your new unit type.

I'll have to look up how to do this and get back to you on whether or not it works.
 
I'm working on a mod similar to Venice, and needed to spawn more Settlers straight off the bat.

Would spawning a new settler solve your issue? If so it's quite easy:

<MajorStartingUnits>
<Row Era="ERA_ANCIENT" Unit="UNIT_SETTLER" NotStartTile="true"/>
<Row Era="ERA_ANCIENT" Unit="UNIT_SETTLER" NotStartTile="true"/>
<Row Era="ERA_ANCIENT" Unit="UNIT_SETTLER" NotStartTile="true"/>
</MajorStartingUnits>

This would spawn 3 extra settlers (not including the default one).

EDIT:

Scratch that, just tried it on multi and everyone spawned with the units for some reason.
everyone will because <MajorStartingUnits> applies to all major civilizations in the game, not just the human player.

But the game will do auto-replacing to give the correct replacement unit for a civ rather than the "vanilla" unit actually stated.
 
Alright, if you're still looking for a way to spawn specific units, I've found one that I modified and works only for the human players this time.

Essentially it's the one found here: http://www.nexusmods.com/civilisationvi/mods/9/?

Here is the code:

Code:
local numSettlers = 1  --------------------------------------------set number of extra starting settlers for player
local iSettler = GameInfo.Units["UNIT_SETTLER"].Index -------------set unit

function OnPlayerTurnActivated( player, bIsFirstTime )
    local currentTurn = Game.GetCurrentGameTurn();
    local SpawnTurn = 0;
    local playerUnits;  
    local adjacentPlot;
    local unitPlot;

    if currentTurn == GameConfiguration.GetStartTurn() then
        local pPlayer = Players[player]
        if pPlayer:IsHuman() then
            playerUnits = pPlayer:GetUnits()
            for i, unit in playerUnits:Members() do
                local unitTypeName = UnitManager.GetTypeName(unit)
                if "LOC_UNIT_SETTLER_NAME" == unitTypeName then
                    SpawnTurn = 1;
                    unitPlot = Map.GetPlot(unit:GetX(), unit:GetY());      
                end
            end
        end      
        if SpawnTurn == 1 then
            local lastPlot = unitPlot;
            if numSettlers > 0 then
                for i = 1, numSettlers do  
                    for direction = 1, DirectionTypes.NUM_DIRECTION_TYPES - 1, 1 do
                        adjacentPlot = Map.GetAdjacentPlot((lastPlot:GetX() ), lastPlot:GetY(), direction);
                        if (adjacentPlot ~= nil) and not (adjacentPlot:IsWater() or adjacentPlot:IsImpassable()) then
                            break      
                        end
                    end
                    pUnit = playerUnits:Create(iSettler, adjacentPlot:GetX(), adjacentPlot:GetY())  
                    lastPlot = Map.GetPlot(pUnit:GetX(), pUnit:GetY());
                end  
            end
        end
    end
end
           


function Initialize()
Events.LocalPlayerChanged.Add(OnPlayerTurnActivated);
Events.PlayerTurnActivated.Add(OnPlayerTurnActivated);
end

Initialize();

This script needs to be modified to only spawn a settler for you though.
 
Last edited:
this can never evaluate to true if he has no starting settler:
Code:
if "LOC_UNIT_SETTLER_NAME" == unitTypeName then

You would probably be better off looking for whether the player has any cities or any settlers, and if the player has neither, use
Code:
Player:GetStartingPlot()
I believe this will return the starting plot's object for the player, which can then be used in a similar manner as adjacentPlot is being used to get a valid XY position to spawn a settler unit.
 
  1. You need to replace CIVILIZATION_ROME with the correct name as you are using it for your civilization, and you do need the " marks at each end
  2. Whether or not the game will then auto-replace this settler is something I don't know.
  3. The code needs to be placed into an lua file, and the file's action added as an In-Game Actions Action in Modbuddy with an action-type of AddGameplayScripts
    Code:
    local sRequiredCivilizationName = "CIVILIZATION_ROME"
    local iSettlerIndex = GameInfo.Units["UNIT_SETTLER"].Index
    
    for iLoopPlayer = 0, 62 do
    	local pLoopPlayer = Players[iLoopPlayer]
    	if pLoopPlayer:IsAlive() and (PlayerConfigurations[iLoopPlayer]:GetCivilizationTypeName() == sRequiredCivilizationName) then
    		if (pLoopPlayer:GetCities():GetCount() == 0) then
    			local bHasSettlers = false
    			local pLoopPlayerUnits = pLoopPlayer:GetUnits()
    			for i, pUnit in pLoopPlayerUnits:Members() do
    				if pUnit:GetType() == iSettlerIndex then
    					bHasSettlers = true
    					break
    				end
    			end
    			if (bHasSettlers == false) then
    				local pPlot = pLoopPlayer:GetStartingPlot()
    				pLoopPlayerUnits:Create(iSettlerIndex, pPlot:GetX(), pPlot:GetY())
    			end
    		end
    	end
    end
 
Alternative (probably better) code method would be:
Code:
local sRequiredCivilizationName = "CIVILIZATION_ROME"
local iSettlerIndex = GameInfo.Units["UNIT_SETTLER"].Index

function OnPlayerTurnActivated(iPlayer)
	if (PlayerConfigurations[iPlayer]:GetCivilizationTypeName() == sRequiredCivilizationName) then
		local pPlayer = Players[iPlayer]
		if (pPlayer:GetCities():GetCount() == 0) then
			local bHasSettlers = false
			local pPlayerUnits = pPlayer:GetUnits()
			for i, pUnit in pPlayerUnits:Members() do
				if pUnit:GetType() == iSettlerIndex then
					bHasSettlers = true
					break
				end
			end
			if (bHasSettlers == false) then
				local pPlot = pPlayer:GetStartingPlot()
				pPlayerUnits:Create(iSettlerIndex, pPlot:GetX(), pPlot:GetY())
			end
		end
	end
end
Events.PlayerTurnActivated.Add(OnPlayerTurnActivated)
This method does not rely on game loading game turn or anything else except whether it is the correct player and whether or not that player has any cities or settlers. Essentially the only time it would execute would be on the starting turn of the game, because it would add a settler to the player at the player's starting location, and thereafter that player would already have either a city or a settler so the code would not add another settler unless something bad happened like the player shifted the settler around looking for a better city spot, and the settler got eaten by the barbs.
 
Alternative (probably better) code method would be:
Code:
local sRequiredCivilizationName = "CIVILIZATION_ROME"
local iSettlerIndex = GameInfo.Units["UNIT_SETTLER"].Index

function OnPlayerTurnActivated(iPlayer)
    if (PlayerConfigurations[iPlayer]:GetCivilizationTypeName() == sRequiredCivilizationName) then
        local pPlayer = Players[iPlayer]
        if (pPlayer:GetCities():GetCount() == 0) then
            local bHasSettlers = false
            local pPlayerUnits = pPlayer:GetUnits()
            for i, pUnit in pPlayerUnits:Members() do
                if pUnit:GetType() == iSettlerIndex then
                    bHasSettlers = true
                    break
                end
            end
            if (bHasSettlers == false) then
                local pPlot = pPlayer:GetStartingPlot()
                pPlayerUnits:Create(iSettlerIndex, pPlot:GetX(), pPlot:GetY())
            end
        end
    end
end
Events.PlayerTurnActivated.Add(OnPlayerTurnActivated)
This method does not rely on game loading game turn or anything else except whether it is the correct player and whether or not that player has any cities or settlers. Essentially the only time it would execute would be on the starting turn of the game, because it would add a settler to the player at the player's starting location, and thereafter that player would already have either a city or a settler so the code would not add another settler unless something bad happened like the player shifted the settler around looking for a better city spot, and the settler got eaten by the barbs.

This worked like a charm! Thank you LeeS!
 
Back
Top Bottom