function damageAndDestroyUnit(pPlayer,iUnit,minDam,maxDam)
local tKillUnits = {}
local pPlayerToCheck = Players[pPlayer]
local pUnits = pPlayerToCheck:GetUnits()
for i, pUnit in pUnits:Members() do
if(tostring(pUnit:GetID()) == tostring(iUnit)) then
local unitDamage = math.random(minDam,maxDam)
if (pUnit:GetDamage() + unitDamage) >= 100 then
table.insert(tKillUnits, pUnit)
else
pUnit:ChangeDamage(unitDamage)
print("inflicted "..unitDamage.." to unit")
end
end
end
--now we've completed the iteration through table pUnits:Members() and can safely delete units listed as members
for k,pUnit in pairs(tKillUnits) do
pUnits:Destroy(pUnit)
print("a unit was destroyed because of attrition")
end
end
function Attrition(PlayerID,UnitID,UnitX,UnitY)
-- set base values for variables
local BaseAttritionMin,BaseAttritionMax = 1,6
local TerrainAttritionMul,CataChance,TerrainCataMul = 1,15,2
local experienceFromCata = false
local feedBack = false
-- give feedback only to player
if PlayerID == 0 then feedBack = true end
-- set values for terrains
local plotToCheck = Map.GetPlot(UnitX,UnitY)
local tTerrain = GameInfo.Terrains[plotToCheck:GetTerrainType()].TerrainType
print(tTerrain)
if tTerrain == "TERRAIN_DESERT" then
TerrainAttritionMul = 3
CataChance = 15
TerrainCataMul = 5
elseif tTerrain == "TERRAIN_DESERT_HILLS" then
TerrainAttritionMul = 3
CataChance = 25
TerrainCataMul = 5
elseif tTerrain == "TERRAIN_DESERT_MOUNTAIN" then
TerrainAttritionMul = 4
CataChance = 35
TerrainCataMul = 7
elseif tTerrain == "TERRAIN_GRASS_MOUNTAIN" then
TerrainAttritionMul = 3
CataChance = 35
TerrainCataMul = 5
elseif tTerrain == "TERRAIN_PLAINS_MOUNTAIN" then
TerrainAttritionMul = 3
CataChance = 35
TerrainCataMul = 5
elseif tTerrain == "TERRAIN_TUNDRA" then
TerrainAttritionMul = 2
CataChance = 15
TerrainCataMul = 3
elseif tTerrain == "TERRAIN_TUNDRA_HILLS" then
TerrainAttritionMul = 2
CataChance = 25
TerrainCataMul = 3
elseif tTerrain == "TERRAIN_TUNDRA_MOUNTAIN" then
TerrainAttritionMul = 2
CataChance = 45
TerrainCataMul = 7
elseif tTerrain == "TERRAIN_SNOW" then
TerrainAttritionMul = 3
CataChance = 20
TerrainCataMul = 4
elseif tTerrain == "TERRAIN_SNOW_HILLS" then
TerrainAttritionMul = 3
CataChance = 30
TerrainCataMul = 5
elseif tTerrain == "TERRAIN_SNOW_MOUNTAIN" then
TerrainAttritionMul = 3
CataChance = 60
TerrainCataMul = 8
elseif tTerrain == "TERRAIN_COAST" then
TerrainAttritionMul = 2
CataChance = 30
TerrainCataMul = 4
elseif tTerrain == "TERRAIN_OCEAN" then
TerrainAttritionMul = 2
CataChance = 50
TerrainCataMul = 5
end
-- check features. Takes precedence on terrain.
if plotToCheck:GetFeatureType() > -1 then
local plotFeature = GameInfo.Features[plotToCheck:GetFeatureType()].FeatureType
print(plotFeature)
if plotFeature == "FEATURE_ICE" then
TerrainAttritionMul = 3
CataChance = 60
TerrainCataMul = 6
end
if plotFeature == "FEATURE_JUNGLE" then
TerrainAttritionMul = 4
CataChance = 20
TerrainCataMul = 5
end
if plotFeature == "FEATURE_MARSH" then
TerrainAttritionMul = 3
CataChance = 30
TerrainCataMul = 5
end
if plotFeature == "FEATURE_OASIS" then
TerrainAttritionMul = 1
CataChance = 15
TerrainCataMul = 4
end
end
-- reduce attrition and cata chance if road on plot.
if plotToCheck:GetRouteType() > -1 then
print("There is a route here, so much less attrition.")
CataChance = CataChance/5
TerrainCataMul = 1
TerrainAttritionMul = 0.1
end
-- check cata chance
if math.random(1,100) <= CataChance then
experienceFromCata = true
TerrainAttritionMul = TerrainCataMul
if feedBack then
Game.AddWorldViewText(0, "A catastrophe happened to this unit while moving", UnitX, UnitY, 0)
end
end
-- deal damages
BaseAttritionMin = BaseAttritionMin*TerrainAttritionMul
BaseAttritionMax = BaseAttritionMax*TerrainAttritionMul
damageAndDestroyUnit(PlayerID,UnitID,BaseAttritionMin,BaseAttritionMax)
-- give XP if a cata happens.
if experienceFromCata then
local pPlayerToCheck = Players[PlayerID]
local pUnits = pPlayerToCheck:GetUnits()
for i, pUnit in pUnits:Members() do
if(tostring(pUnit:GetID()) == tostring(UnitID)) then
local currentXP = pUnit:GetExperience()
local currentXPPoints = currentXP:GetExperiencePoints()+5
--currentXPPoints = currentXPPoints+5
local experienceChangeAmount = math.random((BaseAttritionMin/10)+1,(BaseAttritionMax/10)+1)
currentXP:ChangeExperience(experienceChangeAmount)
end
end
end
end
Events.UnitMoved.Add(Attrition)