1
0
mirror of https://github.com/veden/Rampant.git synced 2025-01-05 22:53:24 +02:00
Rampant/libs/AIPlanning.lua

360 lines
14 KiB
Lua
Raw Normal View History

2019-02-16 06:17:30 +02:00
if aiPlanningG then
return aiPlanningG
end
2016-10-15 02:00:18 +02:00
local aiPlanning = {}
-- imports
local constants = require("Constants")
local mathUtils = require("MathUtils")
-- local aiPredicates = require("AIPredicates")
2017-06-01 03:46:53 +02:00
2016-10-15 02:00:18 +02:00
-- constants
2017-06-01 03:46:53 +02:00
local NO_RETREAT_BASE_PERCENT = constants.NO_RETREAT_BASE_PERCENT
local NO_RETREAT_EVOLUTION_BONUS_MAX = constants.NO_RETREAT_EVOLUTION_BONUS_MAX
2016-10-15 02:00:18 +02:00
local AI_STATE_PEACEFUL = constants.AI_STATE_PEACEFUL
local AI_STATE_AGGRESSIVE = constants.AI_STATE_AGGRESSIVE
local AI_STATE_RAIDING = constants.AI_STATE_RAIDING
local AI_STATE_MIGRATING = constants.AI_STATE_MIGRATING
local AI_STATE_ONSLAUGHT = constants.AI_STATE_ONSLAUGHT
local AI_STATE_SIEGE = constants.AI_STATE_SIEGE
2019-04-25 08:13:22 +02:00
local AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION = constants.AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION
local AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION = constants.AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION
2016-10-15 02:00:18 +02:00
2017-06-01 03:46:53 +02:00
local AI_UNIT_REFUND = constants.AI_UNIT_REFUND
2016-10-15 02:00:18 +02:00
local AI_MAX_POINTS = constants.AI_MAX_POINTS
local AI_POINT_GENERATOR_AMOUNT = constants.AI_POINT_GENERATOR_AMOUNT
local AI_MIN_STATE_DURATION = constants.AI_MIN_STATE_DURATION
local AI_MIN_TEMPERAMENT_DURATION = constants.AI_MIN_TEMPERAMENT_DURATION
local AI_MAX_STATE_DURATION = constants.AI_MAX_STATE_DURATION
local AI_MAX_TEMPERAMENT_DURATION = constants.AI_MAX_TEMPERAMENT_DURATION
2017-06-01 03:46:53 +02:00
local BASE_RALLY_CHANCE = constants.BASE_RALLY_CHANCE
local BONUS_RALLY_CHANCE = constants.BONUS_RALLY_CHANCE
2018-02-19 02:21:18 +02:00
local RETREAT_MOVEMENT_PHEROMONE_LEVEL_MIN = constants.RETREAT_MOVEMENT_PHEROMONE_LEVEL_MIN
local RETREAT_MOVEMENT_PHEROMONE_LEVEL_MAX = constants.RETREAT_MOVEMENT_PHEROMONE_LEVEL_MAX
2020-04-03 05:47:26 +02:00
local MINIMUM_AI_POINTS = constants.MINIMUM_AI_POINTS
2017-06-01 03:46:53 +02:00
2016-10-15 02:00:18 +02:00
-- imported functions
local randomTickEvent = mathUtils.randomTickEvent
local linearInterpolation = mathUtils.linearInterpolation
local mFloor = math.floor
local mRandom = math.random
2016-10-15 02:00:18 +02:00
local mMax = math.max
local mMin = math.min
2016-10-15 02:00:18 +02:00
-- module code
function aiPlanning.planning(natives, evolution_factor, tick)
natives.evolutionLevel = evolution_factor
2019-12-16 03:16:56 +02:00
2020-04-03 05:47:26 +02:00
local maxPoints = mMax(AI_MAX_POINTS * evolution_factor, MINIMUM_AI_POINTS)
2017-06-01 03:46:53 +02:00
2019-12-07 07:57:20 +02:00
if not natives.ranIncompatibleMessage and natives.newEnemies and (game.active_mods["bobenemies"] or game.active_mods["Natural_Evolution_Enemies"]) then
natives.ranIncompatibleMessage = true
for i,p in ipairs(game.connected_players) do
p.print("Bobs enemies or NEE has been detected with Rampant's new enemies, the artifacts from each of these mods will still work with Rampant's new enemies. The generation of bobs or NEE unit spawners explicitly by Rampant is no longer supported when the Rampant's new enemies are active.")
end
end
2019-10-19 21:13:48 +02:00
local maxOverflowPoints = maxPoints * 3
2017-06-01 03:46:53 +02:00
local attackWaveMaxSize = natives.attackWaveMaxSize
2018-02-19 02:21:18 +02:00
natives.retreatThreshold = linearInterpolation(evolution_factor, RETREAT_MOVEMENT_PHEROMONE_LEVEL_MIN, RETREAT_MOVEMENT_PHEROMONE_LEVEL_MAX)
2017-06-01 03:46:53 +02:00
natives.rallyThreshold = BASE_RALLY_CHANCE + (evolution_factor * BONUS_RALLY_CHANCE)
natives.formSquadThreshold = mMax((0.25 * evolution_factor), 0.10)
2020-04-03 05:47:26 +02:00
natives.attackWaveSize = attackWaveMaxSize * (evolution_factor ^ 1.15)
natives.attackWaveDeviation = (natives.attackWaveSize * 0.333)
natives.attackWaveUpperBound = natives.attackWaveSize + (natives.attackWaveSize * 0.35)
if (natives.attackWaveSize < 1) then
natives.attackWaveSize = 2
natives.attackWaveDeviation = 1
natives.attackWaveUpperBound = 3
end
2019-02-03 08:01:28 +02:00
natives.settlerWaveSize = linearInterpolation(evolution_factor ^ 1.66667, natives.expansionMinSize, natives.expansionMaxSize)
2019-05-03 21:32:59 +02:00
natives.settlerWaveDeviation = (natives.settlerWaveSize * 0.33)
2019-02-06 08:25:43 +02:00
2019-05-03 21:32:59 +02:00
natives.settlerCooldown = mFloor(linearInterpolation(evolution_factor ^ 1.66667, natives.expansionMaxTime, natives.expansionMinTime))
2019-02-03 08:01:28 +02:00
2017-06-01 03:46:53 +02:00
natives.unitRefundAmount = AI_UNIT_REFUND * evolution_factor
natives.kamikazeThreshold = NO_RETREAT_BASE_PERCENT + (evolution_factor * NO_RETREAT_EVOLUTION_BONUS_MAX)
local points = mFloor((AI_POINT_GENERATOR_AMOUNT * mRandom()) + ((AI_POINT_GENERATOR_AMOUNT * 0.7) * (evolution_factor ^ 2.5)) * natives.aiPointsScaler)
2019-02-03 08:01:28 +02:00
if (natives.state == AI_STATE_ONSLAUGHT) then
points = points * 2
end
natives.baseIncrement = points
2019-02-03 08:01:28 +02:00
2019-10-19 21:13:48 +02:00
local currentPoints = natives.points
2019-12-16 03:16:56 +02:00
2019-10-19 21:13:48 +02:00
if (currentPoints < maxPoints) then
natives.points = currentPoints + points
end
2019-10-19 21:13:48 +02:00
if (currentPoints > maxOverflowPoints) then
natives.points = maxOverflowPoints
2016-10-15 02:00:18 +02:00
end
2019-02-03 08:01:28 +02:00
2019-05-10 02:46:57 +02:00
if (natives.stateTick <= tick) then
-- local roll = mRandom() * mMax(1 - evolution_factor, 0.15) * natives.aiAggressiveness
local roll = mRandom()
2019-12-16 03:16:56 +02:00
if (natives.temperament < 0.05) then -- 0 - 0.05
if natives.enabledMigration then
natives.state = AI_STATE_SIEGE
else
if natives.raidAIToggle then
2019-12-16 03:16:56 +02:00
if (roll < 0.85) then
natives.state = AI_STATE_AGGRESSIVE
natives.canAttackTick = randomTickEvent(tick,
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
else
natives.state = AI_STATE_RAIDING
end
else
natives.state = AI_STATE_AGGRESSIVE
2019-12-16 03:16:56 +02:00
natives.canAttackTick = randomTickEvent(tick,
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
end
end
elseif (natives.temperament < 0.20) then -- 0.05 - 0.2
2019-12-16 03:16:56 +02:00
if (natives.enabledMigration) then
if (roll < 0.4) then
natives.state = AI_STATE_SIEGE
else
natives.state = AI_STATE_MIGRATING
end
else
if natives.raidAIToggle then
if (roll < 0.95) then
natives.state = AI_STATE_AGGRESSIVE
natives.canAttackTick = randomTickEvent(tick,
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
else
natives.state = AI_STATE_RAIDING
end
else
natives.state = AI_STATE_AGGRESSIVE
natives.canAttackTick = randomTickEvent(tick,
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
end
end
elseif (natives.temperament < 0.4) then -- 0.2 - 0.4
2019-12-16 03:16:56 +02:00
if (natives.enabledMigration) then
if (roll < 0.2) then
natives.state = AI_STATE_AGGRESSIVE
natives.canAttackTick = randomTickEvent(tick,
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
elseif (roll < 0.8) then
natives.state = AI_STATE_MIGRATING
else
natives.state = AI_STATE_PEACEFUL
end
else
2019-12-16 03:16:56 +02:00
if (roll < 0.6) then
natives.state = AI_STATE_AGGRESSIVE
natives.canAttackTick = randomTickEvent(tick,
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
else
natives.state = AI_STATE_PEACEFUL
end
end
elseif (natives.temperament < 0.6) then -- 0.4 - 0.6
2019-12-16 03:16:56 +02:00
if (roll < 0.5) then
natives.state = AI_STATE_AGGRESSIVE
2019-12-16 03:16:56 +02:00
natives.canAttackTick = randomTickEvent(tick,
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
else
natives.state = AI_STATE_PEACEFUL
2019-12-16 03:16:56 +02:00
end
elseif (natives.temperament < 0.8) then -- 0.6 - 0.8
if (roll < 0.6) then
natives.state = AI_STATE_AGGRESSIVE
2019-12-16 03:16:56 +02:00
natives.canAttackTick = randomTickEvent(tick,
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
elseif (roll < 0.8) then
natives.state = AI_STATE_ONSLAUGHT
else
natives.state = AI_STATE_PEACEFUL
2019-12-16 03:16:56 +02:00
end
else -- 0.8 - 1
2019-12-16 03:16:56 +02:00
if (natives.enabledMigration and natives.raidAIToggle) then
if (roll < 0.3) then
natives.state = AI_STATE_SIEGE
elseif (roll < 0.6) then
natives.state = AI_STATE_ONSLAUGHT
elseif (roll < 0.8) then
natives.state = AI_STATE_RAIDING
else
natives.state = AI_STATE_AGGRESSIVE
natives.canAttackTick = randomTickEvent(tick,
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
end
elseif (natives.enabledMigration) then
if (roll < 0.3) then
natives.state = AI_STATE_SIEGE
elseif (roll < 0.7) then
natives.state = AI_STATE_ONSLAUGHT
else
natives.state = AI_STATE_AGGRESSIVE
natives.canAttackTick = randomTickEvent(tick,
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
end
elseif (natives.raidAIToggle) then
if (roll < 0.4) then
natives.state = AI_STATE_ONSLAUGHT
elseif (roll < 0.7) then
natives.state = AI_STATE_RAIDING
else
natives.state = AI_STATE_AGGRESSIVE
natives.canAttackTick = randomTickEvent(tick,
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
end
else
if (roll < 0.6) then
natives.state = AI_STATE_ONSLAUGHT
else
natives.state = AI_STATE_AGGRESSIVE
natives.canAttackTick = randomTickEvent(tick,
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
end
2019-10-19 21:13:48 +02:00
end
end
2019-12-16 03:16:56 +02:00
-- print("changing state", natives.state)
2019-10-19 21:13:48 +02:00
natives.stateTick = randomTickEvent(tick, AI_MIN_STATE_DURATION, AI_MAX_STATE_DURATION)
end
2016-10-15 02:00:18 +02:00
end
function aiPlanning.temperamentPlanner(natives)
local destroyPlayerBuildings = natives.destroyPlayerBuildings
local lostEnemyUnits = natives.lostEnemyUnits
local lostEnemyBuilding = natives.lostEnemyBuilding
local rocketLaunched = natives.rocketLaunched
local builtEnemyBuilding = natives.builtEnemyBuilding
local ionCannonBlasts = natives.ionCannonBlasts
local artilleryBlasts = natives.artilleryBlasts
local activeNests = natives.activeNests
local activeRaidNests = natives.activeRaidNests
local currentTemperament = natives.temperamentScore
local delta = 0
if activeNests > 0 then
2019-12-16 03:16:56 +02:00
local val = (1.5 * activeNests)
delta = delta + val
if destroyPlayerBuildings > 0 then
2019-12-16 03:16:56 +02:00
delta = delta - (200 * destroyPlayerBuildings)
end
else
delta = delta - 1
if destroyPlayerBuildings > 0 then
2019-12-16 03:16:56 +02:00
if (currentTemperament > 0) then
delta = delta - (200 * destroyPlayerBuildings)
else
delta = delta + (200 * destroyPlayerBuildings)
end
end
end
if activeRaidNests > 0 then
2019-12-16 03:16:56 +02:00
local val = (0.008 * activeRaidNests)
delta = delta - val
else
2019-12-16 03:16:56 +02:00
delta = delta - 0.5
end
if lostEnemyUnits > 0 then
2019-12-16 03:16:56 +02:00
local val = (0.04 * lostEnemyUnits)
if (currentTemperament > 0) then
delta = delta - val
else
delta = delta + val
end
end
if lostEnemyBuilding > 0 then
2019-12-16 03:16:56 +02:00
delta = delta + (20 * lostEnemyBuilding)
end
if (builtEnemyBuilding > 0) then
2019-12-16 03:16:56 +02:00
local val = (50 * builtEnemyBuilding)
if (currentTemperament > 0) then
delta = delta - val
else
delta = delta + val
end
else
2019-12-16 03:16:56 +02:00
delta = delta - 0.5
end
if (rocketLaunched > 0) then
2019-12-16 03:16:56 +02:00
local val = (100 * rocketLaunched)
delta = delta + val
end
if (ionCannonBlasts > 0) then
2019-12-16 03:16:56 +02:00
local val = (50 * ionCannonBlasts)
delta = delta + val
end
if (artilleryBlasts > 0) then
2019-12-16 03:16:56 +02:00
local val = (50 * artilleryBlasts)
delta = delta + val
end
2019-12-16 03:16:56 +02:00
-- print(natives.activeNests, natives.activeRaidNests, natives.destroyPlayerBuildings, natives.lostEnemyUnits,
-- natives.lostEnemyBuilding, natives.rocketLaunched, natives.builtEnemyBuilding, natives.ionCannonBlasts,
-- natives.artilleryBlasts)
natives.destroyPlayerBuildings = 0
natives.lostEnemyUnits = 0
natives.lostEnemyBuilding = 0
natives.rocketLaunched = 0
natives.builtEnemyBuilding = 0
natives.ionCannonBlasts = 0
natives.artilleryBlasts = 0
2019-12-16 03:16:56 +02:00
natives.temperamentScore = mMin(10000, mMax(-10000, currentTemperament + (natives.evolutionLevel * delta)))
natives.temperament = ((natives.temperamentScore + 10000) * 0.00005)
-- print(natives.temperament, natives.temperamentScore)
-- print("--")
end
2019-02-16 06:17:30 +02:00
aiPlanningG = aiPlanning
2016-10-15 02:00:18 +02:00
return aiPlanning