~technomancy/tremendous-quest-iv

fa2ee20230d1d513f98d1f05b8a4716d25f37e13 — Benaiah Mischenko 1 year, 5 months ago 9a24522 pathfinding
barking and misc. fixes
3 files changed, 41 insertions(+), 14 deletions(-)

M ai.fnl
M characters.fnl
M world.fnl
M ai.fnl => ai.fnl +36 -11
@@ 5,8 5,8 @@

(fn make-ai [character]
  (let [char (or character {})
        ai {:mood :neutral
            :personality :none
        ai {:mood (lume.randomchoice [:happy :foul :neutral])
            :personality (lume.randomchoice [:mean :upbeat :sleepy])
            :task {:name :pause
                   :timer (lume.random 10)}}]
    (tset char :ai ai)


@@ 21,6 21,7 @@
      (set path (pathfinder:getPath sx sy x y))))
  path)

;; todo: don't take the entire state as an argument
(fn choose-next-task [last-task state char]
  (let [{:ai {: mood : personality
              : current-path : current-task}} char


@@ 32,14 33,36 @@
    (match next-task
      :pause {:name :pause :timer (lume.random 5 25)}
      :walk-to-random-point
      (let [path (choose-random-path state.map state.pathfinder (pathfinding.absolute-points->path-points char.x char.y))]
      (let [path (choose-random-path state.map state.pathfinder
                                     (pathfinding.absolute-points->path-points char.x char.y))]
        {:name next-task
         :path path
         :path-points (pathfinding.path->points path)
         :next-point 2}))))

(fn bark [ai]
  (let [bark-msg (match ai
                   {:personality :upbeat :mood :happy}
                   (lume.randomchoice ["*whistle*" "I feel great!" "Nothing can get me down!"
                                       "Oh yeah!" "Feeling good today."])
                   {:personality :mean :mood :happy}
                   (lume.randomchoice ["hehehehe" "later n00bs" "Get on my level!"
                                       "see ya losers!"])
                   {:personality _ :mood :neutral}
                   (lume.randomchoice ["..." "Hmm..." ""])
                   {:personality :mean :mood :foul}
                   (lume.randomchoice ["#&%$!!" "You cheated!" "I hate this game!"])
                   {:personality _ :mood :foul} "Ugh..."
                   _ "you weren't supposed to see this...")]
    (print ai.personality ai.mood bark-msg)
    (set ai.bark bark-msg)
    (set ai.bark-timer 2.5)))

;; todo: don't take the entire state as an argument
(fn run-ai [dt state char]
  (if (and char.ai.bark-timer (> char.ai.bark-timer 0)) (set char.ai.bark-timer (- char.ai.bark-timer dt))
      (and char.ai.bark-timer (<= char.ai.bark-timer 0)) (do (set char.ai.bark nil) (set char.ai.bark-timer nil))
      (not char.ai.bark-timer) (when (= (math.floor (lume.random 1 2000)) 1) (bark char.ai)))
  (let [{: ai} char]
    (match ai.task.name
      :pause


@@ 50,13 73,15 @@
      (let [pyi (* ai.task.next-point 2) pxi (- pyi 1)
            px (. ai.task.path-points pxi) py (. ai.task.path-points pyi)
            (apx apy) (pathfinding.path-points->absolute-points px py)]
        (if (> (lume.distance char.x char.y apx apy) (* char.speed dt))
            (let [(dx dy) (lume.vector (lume.angle char.x char.y apx apy) (* char.speed dt))
                  (nx ny colls) (state.world:move char (+ char.x dx) (+ char.y dy) #nil)]
              (set char.x nx) (set char.y ny))
            (do (set char.x apx) (set char.y apy)
                (set ai.task.next-point (+ ai.task.next-point 1))
                (when (> (* ai.task.next-point 2) (# ai.task.path-points))
                  (set ai.task (choose-next-task :walk-to-random-point state char)))))))))
        (if (or (not apx) (not apy))
            (set ai.task (choose-next-task :walk-to-random-point state char))
            (if (> (lume.distance char.x char.y apx apy) (* char.speed dt))
                (let [(dx dy) (lume.vector (lume.angle char.x char.y apx apy) (* char.speed dt))
                      (nx ny colls) (state.world:move char (+ char.x dx) (+ char.y dy) #nil)]
                  (set char.x nx) (set char.y ny))
                (do (set char.x apx) (set char.y apy)
                    (set ai.task.next-point (+ ai.task.next-point 1))
                    (when (> (* ai.task.next-point 2) (# ai.task.path-points))
                      (set ai.task (choose-next-task :walk-to-random-point state char))))))))))

{:make make-ai :run run-ai}

M characters.fnl => characters.fnl +1 -1
@@ 20,7 20,7 @@
(λ make [?name x y quad-number]
  (let [quad (love.graphics.newQuad (+ 1 (* (- quad-number 1) 16)) 0 14 16
                                    (sprites:getDimensions))]
    {: x : y :w 10 :h 15 :speed 128
    {: x : y :w 10 :h 15 :speed 96
     :name (or ?name (lume.randomchoice nicks))
     :draw (fn [x y] (love.graphics.draw sprites quad
                                         (- (math.floor x) 2)

M world.fnl => world.fnl +4 -2
@@ 13,6 13,7 @@
              :viewport {:scale 1 :x 0 :y 0}})

(set state.player (. state.characters 1))
(set state.player.speed 128)
(global s (or _G.s state)) ; exposed for repl

(fn distance-from-player [a]


@@ 24,7 25,7 @@
       unpack
       (pathfinding.path-points->absolute-points)
       ((fn [...]
          (when (> (select :# ...) 3)
          (when (>= (select :# ...) 4)
            (love.graphics.line ...))))))

(fn print-path [path]


@@ 46,7 47,8 @@
        (love.graphics.rectangle :line x y w h))
      (-?> character (. :ai) (. :task) (. :path) draw-path)
      (character.draw x y)
      (-?> character (. :ai) (. :task) (. :name) (love.graphics.print x y)))))
      (-?> character (. :ai) (. :task) (. :name) (love.graphics.print x y))
      (-?> character (. :ai) (. :bark) (love.graphics.print (+ x 16) (- y 16))))))

(fn init-layer [layer]
  (when layer.properties.autohide