Maybe specify what we want in detail? I worked this up in a couple hours, might be some possibilities of infinite recursion I've missed, but I think it's what I'd want to see, which is intelligent behavior, monsters going after whoever disturbed them, varying behavior for different classes of monsters...
General Lair-based AI for Monsters and Bandits, to be processed during End Turns
Designed for most monsters. Prioritizes survival, then opportunistic preying on weaker units/cities. After attacking a target and presumably surviving, the monster will return to it's lair to rest. Monsters try to stick to forests and hills and swamps when possible.
Modifications for bandits/Syndicate: Remove warden detection. Find new lair if current lair is inside borders. Initial bandits will always guard their lair (only Lair behavior: no random hunting, will only attack targets adjacent to the lair). Spawned bandits will immediately go hunting, targeting closest city, and use lair based AI. After cooldown expires, they will immediately go hunting again.
Modifications for spawned nomadic monsters: They should set off in a specific direction after spawning (hunting behavior), possibly set up a lair.
Modifications for undead: Undead kill because they hate life. Once woken, they continue hunting and killing, not returning to their lairs (nomadic), and they do not care about threats, being mindless. They won't prioritize cover (forests/swamps/hills) and won't randomly awaken to hunt. Good behavior for golems, too. Probably should also attack other monsters...
Modifications for demons: Kill because they hate life, not for sustenance. Similar to undead, except they do care about threats.
General Prey/Threat definitions
- Threats are units/cities with greater or equal strength. If of equal strength, threats have equal or more unit members.
- Prey are units/cites with equal or less strength. If of equal strength, prey have less unit members.
- Pioneers and resources and outposts are always prey unless guarded. The system below allows a unit to guard
Variables
AI: specifies AI algorithm to use for monster (Lair based, nomadic, undead, demonic, bandit-leader, bandit-raider). This can change for a specific monster, for example, if a lair is destroyed, and no room exists to create a new lair, AI becomes nomadic.
Behavior: Current behavior of the monster.
Target: A location where the monster thinks it's current objective is near.
Cooldown: Used as a timer
Start
Behavior = Lair? ; Used when the monster is current in it's lair.
Lair destroyed? ; Shouldn't happen with the monster in the lair... but just in case.
Behavior = FindNewLair
Redo from start
Check for warden
within warden range, and city attached to the outpost has strength greater or equal to monster?
Behavior = FindNewLair
Redo from start
Look for threats ; Threats in this case are units/cities with strength two higher than the monster (Strong unit threatens a weak monster). Scan radius one tile.
Threat? ; Home ain't worth dying over...
Behavior = FindNewLair
Redo from start
Cooldown > 0 ; Recently eaten?
Cooldown = Cooldown - 1
Exit
Health less than max? ; Don't look for trouble if still wounded...
Exit
Look for prey ; Prey are units/cities with strength less than monster. If equal strength, prey have less unit members. Scan radius is two tiles
Prey?
Behavior = Attack
Redo from start
Inside nation borders?
Behavior = Hunt
Cooldown = 9 ; hunt for eight seasons
Target = Closest city matching nation borders.
Redo from start
5% chance of... ; Maybe modified by difficulty?
Behavior = Hunt ; Monsters will occasionally leave their lairs.
Cooldown = 9 ; hunt for eight seasons
Target = random tile within three tiles of lair.
Exit
Behavior = Hunt? ; Hunt behavior is used when a specific target isn't available... Basically searching for targets.
Check for warden
Disallow movement to any tile that is protected by a warden with city strength greater or equal to monster.
No movement available?
Behavior = Evade
Redo from start
Currently within warden range, and city attached to the outpost has strength greater or equal to monster?
Behavior = Evade
Redo from start
Look for threats ; Threats are units/cities with strength greater or equal to monster. If equal strength, threats have equal or more unit members. Scan radius two tiles
Disallow any possible movement that moves monster within attack range of a threat.
No movement available?
Behavior = Evade
Redo from start
Is a threat within attack range? ; one tile attack range.
Behavior = Evade
Redo from start
Look for prey ; Prey are units/cities with strength less than monster. If equal strength, prey have less unit members. Scan radius is two tiles
Prey?
Behavior = Attack
Target = weakest available prey
Redo from start.
Look for resources ; Resources currently being gathered are a secondary priority, so you can bait monsters away with a weak unit. scan radius is 2 tiles.
Resources?
Behavior = Attack
Target = Resource
Redo from start.
Cooldown = 1? ; Cooldown tracks turns until monster gives up and returns to lair empty handed.
Cooldown = 0
Behavior = MoveToLair
Redo from start
Cooldown > 1?
Cooldown = Cooldown - 1
Move to one of the remaining possible tiles, prioritizing target direction (any tiles that move closer to target, this should normally be 3 tiles unless tiles are disallowed by threats), then prioritizing tiles with forest, swamp, and hills. If no priorities, use random determination to select a tile
Exit
Behavior = MoveToLair? ; Used after attacking something
Lair destroyed?
Behavior = FindNewLair
Redo from start
Check for warden
Disallow movement to any tile that is protected by a warden with city strength greater or equal to monster.
If no movement available, reset possible movements
Look for threats ; Threats are units/cities with strength greater or equal to monster. If equal, threats have equal or more unit members. Scan radius two tiles
Disallow any possible movement that moves monster within attack range of a threat.
Is a threat within attack range? ; one tile attack range.
Move to a safe tile, prioritizing forest, swamp, and hill tiles (tiles with cover and no civilization), then prioritizing lair direction
Exit
Move to one of the remaining possible tiles, prioritizing target direction (any tiles that move closer to target, this should normally be 3 tiles unless tiles are disallowed by threats), then prioritizing tiles with forest, swamp, and hills. If no priorities, use random determination to select a tile
Exit
Behavior = Attack? ; Used when a target is found. target is last known location of prey
Check for warden
Disallow movement to any tile that is protected by a warden with city strength greater or equal to monster.
No movement available?
Behavior = Evade
Redo from start
Currently within warden range, and city attached to the outpost has strength greater or equal to monster?
Behavior = Evade
Redo from start
Look for threats ; Threats are units/cities with strength greater or equal to monster. If equal strength, threats have equal or more unit members. Scan radius two tiles
Disallow any possible movement that moves monster within attack range of a threat.
No movement available?
Behavior = Evade
Redo from start
Is a threat within attack range? ; one tile attack range.
Behavior = Evade
Redo from start
Look for prey ; we've possibly moved last turn, along with prey, so try to find again.
Prey?
Is any prey at Range = 1?
Attack target
Behavior = MoveToLair
Cooldown = 3 ; wait three seasons after getting back to lair
Exit
Else
Target = weakest available prey that can be moved to (range will be 2, so we're trying to move adjacent to prey) on remaining possible movement tiles. If no prey meet that criteria, target weakest available prey (means a threat is close, so we have to travel around the threat to get to the prey).
Move to one of the remaining possible tiles, prioritizing target direction (any tiles that move closer to target, this should normally be 3 tiles unless tiles are disallowed by threats), then prioritizing tiles with forest, swamp, and hills. If no clear priority tile, use random determination to select a tile
Exit
Else
Behavior = Hunt ; Lost the target, hunt around the immediate area.
Cooldown = 4 ; Hunt for three turns
Redo from start.
Behavior = Evade? ; Use when a monster is threatened.
Check for threats (one tile radius)
Disallow movement to tiles containing threats
No possible movement left?
25% of attacking weakest unit ; completely surrounded by tougher units. Suggest Frenzying monster.
Exit
Check threat attack ranges (for threats in a two tile radius)
Disallow movement to threatened tiles
No possible movement left?
Is current tile threatened?
Move to tile prioritizing tile without a threat, closer to lair, and containing trees, swamp, or hills. If more than one tile, pick a random tile.
Exit
Else
Check tiles within radius of one for prey
Prey?
Attack target
Exit ; Currently safe.
Check for warden (one tile radius)
Disallow movement to warded tiles
No possible movement left?
Move to tile prioritizing tile without a threat, not threatened, closer to lair, and containing trees, swamps, or hills. If more than one tile, pick a random tile.
Exit
All tiles available to move to?
Behavior = Hunting ; Looks like we're safe
Cooldown = 9
Redo from start
Else
Move to one of the possible movement tiles. Prioritize tile closer to lair, containing trees swamps, or hills. If more than one tile, pick a random tile.
Exit
Behavior = FindNewLair? ; Use when a monster is driven away from it's lair by wardens or major threats
Target is set each turn in a direction away from threats/civilization. New lair is set up as soon as monsters find an area with no threats in 2 tile radius. If not possible to find in 10 seasons, change behavior to nomadic (no more lair). Certain monsters may not set up a lair inside borders.