[LUA] change starting locations in civ5map

Nefliqus

Prince
Joined
Sep 16, 2010
Messages
400
Location
Poland
If someone want to move starting location on civ5map or change starting location in existing game this script could be usefull. I have used it to setup PBEM game on civ5map.
Just include it to InGame.lua.

Code:
print("____________________________________________________________________________________");
print(">>> This is start of the 'makePBEMmap' script v1.");

include("MapGenerator");
include("MapmakerUtilities");

-------------------------------------------------------------------
--Starting positions tables:
-------------------------------------------------------------------

----plr
local PlrStartPosTbl ={
--1
{sPlrName = "Kasimirus",
iCivID = GameInfoTypes.CIVILIZATION_CARTHAGE,
iX = 16,
iY = 18,
iMoveSeqPosition = 2,},
--2
{sPlrName = "Bombel",
iCivID = GameInfoTypes.CIVILIZATION_SIAM,
iX = 39,
iY = 31,
iMoveSeqPosition = 6,},
--3
{sPlrName = "Gadek",
iCivID = GameInfoTypes.CIVILIZATION_IROQUOIS,
iX = 34,
iY = 45,
iMoveSeqPosition = 1,},
--4
{sPlrName = "Krasny",
iCivID = GameInfoTypes.CIVILIZATION_AZTEC,
iX = 24,
iY = 36,
iMoveSeqPosition = 7,},
--5
{sPlrName = "Piteroter",
iCivID = GameInfoTypes.CIVILIZATION_PERSIA,
iX = 61,
iY = 19,
iMoveSeqPosition = 5,},
--6
{sPlrName = "Delpietro",
iCivID = GameInfoTypes.CIVILIZATION_GREECE,
iX = 71,
iY = 33,
iMoveSeqPosition = 10,},
--7
{sPlrName = "Domel",
iCivID = GameInfoTypes.CIVILIZATION_CELTS,
iX = 31,
iY = 15,
iMoveSeqPosition = 7,},
--8
{sPlrName = "Itkovian",
iCivID = GameInfoTypes.CIVILIZATION_CHINA,
iX = 59,
iY = 39,
iMoveSeqPosition = 4,},
--9
{sPlrName = "Cholernik",
iCivID = GameInfoTypes.CIVILIZATION_FRANCE,
iX = 49,
iY = 46,
iMoveSeqPosition = 9,},
--10
{sPlrName = "Forever",
iCivID = GameInfoTypes.CIVILIZATION_GERMANY,
iX = 47,
iY = 16,
iMoveSeqPosition = 3,},
};

----CS
local CSStartPosTbl ={
cs22 = {sCSname= "none1",iX = 27,iY = 26,},
cs23 = {sCSname= "none2",iX = 43,iY = 23,},
cs24 = {sCSname= "none3",iX = 34,iY = 21,},
cs25 = {sCSname= "none4",iX = 52,iY = 33,},
cs26 = {sCSname= "none5",iX = 69,iY = 43,},
cs27 = {sCSname= "none6",iX = 16,iY = 29,},
cs28 = {sCSname= "none7",iX = 22,iY = 51,},
cs29 = {sCSname= "none8",iX = 6,iY = 52,},
cs30 = {sCSname= "none9",iX = 11,iY = 44,},
cs31 = {sCSname= "none10",iX = 0,iY = 41,},
--10
cs32 = {sCSname= "none11",iX = 4,iY = 12,},
cs33 = {sCSname= "none12",iX = 3,iY = 21,},
cs34 = {sCSname= "none13",iX = 70,iY = 53,},
cs35 = {sCSname= "none14",iX = 89,iY = 23,},
cs36 = {sCSname= "none15",iX = 82,iY = 14,},
cs37 = {sCSname= "none16",iX = 72,iY = 17,},
cs38 = {sCSname= "none17",iX = 76,iY = 27,},
cs39 = {sCSname= "none18",iX = 80,iY = 40,},
cs40 = {sCSname= "none19",iX = 86,iY = 37,},
cs41 = {sCSname= "none20",iX = 53,iY = 55,},
--20
cs42 = {sCSname= "none21",iX = -1,iY = -1,},
cs43 = {sCSname= "none22",iX = -1,iY = -1,},
};

