-- Colonies.lua
-- Author: Genghis.Khan
-- Special Thanks: FramedArchitecture, whoward69, Hambil, Irkalla, Gedemon, Putmalk, Machiavelli, LastSword
-- Version: 3.0
------------------------------------------------------------------------------------------------------------
---------------------------------------------- Global Variables --------------------------------------------
g_RevoltedColonies = {}
g_ColoniesRevolted1 = {}
g_ColoniesRevolted2 = {}
g_ColoniesRevolted3 = {}
g_ColoniesRevolted4 = {}
g_ColoniesRevolted5 = {}
g_Colonies = {}
g_BarbarianID = 63
---------------------------------------------- End Global Variables ----------------------------------------
function FoundColony()
for plotLoop = 0, Map.GetNumPlots() - 1, 1 do
local improvementType = plot:GetImprovementType()
if ( improvementType == GameInfoTypes["IMPROVEMENT_COLONY"] ) then
local iColonyPlotX = pPlot:GetX()
local iColonyPlotY = pPlot:GetY()
local pColonyPlot = Plot:At(iColonyPlotX, iColonyPlotY)
local pColonyOwner = pColonyPlot:GetOwner()
if not g_Colonies[pColonyPlot] then
table.insert(pColonyPlot, g_Colonies)
pColonyOwner:InitCity(iColonyPlotX, iColonyPlotY);
local pCity = City.At(iColonyPlotX, iColonyPlotY)
pCity:SetPuppet()
pCity:SetNumRealBuilding(GameInfoType["BUILDING_COLONY"], 1)
end
end
end
end
GameEvents.PlayerDoTurn.Add( FoundColony )
function GetEraModifiersForRevolt(iPlayer)
local pPlayerTeam = iPlayer:GetTeam()
local pTeamTechs = pPlayerTeam:GetTeamTechs()
if ( pPlayerTeam:GetCurrentEra() == GameInfoTypes["ERA_COLONIAL"] ) then
local iEraHappinessModifier = 0
return iEraHappinessModifier
elseif ( pPlayerTeam:GetCurrentEra() == GameInfoTypes["ERA_INDUSTRIAL"] ) then
local iEraHappinessModifier = 5
return iEraHappinessModifier
elseif ( pPlayerTeam:GetCurrentEra() == GameInfoTypes["ERA_MODERN"] ) then
local iEraHappinessModifier = 10
return iEraHappinessModifier
elseif ( pPlayerTeam:GetCurrentEra() == GameInfoTypes["ERA_POSTMODERN"] ) then
local iEraHappinessModifier = 15
return iEraHappinessModifier
elseif ( pPlayerTeam:GetCurrentEra() == GameInfoTypes["ERA_FUTURE"] ) then
local iEraHappinessModifier = 20
return iEraHappinessModifier
end
end
function PlayerGetNumColonies(iPlayer)
local pPlayer = iPlayer
local buildingID = GameInfoTypes["BUILDING_COLONY"]
local iNumColonies = 0
for pCity in pPlayer:Cities() do
if pCity:IsHasBuilding(buildingID) then
iNumColonies = iNumColonies + 1
end
end
end
function GetOwnerLocalUnitsPower(city)
for i = 0, city:GetNumCityPlots() -1 do
if city:GetCityIndexPlot(i) ~= nil then
local iPlot = city:GetCityIndexPlot(i);
local iCityOwner = city:GetOwner()
if Map.PlotDistance(iPlot:GetX(), iPlot:GetY(), city:GetX(), city:GetY()) < 3 then
local iUnitPower = iPlot:GetUnitPower(iCityOwner)
return iUnitPower
end
end
end
end
function CalculatePublicOrderForRevolt(city)
local pOnwer = city:GetOwner()
local pTeam = pOwner:GetTeam()
local pTeamTechs = pTeam:GetTeamTechs()
local iOwnerLocalPower = GetOwnerLocalUnitsPower(city)
if pTeamTechs:HasTech(GameInfoTypes["TECH_MOBILE_TACTICS"] then
return iOwnerLocalUnitsPower / 90
end
elseif pTeamTechs:HasTech(GameInfoTypes["TECH_PLASTICS"] then
return iOwnerLocalUnitsPower / 70
end
elseif pTeamTechs:HasTech(GameInfoTypes["TECH_REPLACEABLE_PARTS"] then
return iOwnerLocalUnitsPower / 50
end
elseif pTeamTechs:HasTech(GameInfoTypes["TECH_RIFLING"] then
return iOwnerLocalUnitsPower / 34
end
elseif pTeamTechs:HasTech(GameInfoTypes["TECH_FLINTLOCK"] then
return iOwnerLocalUnitsPower / 30
end
elseif pTeamTechs:HasTech(GameInfoTypes["TECH_CHEMISTRY"] then
return iOwnerLocalUnitsPower / 27
end
elseif pTeamTechs:HasTech(GameInfoTypes["TECH_GUNPOWDER"] then
return iOwnerLocalUnitsPower / 24
end
end
end
function GetRevoltedUnitsPower(iPlayer)
local pTeam = iPlayer:GetTeam()
local teamTechs = pTeam:GetTeamTechs()
if Game.GetHandicapType() == 0 then
if teamTechs:HasTech( GameInfo.Techs.TECH_MOBILE_TACTICS ) then
return 50
end
elseif teamTechs:HasTech( GameInfo.Techs.TECH_PLASTIC.ID ) then
return 34
end
elseif teamTechs:HasTech( GameInfo.Techs.TECH_REPLACEABLE_PARTS.ID )
return 24
elseif teamTechs:HasTech( GameInfo.Techs.TECH_RIFLING.ID ) then
return 16
elseif teamTechs:HasTech( GameInfo.Techs.TECH_GUNPOWDER.ID ) then
return 11
elseif Game.GetHandicapType() == 1 then
if teamTechs:HasTech( GameInfo.Techs.TECH_MOBILE_TACTICS ) then
return 70
end
elseif teamTechs:HasTech( GameInfo.Techs.TECH_PLASTIC.ID ) then
return 50
elseif teamTechs:HasTech( GameInfo.Techs.TECH_REPLACEABLE_PARTS.ID )
return 34
elseif teamTechs:HasTech( GameInfo.Techs.TECH_RIFLING.ID ) then
return 24
elseif teamTechs:HasTech( GameInfo.Techs.TECH_GUNPOWDER.ID ) then
return 16
elseif Game.GetHandicapType() == 2 then
if teamTechs:HasTech( GameInfo.Techs.TECH_MOBILE_TACTICS ) then
return 100
elseif teamTechs:HasTech( GameInfo.Techs.TECH_PLASTIC.ID ) then
return 68
elseif teamTechs:HasTech( GameInfo.Techs.TECH_REPLACEABLE_PARTS.ID )
return 48
elseif teamTechs:HasTech( GameInfo.Techs.TECH_RIFLING.ID ) then
return 32
elseif teamTechs:HasTech( GameInfo.Techs.TECH_GUNPOWDER.ID ) then
return 22
end
elseif Game.GetHandicapType() == 3 then
if teamTechs:HasTech( GameInfo.Techs.TECH_MOBILE_TACTICS ) then
return 140
end
elseif teamTechs:HasTech( GameInfo.Techs.TECH_PLASTIC.ID ) then
return 100
elseif teamTechs:HasTech( GameInfo.Techs.TECH_REPLACEABLE_PARTS.ID )
return 68
elseif teamTechs:HasTech( GameInfo.Techs.TECH_RIFLING.ID ) then
return 48
elseif teamTechs:HasTech( GameInfo.Techs.TECH_GUNPOWDER.ID ) then
return 32
elseif Game.GetHandicapType() == 4 then
if teamTechs:HasTech( GameInfo.Techs.TECH_MOBILE_TACTICS ) then
return 190
elseif teamTechs:HasTech( GameInfo.Techs.TECH_PLASTIC.ID ) then
return 134
elseif teamTechs:HasTech( GameInfo.Techs.TECH_REPLACEABLE_PARTS.ID )
return 92
elseif teamTechs:HasTech( GameInfo.Techs.TECH_RIFLING.ID ) then
return 62
elseif teamTechs:HasTech( GameInfo.Techs.TECH_GUNPOWDER.ID ) then
return 43
end
elseif Game.GetHandicapType() == 5 then
if teamTechs:HasTech( GameInfo.Techs.TECH_MOBILE_TACTICS ) then
return 250
end
elseif teamTechs:HasTech( GameInfo.Techs.TECH_PLASTIC.ID ) then
return 170
elseif teamTechs:HasTech( GameInfo.Techs.TECH_REPLACEABLE_PARTS.ID )
return 118
elseif teamTechs:HasTech( GameInfo.Techs.TECH_RIFLING.ID ) then
return 92
elseif teamTechs:HasTech( GameInfo.Techs.TECH_GUNPOWDER.ID ) then
return 64
elseif Game.GetHandicapType() == 6 then
if teamTechs:HasTech( GameInfo.Techs.TECH_MOBILE_TACTICS ) then
return 340
end
elseif teamTechs:HasTech( GameInfo.Techs.TECH_PLASTIC.ID ) then
return 240
elseif teamTechs:HasTech( GameInfo.Techs.TECH_REPLACEABLE_PARTS.ID )
return 168
elseif teamTechs:HasTech( GameInfo.Techs.TECH_RIFLING.ID ) then
return 116
elseif teamTechs:HasTech( GameInfo.Techs.TECH_GUNPOWDER.ID ) then
return 88
elseif Game.GetHandicapType() == 7 then
if teamTechs:HasTech( GameInfo.Techs.TECH_MOBILE_TACTICS ) then
return 430
elseif teamTechs:HasTech( GameInfo.Techs.TECH_PLASTIC.ID ) then
return 330
elseif teamTechs:HasTech( GameInfo.Techs.TECH_REPLACEABLE_PARTS.ID )
return 234
elseif teamTechs:HasTech( GameInfo.Techs.TECH_RIFLING.ID ) then
return 150
elseif teamTechs:HasTech( GameInfo.Techs.TECH_GUNPOWDER.ID ) then
return 106
end
end
function Shuffle(t) -- by Gedemon
local n = #t
while n >= 2 do
-- n is now the last pertinent index
local k = math.random(n) -- 1 <= k <= n
-- Quick swap
t[n], t[k] = t[k], t[n]
n = n - 1
end
return t
end
function RebelUnitsToSpawnSettler(iPlayer)
local pTeam = iPlayer:GetTeam()
local teamTechs = pTeam:GetTeamTechs()
if teamTechs:HasTech( GameInfo.Techs.TECH_MOBILE_TACTICS ) then
return GameInfo.Units.UNIT_GREAT_WAR_INFANTRY.ID
elseif teamTechs:HasTech( GameInfo.Techs.TECH_PLASTIC.ID ) then
return GameInfo.Units.UNIT_RIFLEMAN.ID
elseif teamTechs:HasTech( GameInfo.Techs.TECH_REPLACEABLE_PARTS.ID ) then
return GameInfo.Units.UNIT_MUSKETMAN.ID
elseif teamTechs:HasTech( GameInfo.Techs.TECH_RIFLING.ID ) then
return GameInfo.Units.UNIT_PIKEMAN.ID
elseif teamTechs:HasTech( GameInfo.Techs.TECH_GUNPOWDER.ID ) then
return GameInfo.Units.UNIT_SPEARMEN.ID
else
return GameInfo.Units.UNIT_WARRIOR.ID
end
end
function RebelUnitsToSpawnPrince(iPlayer)
local pTeam = iPlayer:GetTeam()
local teamTechs = pTeam:GetTeamTechs()
if teamTechs:HasTech( GameInfo.Techs.TECH_MOBILE_TACTICS ) then
return GameInfo.Units.UNIT_INFANTRY.ID
elseif teamTechs:HasTech( GameInfo.Techs.TECH_PLASTIC.ID ) then
return GameInfo.Units.UNIT_GREAT_WAR_INFANTRY.ID
elseif teamTechs:HasTech( GameInfo.Techs.TECH_REPLACEABLE_PARTS.ID ) then
return GameInfo.Units.UNIT_RIFLEMAN.ID
elseif teamTechs:HasTech( GameInfo.Techs.TECH_RIFLING.ID ) then
return GameInfo.Units.UNIT_MUSKETMAN.ID
elseif teamTechs:HasTech( GameInfo.Techs.TECH_GUNPOWDER.ID ) then
return GameInfo.Units.UNIT_PIKEMAN.ID
else
return GameInfo.Units.UNIT_SPEARMEN.ID
end
end
function RebelUnitsToSpawnEmperor(iPlayer)
local pTeam = iPlayer:GetTeam()
local teamTechs = pTeam:GetTeamTechs()
if teamTechs:HasTech( GameInfo.Techs.TECH_MOBILE_TACTICS ) then
return GameInfo.Units.UNIT_MECHANIZED_INFANTRY.ID
elseif teamTechs:HasTech( GameInfo.Techs.TECH_PLASTIC.ID ) then
return GameInfo.Units.UNIT_INFANTRY.ID
elseif teamTechs:HasTech( GameInfo.Techs.TECH_REPLACEABLE_PARTS.ID ) then
return GameInfo.Units.UNIT_GREAT_WAR_INFANTRY.ID
elseif teamTechs:HasTech( GameInfo.Techs.TECH_RIFLING.ID ) then
return GameInfo.Units.UNIT_RIFLEMAN.ID
elseif teamTechs:HasTech( GameInfo.Techs.TECH_GUNPOWDER.ID ) then
return GameInfo.Units.UNIT_MUSKETMAN.ID
else
return GameInfo.Units.UNIT_PIKEMAN.ID
end
end
function ColonyIsRevolted(city)
for i = 0, city:GetNumCityPlots() -1 do
if city:GetCityIndexPlot(i) ~= nil then
local iPlot = city:GetCityIndexPlot(i);
local iCityOwner = city:GetOwner()
if Map.PlotDistance(iPlot:GetX(), iPlot:GetY(), city:GetX(), city:GetY()) < 2 then
local iBarbUnitPower = iPlot:GetUnitPower(g_BarbarianID)
if iBarbUnitPower > 0 then
return 1
end
else
if g_RevoltedColonies[city] then
table.remove(city, g_RevoltedColonies)
table.insert(city, g_ColoniesRevolted1)
end
end
end
end
end
function GetNumColonyRevolts(city)
if not g_ColoniesRevolted1[city] and not g_ColoniesRevolted2[city] and not g_ColoniesRevolted3[city] and not g_ColoniesRevolted4[city] and not g_ColoniesRevolted5[city] then
return 0
elseif g_ColoniesRevolted1[city] then
return 1
elseif g_ColoniesRevolted2[city] then
return 2
elseif g_ColoniesRevolted3[city] then
return 3
elseif g_ColoniesRevolted4[city] then
return 4
elseif g_ColoniesRevolted5[city] then
return 5
end
end
function SpawnRevoltedUnits(city)
for i = 0, city:GetNumCityPlots() -1 do
if city:GetCityIndexPlot(i) ~= nil then
local iPlot = city:GetCityIndexPlot(i);
local iOwner = city:GetOwner()
if Map.PlotDistance(iPlot:GetX(), iPlot:GetY(), city:GetX(), city:GetY()) < 3 then
local plotNumUnits = plot:GetNumUnits()
if not (iPlot:IsWater()) and not (plotNumUnits > 3) and not iPlot:GetUnitPower(iOnwer) then
local freePlots = {}
table.insert(iPlot, freePlots)
Shuffle(freePlots)
for n, plot in pairs(freePlots) do
if Game.GetHandicapType() == 0 then
Player[g_BarbarianID]:InitUnit(freeUnitSettler, iPlot:GetX(), iPlot:GetY())
elseif Game.GetHandicapType() == 1 then
Player[g_BarbarianID]:InitUnit(freeUnitPrince, iPlot:GetX(), iPlot:GetY())
elseif Game.GetHandicapType() == 2 then
Player[g_BarbarianID]:InitUnit(freeUnitSettler, iPlot:GetX(), iPlot:GetY())
Player[g_BarbarianID]:InitUnit(freeUnitSettler, iPlot:GetX(), iPlot:GetY())
elseif Game.GetHandicapType() == 3 then
Player[g_BarbarianID]:InitUnit(freeUnitPrince, iPlot:GetX(), iPlot:GetY())
Player[g_BarbarianID]:InitUnit(freeUnitPrince, iPlot:GetX(), iPlot:GetY())
elseif Game.GetHandicapType() == 4 then
Player[g_BarbarianID]:InitUnit(freeUnitPrince, iPlot:GetX(), iPlot:GetY())
Player[g_BarbarianID]:InitUnit(freeUnitPrince, iPlot:GetX(), iPlot:GetY())
Player[g_BarbarianID]:InitUnit(freeUnitSettler, iPlot:GetX(), iPlot:GetY())
elseif Game.GetHandicapType() == 5 then
Player[g_BarbarianID]:InitUnit(freeUnitEmperor, iPlot:GetX(), iPlot:GetY())
Player[g_BarbarianID]:InitUnit(freeUnitEmperor, iPlot:GetX(), iPlot:GetY())
Player[g_BarbarianID]:InitUnit(freeUnitPrince, iPlot:GetX(), iPlot:GetY())
elseif Game.GetHandicapType() == 6 then
Player[g_BarbarianID]:InitUnit(freeUnitEmperor, iPlot:GetX(), iPlot:GetY())
Player[g_BarbarianID]:InitUnit(freeUnitEmperor, iPlot:GetX(), iPlot:GetY())
Player[g_BarbarianID]:InitUnit(freeUnitEmperor, iPlot:GetX(), iPlot:GetY())
Player[g_BarbarianID]:InitUnit(freeUnitPrince, iPlot:GetX(), iPlot:GetY())
elseif Game.GetHandicapType() == 7 then
Player[g_BarbarianID]:InitUnit(freeUnitEmperor, iPlot:GetX(), iPlot:GetY())
Player[g_BarbarianID]:InitUnit(freeUnitEmperor, iPlot:GetX(), iPlot:GetY())
Player[g_BarbarianID]:InitUnit(freeUnitEmperor, iPlot:GetX(), iPlot:GetY())
Player[g_BarbarianID]:InitUnit(freeUnitEmperor, iPlot:GetX(), iPlot:GetY())
Player[g_BarbarianID]:InitUnit(freeUnitPrince, iPlot:GetX(), iPlot:GetY())
end
end
end
end
end
end
end
function RevoltColony(iPlayer)
for plotLoop = 0, Map.GetNumPlots() - 1, 1 do
local improvementType = plot:GetImprovementType()
if ( improvementType == GameInfoTypes["IMPROVEMENT_COLONY"] ) then
local iColonyPlotX = pPlot:GetX()
local iColonyPlotY = pPlot:GetY()
local pColonyPlot = PlotAt:(iColonyPlotX, iColonyPlotY)
local iImprovementOwner = pColonyPlot:GetOwner()
local iEraModifier = GetEraModifiersForRevolt(iImprovementOwner) -- Colonial: 5; Industrial: 10; Modern: 15; Atomic: 20;
local pColonyCity = City:At(iColonyPlotX, iColonyPlotY)
local iHandicapRevoltModifier = (3 * Game:GetHandicapType()) -- Deity = 21; Prince = 12
local iNumColonies = PlayerGetNumColonies(iImprovementOwner)
local iNumColoniesModifier = (iNumColonies + 3) * iNumColonies) -- 4*1 = 4; 5*2= 10; 6*3= 18; 7*4= 28
local iColonyHappinessModifier = pColonyCity:GetLocalHappiness()
print(" .. iColonyHappinessModifier .. ")
local iPublicOrderPoints = CalculatePublicOrderForRevolt(pColonyCity)
print("PublicOrder is" ..iPublicOrderPoints.. "for the city of" ..iCityName .. "!")
local iCityName = pColonyCity:GetName()
local iOurUnitsPower = GetRevoltedUnitsPower(iImprovementOwner)
local iOurUnitsPowerConverted = (iOurUnitsPower * 1.75)
local iNumRevoltsModifier = GetNumColonyRevolts(pColonyCity) * 25 --2nd revolt required + 25 points
local iRevoltCounter = ((iHandicapRevoltModifier + iEraModifier + iNumColoniesModifier + iColonyHappinessModifier - iPublicOrderPoints - iNumRevoltsModifier)
if (math.random(0, 55) + iRevoltCounter) == 100 and not iOwnerLocalUnitsPower > iOurUnitsPowerConverted
if not g_RevoltedColonies[pColonyCity] then
SpawnRevoltedUnits(pColonyCity)
iImprovementOwner:AddNotification(NotificationTypes.NOTIFICATION_WONDER_COMPLETED_ACTIVE_PLAYER, .. iCityName .. ' has revolted! Rebel units will spawn near the revolted Colony and attemp to reclaim those lands! ')
table.insert(pColonyCity, g_RevoltedColonies)
if not g_ColoniesRevolted1[pColonyCity] and not g_ColoniesRevolted2[pColonyCity] and not g_ColoniesRevolted3[pColonyCity] and not g_ColoniesRevolted4[pColonyCity] and not g_ColoniesRevolted5[pColonyCity] then
table.insert(pColonyCity, g_ColoniesRevolted1)
elseif g_ColoniesRevolted1[pColonyCity] then
table.remove(pColonyCity, g_ColoniesRevolted1)
table.insert(pColonyCity, g_ColoniesRevolted2)
elseif g_ColoniesRevolted2[pColonyCity] then
table.remove(pColonyCity, g_ColoniesRevolted2)
table.insert(pColonyCity, g_ColoniesRevolted3)
elseif g_ColoniesRevolted3[pColonyCity] then
table.remove(pColonyCity, g_ColoniesRevolted3)
table.insert(pColonyCity, g_ColoniesRevolted4)
elseif g_ColoniesRevolted4[pColonyCity] then
table.remove(pColonyCity, g_ColoniesRevolted4)
table.insert(pColonyCity, g_ColoniesRevolted5)
end
end
end
end
end
end
GameEvents.PlayerDoTurn.Add( RevoltColony );