feat(ai): add monster behaviours
This commit is contained in:
1 parent
18f2b5f510
commit
0ed5df6a25
1 file changed
+79
+79
@@ -0,0 +1,79 @@
|
|||||||
|
-- Monster behaviours, one per ai tag. Each takes (game, monster) and fully
|
||||||
|
-- resolves that monster's turn through game helpers, so all state mutation and
|
||||||
|
-- rng use stays centralised and deterministic.
|
||||||
|
|
||||||
|
local Ai = {}
|
||||||
|
|
||||||
|
local AGGRO = { chase = 10, pack = 13, ranged = 12, flee = 8, erratic = 8 }
|
||||||
|
local DIRS = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } }
|
||||||
|
|
||||||
|
local function chase(game, monster)
|
||||||
|
if game:playerAdjacent(monster) then
|
||||||
|
game:monsterMelee(monster)
|
||||||
|
elseif game:canSeePlayer(monster, AGGRO.chase) then
|
||||||
|
game:stepMonsterToward(monster, game.player.x, game.player.y)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function pack(game, monster)
|
||||||
|
if game:playerAdjacent(monster) then
|
||||||
|
game:monsterMelee(monster)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if game:canSeePlayer(monster, AGGRO.pack) then
|
||||||
|
game:stepMonsterToward(monster, game.player.x, game.player.y)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local ally = game:nearestAlly(monster)
|
||||||
|
if ally then
|
||||||
|
game:stepMonsterToward(monster, ally.x, ally.y)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ranged(game, monster)
|
||||||
|
if game:canSeePlayer(monster, monster.range) and game:hasClearShot(monster) then
|
||||||
|
if game:playerAdjacent(monster) then
|
||||||
|
game:stepMonsterAway(monster, game.player.x, game.player.y)
|
||||||
|
else
|
||||||
|
game:monsterShoot(monster)
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if game:canSeePlayer(monster, AGGRO.ranged) then
|
||||||
|
game:stepMonsterToward(monster, game.player.x, game.player.y)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function flee(game, monster)
|
||||||
|
if game:canSeePlayer(monster, AGGRO.flee) then
|
||||||
|
game:stepMonsterAway(monster, game.player.x, game.player.y)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function erratic(game, monster)
|
||||||
|
if game:playerAdjacent(monster) then
|
||||||
|
game:monsterMelee(monster)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if game:canSeePlayer(monster, AGGRO.erratic) and game.rng:chance(1, 2) then
|
||||||
|
game:stepMonsterToward(monster, game.player.x, game.player.y)
|
||||||
|
else
|
||||||
|
local dir = DIRS[game.rng:range(1, 4)]
|
||||||
|
game:moveMonster(monster, dir[1], dir[2])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Ai.behaviours = {
|
||||||
|
chase = chase,
|
||||||
|
pack = pack,
|
||||||
|
ranged = ranged,
|
||||||
|
flee = flee,
|
||||||
|
erratic = erratic,
|
||||||
|
}
|
||||||
|
|
||||||
|
function Ai.act(game, monster)
|
||||||
|
local behaviour = Ai.behaviours[monster.ai] or chase
|
||||||
|
behaviour(game, monster)
|
||||||
|
end
|
||||||
|
|
||||||
|
return Ai
|
||||||
Reference in new issue
Block a user