local PlrHandiC = "HANDICAP_PRINCE";

------------------------------------------------------------------
------------------------------------------------------------------
function isValidPlayer(pPlayer)
	return  pPlayer ~= nil and pPlayer:GetStartingPlot() ~= nil and pPlayer:IsAlive();
end
---------------------------------------
function AddPBEMcsArmy()
	print(">>> AddPBEMcsArmy(): adding cs army.");
	--add CS army
	local iW, iH = Map.GetGridSize();
	local embarkID = GameInfoTypes.PROMOTION_EMBARKATION;
	local accuracyID = GameInfoTypes.PROMOTION_ACCURACY_1;
	local barrageID = GameInfoTypes.PROMOTION_BARRAGE_1;
	local marchID = GameInfoTypes.PROMOTION_MARCH;
	local logisticsID = GameInfoTypes.PROMOTION_LOGISTICS;
	local shockID = GameInfoTypes.PROMOTION_SHOCK_1;
	local blitzID = GameInfoTypes.PROMOTION_BLITZ;
	local moveID = GameInfoTypes.PROMOTION_EXTRA_MOVES_I;
	----
	
	for player_ID = GameDefines.MAX_MAJOR_CIVS, GameDefines.MAX_MAJOR_CIVS + GameDefines.MAX_MINOR_CIVS - 1  do
		local pPlayer = Players[player_ID];
		if isValidPlayer(pPlayer) then
			local iCivType = pPlayer:GetCivilizationType(); 
			print(">>>",pPlayer:GetCivilizationShortDescription(),player_ID," adding units...");
			local playerStartPlot = pPlayer:GetStartingPlot();
			local plotX = playerStartPlot:GetX();
			local plotY = playerStartPlot:GetY();
			----
			local unitID = GameInfoTypes.UNIT_SETTLER;
			local unit01 = pPlayer:InitUnit( unitID, plotX, plotY, UNITAI_SETTLE, NO_DIRECTION); --add unit 
			----
			unitID = GameInfoTypes.UNIT_WORKER;
			local unit02 = pPlayer:InitUnit( unitID, plotX, plotY, UNITAI_WORKER, NO_DIRECTION); --add unit 
			unit02:JumpToNearestValidPlot();
			unit02:SetHasPromotion(embarkID, true); --embark
			----
			unitID = GameInfoTypes.UNIT_COMPOSITE_BOWMAN;
			local unit1 = pPlayer:InitUnit( unitID, plotX, plotY, UNITAI_RANGED, NO_DIRECTION); --add unit 
			unit1:SetHasPromotion(embarkID, true); --embark
			unit1:SetHasPromotion(accuracyID, true); --Acurency I
			unit1:SetHasPromotion(barrageID, true); --Barrage I
			unit1:SetHasPromotion(marchID, true); --march
			unit1:SetHasPromotion(ogisticsID, true); --logistic
			----
			unitID = GameInfoTypes.UNIT_GREEK_HOPLITE;
			local unit2 = pPlayer:InitUnit( unitID, plotX, plotY, UNITAI_DEFENCE, NO_DIRECTION); --add unit 
			unit2:JumpToNearestValidPlot();
			unit2:SetHasPromotion(embarkID, true); --embark
			unit2:SetHasPromotion(shockID, true); --shock I
			unit2:SetHasPromotion(marchID, true); --march
			----
			unitID = GameInfoTypes.UNIT_CARTHAGINIAN_FOREST_ELEPHANT;
			local unit3 = pPlayer:InitUnit( unitID, plotX, plotY, UNITAI_COUNTERATTACK, NO_DIRECTION); --add unit 
			unit3:JumpToNearestValidPlot();
			unit3:SetHasPromotion(embarkID, true); --embark
			unit3:SetHasPromotion(shockID, true); --shock I
			unit3:SetHasPromotion(marchID, true); --march
			unit3:SetHasPromotion(blitzID, true); --bliz
			unit3:SetHasPromotion(moveID, true); -- +1 move
			----
		end
	end
	print(">>> End.");
	print("");
	return true
