bane_
Howardianism High-Priest
- Joined
- Nov 27, 2013
- Messages
- 1,559
I'm having a major headache from trying to make the AI build a damn Improvement in foreign lands.
It is a major pain in the ass to get out of the game each 10 minutes to re-build the mod, wait for the game to load again, then build the world, start it all, alt+tab to start firetuner, wait until error, rinse & repeat.
I decided so, to ask the more experienced modders for advice. Anything really. The latest wall I found to bang my head against was that the mission MoveTo is cancelled if there is an unit in the plot, even if I can move into that plot (no Civillian Traffic Jam) and even if it is invisible. So, I order the unit to go there, and it never completes the mission, because the plot is more than 2-3 turns away and the tile owner will move someone there eventually.
I'm trying a new workaround, but it consists on repeating the order for one single unit, which kind of sucks, making it only possible for the AI to build on at a time. :\
I'll put the relevant code here in the off chance someone with more patience than I have right now will read it and comment on it:
-AIHelper.lua
-DomotaiUtils.lua
It is a major pain in the ass to get out of the game each 10 minutes to re-build the mod, wait for the game to load again, then build the world, start it all, alt+tab to start firetuner, wait until error, rinse & repeat.
I decided so, to ask the more experienced modders for advice. Anything really. The latest wall I found to bang my head against was that the mission MoveTo is cancelled if there is an unit in the plot, even if I can move into that plot (no Civillian Traffic Jam) and even if it is invisible. So, I order the unit to go there, and it never completes the mission, because the plot is more than 2-3 turns away and the tile owner will move someone there eventually.
I'm trying a new workaround, but it consists on repeating the order for one single unit, which kind of sucks, making it only possible for the AI to build on at a time. :\
I'll put the relevant code here in the off chance someone with more patience than I have right now will read it and comment on it:
-AIHelper.lua
Spoiler :
Code:
include("DomotaiUtils.lua")
iUnitIDBuilder = 0
pTargettedPlot = 0
bBuildingGarden = true
local ArtisanBuildingCheck = 0
local bCraneAvWorkers = false
local usedCitiesCrane = {}
--local CraneAvWorkers = {}
--local CraneAvWorkersUsed = {}
--[[function IsWorkerUsed(iCraneWorker)
if CraneAvWorkersUsed then
for _, v in pairs(CraneAvWorkersUsed) do
if iCraneWorker == v then
return true
end
end
end
return false
end]]
function CraneCheckCityValidity(pCity)
for _, v in pairs(usedCitiesCrane) do
if v == pCity:GetID() then
print("CraneCheckCityValidity: Found city in the table.")
return false
end
end
print("CraneCheckCityValidity: City absent from the table.")
return true
end
[B]function FindWorkerCrane(iPlayer, iOtPlayer)
local pPlayer = Players[iPlayer]
for pUnit in pPlayer:Units() do
if (pUnit:GetUnitType() == GameInfoTypes["UNIT_KAKITA_ARTISAN"] or pUnit:GetUnitType() == GameInfoTypes["UNIT_WORKER"]) and pUnit:GetPlot():GetOwner() == iPlayer and not pUnit:IsHasPromotion(GameInfoTypes["PROMOTION_SELECTED_WORKER"]) then
if pUnit:GetUnitType() == GameInfoTypes["UNIT_KAKITA_ARTISAN"] then
if pPlayer:IsPlayerHasOpenBorders(iOtPlayer) then
pUnit:SetHasPromotion(GameInfoTypes["PROMOTION_SELECTED_WORKER"], true)
local iUnit = pUnit:GetID()
return iUnit
else
return nil
end
else
pUnit:SetHasPromotion(GameInfoTypes["PROMOTION_SELECTED_WORKER"], true)
local iUnit = pUnit:GetID()
return iUnit
end
end
end
return nil
end
function CraneAIHelpUI(iPlayer)
local pPlayer = Players[iPlayer]
if pPlayer:GetCivilizationType() == GameInfoTypes["CIVILIZATION_CRANE_CLAN"] and not pPlayer:IsHuman() then
if not pPlayer:HasTech(GameInfoTypes["TECH_PHILOSOPHY"]) then
print("Doesn't know Philosophy yet.")
return
end
local iNumFriends = GetNumberCraneFriends(iPlayer)
if iNumFriends == 0 then
print("iNumFriends = 0")
return
end
local iNumTreshold = math.ceil(iNumFriends + ((Game.GetNumCivCities() / CraneCountCivPlayersAlive()) * 1.75))
if iNumFantasticGardensAI ~= nil then
if iNumFantasticGardensAI >= iNumTreshold then
print("Number of Fantastic Gardens is already higher than the treshold.")
return
end
else
print("iNumFantasticGardensAI == nil")
end
if bBuildingGarden then
LookForSuitableGardens(iUnitIDBuilder, pTargettedPlot, true)
else
for i = 0, GameDefines.MAX_MAJOR_CIVS - 1, 1 do
print("Checking now if anyone is friend with the Crane.")
if Players[i]:IsDoF(iPlayer) then
for pCity in Players[i]:Cities() do
local iCraneWorker = FindWorkerCrane(iPlayer, i)
if iCraneWorker == nil then
return
end
local pUnit = pPlayer:GetUnitByID(iCraneWorker)
local pPlot = Map.GetPlot(pCity:GetX(), pCity:GetY())
print("Looking for suitable place for a garden.")
LookForSuitableGardens(iUnit, pPlot, true)
end
end
end
end
end
end[/B]
[...]
GameEvents.GetScenarioDiploModifier1.Add(function(iPlayer1, iPlayer2) --From ViceVirtuoso's Fate Zero.
local pPlayer1 = Players[iPlayer1]
local pPlayer2 = Players[iPlayer2]
if pPlayer1:GetCivilizationType() == GameInfoTypes["CIVILIZATION_CRANE_CLAN"] and not pPlayer1:IsHuman() then
return -30
elseif pPlayer2:GetCivilizationType() == GameInfoTypes["CIVILIZATION_CRANE_CLAN"] and not pPlayer2:IsHuman() then
return -30
else
return 0
end
end)
GameEvents.PlayerBuilt.Add(
function(iPlayer, iUnit, iX, iY, iBuild)
local pPlayer = Players[iPlayer]
if iBuild == GameInfoTypes["BUILD_FANTASTIC_GARDENS"] then
gT.iNumFantasticGardensAI = gT.iNumFantasticGardensAI + 1
print("Garden built.")
end
if not pPlayer:IsHuman() then
local pUnit = pPlayer:GetUnitByID(iUnit)
if pUnit:IsHasPromotion(GameInfoTypes["PROMOTION_SELECTED_WORKER"]) then
pUnit:SetHasPromotion(GameInfoTypes["PROMOTION_SELECTED_WORKER"], false)
end
end
end)
GameEvents.PlayerDoTurn.Add(CraneAIHelpArtisanBuilding)
GameEvents.PlayerDoTurn.Add(CraneAIHelpUI)
-DomotaiUtils.lua
Spoiler :
Code:
iCraneClan = 0
function GetCranePlayer()
for i = 0, GameDefines.MAX_MAJOR_CIVS - 1, 1 do
Players[i]:SetNumFreePolicies(1)
Players[i]:SetNumFreePolicies(0)
if Players[i]:GetCivilizationType() == GameInfoTypes["CIVILIZATION_CRANE_CLAN"] then
iCraneClan = i
print("Crane Clan ID: " ..iCraneClan)
end
end
end
function GetRandom(iMin, iMax)
return Map.Rand((iMax + 1) - iMin, "") + iMin
end
function tablerandom(tbl)
local keys = {}
for k in pairs(tbl) do
table.insert(keys, k)
end
local randIndex = math.random(#keys)
local randKey = keys[randIndex]
return tbl[randKey]
end
function LookForSuitableGardens(iUnit, pPlot, bAppend)
local iPlotOwner = pPlot:GetOwner()
local pUnit = Players[iCraneClan]:GetUnitByID(iUnit)
for idX = -2, 2, 1 do
for idY = -2, 2, 1 do
local pTargetPlot = Map.PlotXYWithRangeCheck(pPlot:GetX(), pPlot:GetY(), idX, idY, 2)
if pTargetPlot and pTargetPlot:GetOwner() == iPlotOwner and pTargetPlot:CanHaveImprovement(GameInfoTypes["IMPROVEMENT_FANTASTIC_GARDENS"], NO_TEAM) then
local buildType = GameInfoTypes["BUILD_FANTASTIC_GARDENS"]
if bAppend then
pUnit:PushMission(MissionTypes.MISSION_MOVE_TO, pTargetPlot:GetX(), pTargetPlot:GetY(), 0, 1, 1, MissionTypes.MISSION_MOVE_TO, pUnit:GetPlot(), pUnit)
pUnit:PushMission(MissionTypes.MISSION_BUILD, buildType, -1, 0, 1, 1, MissionTypes.MISSION_BUILD, pPlot, pUnit)
print("Found a good place")
else
pUnit:PushMission(MissionTypes.MISSION_BUILD, buildType, -1, 0, 0, 1, MissionTypes.MISSION_BUILD, pPlot, pUnit)
print("Found a good place")
end
return
end
end
end
end
function GetNumberCraneFriends(iCraneClan)
local iNumFriendsAI = 0
for i = 0, GameDefines.MAX_MAJOR_CIVS - 1, 1 do
local pOtPlayer = Players[i]
if pOtPlayer:IsDoF(iCraneClan) then
iNumFriendsAI = iNumFriendsAI + 1
print("GetNumberCraneFriends: Found friend. iNumFriendsAI is now: " ..iNumFriendsAI)
end
end
if iNumFriendsAI >= 1 then
print("GetNumberCraneFriends: " ..iNumFriendsAI)
return iNumFriendsAI * 3
else
print("GetNumberCraneFriends: No friends.")
return 0
end
end
function MakeMedianCulturePerTurn()
local RawCultureOtherPlayers = 0
for i = 0, GameDefines.MAX_MAJOR_CIVS - 1, 1 do
if Players[i]:GetCivilizationType() ~= GameInfoTypes["CIVILIZATION_CRANE_CLAN"] then
RawCultureOtherPlayers = RawCultureOtherPlayers + (Players[i]:GetTotalJONSCulturePerTurn())
else
pCraneClan = Players[i]
end
end
print("Making Median Culture/turn.")
local iMedianCultureOtherPlayers = math.floor((RawCultureOtherPlayers / CraneCountCivPlayersAlive()) + ((RawCultureOtherPlayers / CraneCountCivPlayersAlive()) * 0.45))
local iCraneCulture = pCraneClan:GetTotalJONSCulturePerTurn()
print("iMedianCultureOtherPlayers (with the +45%): " ..iMedianCultureOtherPlayers.. ". iCraneCulture: " ..iCraneCulture)
if iMedianCultureOtherPlayers <= iCraneCulture then
print("Crane's Culture/turn is at least 145% of the median from other players.")
return true
else
print("Crane's Culture/turn is NOT enough.")
return false
end
end
function CraneCountCivPlayersAlive()
local CraneCountCivPlayersAlive = 0
for i = 0, GameDefines.MAX_MAJOR_CIVS - 1, 1 do
if Players[i]:IsAlive() then
CraneCountCivPlayersAlive = CraneCountCivPlayersAlive + 1
end
end
print("CraneCountCivPlayersAlive: " ..CraneCountCivPlayersAlive)
return CraneCountCivPlayersAlive
end