end
-----------------------------------------------
function ClearPBEMmap()
	print(">>> ClearPBEMmap(): start.");
	for player_ID = 0, GameDefines.MAX_MAJOR_CIVS + GameDefines.MAX_MINOR_CIVS - 1   do
		local pPlayer = Players[player_ID];
		if isValidPlayer(pPlayer) then
			local t_pPlayerPlots = {};
			local iTeam = pPlayer:GetTeam()
			-- Find all of Player1's plots
			if (player_ID <= (GameDefines.MAX_MAJOR_CIVS - 1)) then
				for iPlotLoop = 0, Map.GetNumPlots()-1, 1 do
				  local pPlot = Map.GetPlotByIndex(iPlotLoop)
				  if (pPlot:GetVisibilityCount(iTeam) > 0) then
					table.insert(t_pPlayerPlots, pPlot)
				  end
				end
			end
			----
			for u in pPlayer:Units() do
				u:Kill();
			end
			----
			if (player_ID <= (GameDefines.MAX_MAJOR_CIVS - 1)) then
				-- Fog out the original Player starting position
				for iPlotLoop = 1, #t_pPlayerPlots, 1 do
				  local pPlot = t_pPlayerPlots[iPlotLoop]
				  pPlot:SetRevealed(iTeam, false)
				  pPlot:UpdateFog()
				end
			end
		end
	end
	Map.UpdateDeferredFog();
	print(">>> End.");
	print("");
	return true
end
-----------------------------------------------
function AddPBEMplrArmy()
	print(">>> AddPBEMplrArmy(): adding players army.");
	for player_ID = 0, GameDefines.MAX_MAJOR_CIVS - 1  do
		local pPlayer = Players[player_ID];
		if isValidPlayer(pPlayer) then
			pPlayer:AddFreeUnit(82);--zwiadowca
			pPlayer:AddFreeUnit(83);--wojownik
			pPlayer:AddFreeUnit(83);--dodatkowy wojownik
			pPlayer:AddFreeUnit(1);--robol
			pPlayer:AddFreeUnit(0);--osadnik
			pPlayer:AddFreeUnit(0);--dodatkowy osadnik
		end
	end
	Map.UpdateDeferredFog();
	print(">>> End.");
	print("");
	return true
end
-----------------------------------------------
function PBEMaddBarbNave()
	print(">>> PBEMaddBarbNave(): start.");
	if (Game.IsOption(GameOptionTypes.GAMEOPTION_NO_BARBARIANS)) then
		print(">>> Barbs are off.");
		return false;
	end
	
	local moraleID = GameInfoTypes.PROMOTION_MORALE;
	local grelighID = GameInfoTypes.PROMOTION_GREAT_LIGHTHOUSE;
	local bordID = GameInfoTypes.PROMOTION_BOARDING_PARTY_1;
	local mafterID = GameInfoTypes.PROMOTION_CAN_MOVE_AFTER_ATTACKING;
	local oceanimpasID = GameInfoTypes.PROMOTION_OCEAN_IMPASSABLE;
	local oceanmovesID = GameInfoTypes.PROMOTION_OCEAN_MOVEMENT;
	local BarbGalleyID = GameInfoTypes.UNIT_GALLEY;
	local iceID = GameInfoTypes.FEATURE_ICE;
	local plotX = nil;
	local plotY = nil;
	local barbplayer = Players[63];
	local iW, iH = Map.GetGridSize();
	
	for player_ID = 0, GameDefines.MAX_MAJOR_CIVS + GameDefines.MAX_MINOR_CIVS - 1 do
		local pPlayer = Players[player_ID];
		if isValidPlayer(pPlayer) then
			local playerStartPlot = pPlayer:GetStartingPlot();
			plotX = playerStartPlot:GetX();
			plotY = playerStartPlot:GetY();
			local isDone = false;
			for ix = -10, 10 do 
				for iy = -10, 10 do
					----
					if ix <= 0 then
						ix = -10 - ix; 
					end
					----
					if iy <= 0 then
						iy = -10 - iy; 
					end
					
					local newX = plotX + ix;
					local newY = plotY + iy;
					if (newX > 1 and newX < iW - 2 and newY > 1 and newY < iH -2 ) then --map edge
						local newPlot = Map.GetPlot(newX, newY);
						if ( newPlot:IsWater() ) then
							local featureType = newPlot:GetFeatureType();
							if (featureType ~= iceID) then --no ice
								if (isDone == false) then
									isDone = true;
									plotX = newX;
									plotY = newY;
									print(">>> New barb's plot at ",newX,newY," ix/iy=",ix,iy);
								end 
							end
						end
					end	
				end
			end
			
			local barbsQty = 3;
			for n = 1, barbsQty do
				local bunit = barbplayer:InitUnit( BarbGalleyID, plotX, plotY, UNITAI_ATTACK_SEA, NO_DIRECTION); -- add NAVE barb unit
				print(">>> Barb galley for ",pPlayer:GetName(),n," added at ",plotX, plotY);
				bunit:SetHasPromotion(moraleID, true); --morale
				bunit:SetHasPromotion(grelighID, true); --extra move GLighth
				bunit:SetHasPromotion(bordID, true); --bording party I
				bunit:SetHasPromotion(mafterID, true); --move after atack
				bunit:SetHasPromotion(oceanimpasID, false);
				bunit:SetHasPromotion(oceanmovesID, true);
				bunit:JumpToNearestValidPlot();
			end
			print(">>> ----");
		end	
	end
	
	print(">>> End.");
	print("");
	return true
end
-----------------------------------------------
function PBEMmoveCSStartPos()

	----cs
	print(">>> PBEMmoveCSStartPos(): start changing CS's start locations.");
	for player_ID = GameDefines.MAX_MAJOR_CIVS, GameDefines.MAX_MAJOR_CIVS + GameDefines.MAX_MINOR_CIVS - 1 do
		local pPlayer = Players[player_ID];
		if isValidPlayer(pPlayer) then
			local iCivType = pPlayer:GetCivilizationType(); 
			print(">>>",pPlayer:GetCivilizationShortDescription()," iCivType =",iCivType);
			local iTargetX = nil;
			local iTargetY = nil;
			local i = "cs" .. player_ID;
			print(">>> ", i);
			local v = CSStartPosTbl[i];
			iTargetX = v["iX"];
			iTargetY = v["iY"];
			local iW, iH = Map.GetGridSize();
			if (iTargetX < 0 or iTargetX > (iW - 1)) then
				print(">>> Err: X out of range !!!");
				return false
			end
			if (iTargetY < 0 or iTargetY > (iH - 1)) then
				print(">>> Err: Y out of range !!!");
				return false
			end
			if (iTargetX ~= nil and iTargetX ~= nil) then
				local pPlot = Map.GetPlot(iTargetX, iTargetY);
				pPlayer:SetStartingPlot(pPlot);
				print(">>> New starting position:",iTargetX, iTargetY);
			else
				print(">>> Err: X or Y = nil !!!");
				return false
			end
			----
			
			print(">>> ----");
		end
	end
	print(">>> End.");
	print("");
	return true
end
-----------------------------------------------------------------------
function PBEMmovePlrStartPos()
	----plr
	print(">>> PBEMmovePlrStartPos(): start changing plr's start locations.");
	local iW, iH = Map.GetGridSize();
	local iTargetX = nil;
	local iTargetY = nil;
	local sTragetName = nil;
	for player_ID = 0, GameDefines.MAX_MAJOR_CIVS - 1 do
		local pPlayer = Players[player_ID];
		if isValidPlayer(pPlayer) then
			local iCivType = pPlayer:GetCivilizationType(); 
			print(">>>",pPlayer:GetCivilizationShortDescription()," iCivType =",iCivType);
			----
			for k = 1, #PlrStartPosTbl do	
				local v = PlrStartPosTbl[k];
				local iCivID = v["iCivID"];
				if iCivID == iCivType then
					sTragetPlrName = "Player";
					sTragetPlrName = v["sPlrName"];
					print(">>> ",sTragetPlrName, "iCivID =",iCivID);
					iTargetX = v["iX"];
					iTargetY = v["iY"];
					----
					if (iTargetX < 0 or iTargetX > (iW - 1)) then
						print(">>> Err: X out of range !!!");
						return false
					end
					if (iTargetY < 0 or iTargetY > (iH - 1)) then
						print(">>> Err: Y out of range !!!");
						return false
					end
				end
			end
			----
			if (iTargetX ~= nil and iTargetX ~= nil) then
				local pPlot = Map.GetPlot(iTargetX, iTargetY);
				pPlayer:SetStartingPlot(pPlot);
				print(">>> New starting position:",iTargetX, iTargetY);
			else
				print(">>> Err: X or Y = nil !!!");
				return false
			end
			----name change
			PreGame.SetNickName(player_ID, sTragetPlrName);
			local sNewTragetPlrName = "Donut" .. tostring(sTragetPlrName);
			PreGame.SetLeaderName( player_ID, sNewTragetPlrName);
			
			print("----");
		end -- ifvalid end
	end -- for end
	print(">>> End.");
	print("");
	return true
end
---------------------------------------------------------------------
function deepcopy(object)
    local lookup_table = {}
    local function _copy(object)
        if type(object) ~= "table" then
            return object
        elseif lookup_table[object] then
            return lookup_table[object]
        end
        local new_table = {}
        lookup_table[object] = new_table
        for index, value in pairs(object) do
            new_table[_copy(index)] = _copy(value)
        end
        return setmetatable(new_table, getmetatable(object))
    end
    return _copy(object)
end
---------------------------------------------------------------------
function PBEMprintPlrTbl()
	print("==============plr tbl===============");
	for player_ID = 0, GameDefines.MAX_MAJOR_CIVS + GameDefines.MAX_MINOR_CIVS - 1 do
		local pPlayer = Players[player_ID];
		if isValidPlayer(pPlayer) then
			local playerStartPlot = pPlayer:GetStartingPlot();
			local plotX = playerStartPlot:GetX();
			local plotY = playerStartPlot:GetX();
			print("	player_ID:	",player_ID,"	Name:",pPlayer:GetName(),"		biCivType2:",pPlayer:GetCivilizationType(),"	Nick:	",pPlayer:GetNickName(),"	start x/y=	",plotX,plotY);
		end
	end
	print("====================================");
end
---------------------------------------------------------------------
function PBEMChangeMoveSeqPos()
	print("");
	print(">>> PBEMChangeMoveSeqPos(): start");
	PBEMprintPlrTbl();
	for player_ID = 0, GameDefines.MAX_MAJOR_CIVS - 1 do
		local pPlayer = Players[player_ID];
		if isValidPlayer(pPlayer) then
			print(">>> Processing player: ",player_ID,pPlayer:GetName())
			local iCivID = nil;
			local iCivType = nil;
			for k = 1, #PlrStartPosTbl do	
				local v = PlrStartPosTbl[k];
				local iMoveSeqPosition = v["iMoveSeqPosition"];
				iMoveSeqPosition = iMoveSeqPosition -1;
				if iMoveSeqPosition == player_ID then
					iCivID = v["iCivID"];
					iCivType = pPlayer:GetCivilizationType(); 
					print(">>> ",v["sPlrName"],"iCivID,iCivType=",iCivID,iCivType);
				end
			end
			--loop2
			local isDone = false
			for player2_ID = 0, GameDefines.MAX_MAJOR_CIVS - 1 do
				local pPlayer2 = Players[player2_ID];
				if isValidPlayer(pPlayer2) then
					local iCivType2 = pPlayer2:GetCivilizationType(); 
					print("test2",player2_ID,iCivType2 == iCivID,iCivType2, iCivID,isDone);
					if (iCivType2 == iCivID and isDone == false) then
						if iCivType ~= iCivID then
							local leaderType1 = PreGame.GetLeaderType(player_ID);
							local leaderType2 = PreGame.GetLeaderType(player2_ID);
							local color1 = pPlayer:GetPlayerColor();
							local color2 = pPlayer2:GetPlayerColor();
							PreGame.SetPlayerColor(player_ID,color2);
							PreGame.SetPlayerColor(player2_ID,color1);
							PreGame.SetCivilization( player_ID, iCivID);
							PreGame.SetCivilization( player2_ID, iCivType);
							PreGame.SetLeaderType(player_ID,leaderType2);
							PreGame.SetLeaderType(player2_ID,leaderType1);
							local handicap = GameInfo.HandicapInfos[PlrHandiC];
							PreGame.SetHandicap( player_ID, handicap.ID );
							PreGame.SetHandicap( player2_ID, handicap.ID );
							print(">>> Civ types changed for plr1 ID",player_ID," new CivID=",iCivID);
							print(">>> Civ types changed for plr2 ID",player2_ID," new CivID=",iCivType);
							isDone = true;
						else
							print(">>> It is OK, iCivType == iCivID.");
							isDone = true;
						end
					end
				end
			end
			print(">>> ----");
			if isDone == false then
				print(">>> Err: No valid civ on list !!!");
				return false
			end
		end
	end
	PBEMprintPlrTbl()
	print(">>> End.");
	print("");
	return true
end
---------------------------------------------------------------------
function isMap()
	print(">>> Map name: ", PreGame.GetMapScript());
	return Path.UsesExtension(PreGame.GetMapScript(),".Civ5Map")
end
---------------------------------------------------------------------
function IsInitialised()
  local savedData = Modding.OpenSaveData()
  local sKey = "166f91ed-2546-45ee-a03a-d63b9a75132b_Initialised";

  local bInitialised = (savedData.GetValue(sKey) ~= nil)

  if (not bInitialised) then
    savedData.SetValue(sKey, 1)
  end

  return bInitialised
end
------------------------------------------------------------------
function IsNotInitialised()
  return not IsInitialised()
end
------------------------------------------------------------------
----StartPBEMmapChange
------------------------------------------------------------------
function StartPBEMmapChange()
	if (isMap()) then
		print(">>> StartPBEMmapChange(): start changing map.");
		local step1 = PBEMChangeMoveSeqPos();
		local step2 = ClearPBEMmap();
		local step3 = PBEMmovePlrStartPos();
		local step4 = PBEMmoveCSStartPos();
		local step5 = PBEMaddBarbNave();
		local step6 = AddPBEMplrArmy();
		local step7 = AddPBEMcsArmy();
		PBEMprintPlrTbl();
		print("step1=",step1);
		print("step2=",step2);
		print("step3=",step3);
		print("step4=",step4);
		print("step5=",step5);
		print("step6=",step6);
		print("step7=",step7);
		Map:RecalculateAreas();
		if (step1 and step2 and step3 and step4 and step5 and step6 and step7) then
			player = Players[0];
			player:AddNotification(NotificationTypes.NOTIFICATION_GENERIC, "Map is ok." , "Map is ok.");
		end
	else
		print(">>> StartPBEMmapChange(): err: is not a Civ5Map.");
	end
end

------------------------------------------------------------------
----Initiate
------------------------------------------------------------------
-- This gets called after the map has been generated and the units placed by the core code
-- but *before* the load screen dialog (the one with the partial map in the background)
-- has been displayed - effectively it's an OnGameStart() event!

if (IsNotInitialised() and Game.GetGameTurn() == 0) then StartPBEMmapChange() end

print(">>> This is end of the 'makePBEMmap' script.");
print("____________________________________________________________________________________");
 
Back
Top Bottom