diff --git a/editor/mapedit.fnl b/editor/mapedit.fnl index 45661e2..37a87bc 100644 --- a/editor/mapedit.fnl +++ b/editor/mapedit.fnl @@ -185,6 +185,8 @@ (set y (+ y 30)) (set self.level.moveword (textfield self "Move word" self.level.moveword x y 100 200)) (set y (+ y 30)) + (set self.level.loadword (textfield self "Load word" self.level.loadword x y 100 200)) + (set y (+ y 30)) (when (checkbox self "Edit objects" (= self.itile nil) x y) (set self.itile nil) (set self.playerpos nil)) diff --git a/game/defs.fnl b/game/defs.fnl index cf1c46c..5b0e8e5 100644 --- a/game/defs.fnl +++ b/game/defs.fnl @@ -101,7 +101,8 @@ [:dw (tiles.encode-yx map.neut)] [:dw (if map.gord-following (tiles.encode-yx map.jaye) 0xffff)] [:jmp (if (= (or map.tickword "") "") :next map.tickword)] - [:jmp (if (= (or map.moveword "") "") :move-noop map.moveword)])) + [:jmp (if (= (or map.moveword "") "") :move-noop map.moveword)] + [:jmp (if (= (or map.loadword "") "") :next map.loadword)])) (vm.code:append :map-ptr [:db 0] :map-page [:db 0]) (vm:word :map :lit :map-ptr :get) @@ -111,6 +112,7 @@ (vm:word :map-gord-yx :map 245 :+ :get) (vm:word :map-specific-tick :map 247 :+ :execute) (vm:word :map-specific-move :map 250 :+ :execute) +(vm:word :map-specific-load :map 253 :+ :execute) (fn deflevel [mapfile label] (local level prg) ; todo: (asm.new prg) - if we want to load levels as an overlay diff --git a/game/entity.fnl b/game/entity.fnl index 53b8c96..6c79530 100644 --- a/game/entity.fnl +++ b/game/entity.fnl @@ -67,6 +67,11 @@ (vm:word :set-respondertile ; itile -- :get-responder :get :swap :update-itile) +; run only when processing an ev.touch event +(vm:word :transparent-entity-move ; -- f + :get-responder :get :dup :handle-general-move + :swap :over :not (vm:if [:move-player-to] [:drop])) + (vm:word :handle-onoff ; ev off on -- :do ] [:drop])) -(vm:word :walking-through-door +(vm:word :walking-through-door ; ev -- ev f (vm:if-and [[:is-walking?] [:dup ev.touch :=] [:responder-itile (itile :dooropen) :=]] [vm.true] [vm.false])) @@ -92,7 +97,10 @@ (vm:word :exitdoor ; ev -- :walking-through-door (vm:if - [:move-to-responder :drop :get-responder 4 :+ :get :next-level :set] + [(vm:ifchain + [:gord-sitting :get] [(say :jaye "I'M NOT LEAVING GORD BEHIND.")] + [:libb-hidden? :not] [(say :neut "IT IS INADVISABLE TO LEAVE THIS" "AREA WITHOUT RETRIEVING LIBB")] + [:move-to-responder :drop :get-responder 4 :+ :get :next-level :set])] [:door])) (vm:word :move-to-responder :get-responder :get :move-player-to) @@ -102,13 +110,18 @@ :dup (itile :switchoff) (itile :switchon) :handle-onoff (itile :switchon) :activate-link) +(vm:var :disconnected-term-attempt vm.false) (vm:word :term ; ev -- :dup ev.touch := (vm:when (vm:ifchain [:is-jaye?] [:drop ev.act] - [:is-neut?] [:linked-entity - (vm:if-and [[:dup :entity-itile (itile :termon) :=] - [:responder-itile (itile :termon) :=]] - [:get :move-player-to] [:drop])] + [:is-neut?] [:responder-itile (itile :termon) := (vm:when + :linked-entity :dup :entity-itile (itile :termon) := + (vm:if [:get :move-player-to] + [:drop (say :neut "DESTINATION TERMINAL" "IS DISCONNECTED") + :disconnected-term-attempt :get :not (vm:when + vm.true :disconnected-term-attempt :set + (say :neut "PLEASE CONTACT YOUR" "SYSTEM ADMINISTRATOR") + (say :neut "THIS INCIDENT HAS" "BEEN REPORTED"))]))] [])) (itile :termoff) (itile :termon) :handle-onoff) @@ -171,7 +184,7 @@ (vm:word :trigger-sidekick (vm:if-and [[:is-jaye?] [:gord-sitting :get]] [:gord-yx :get ev.touch :entity-around>do] - [(vm:if-and [[:is-neut?] [:libb-present :get] [:libb-yx :get 0xffff :=]] + [(vm:if-and [[:is-neut?] [:libb-present :get] [:libb-hidden?]] [:neut-yx :get ev.hack :entity-at>do :drop])])) (fn append-from-map [map entity-org prefix] diff --git a/game/init.fnl b/game/init.fnl index 061ebde..0bdfacd 100644 --- a/game/init.fnl +++ b/game/init.fnl @@ -37,6 +37,7 @@ :map-gord-yx :gord-yx :set 0 :gord-dir :set 0xffff :rexx-yx :set + :map-specific-load :full-redraw) (vm.code:append :main @@ -45,7 +46,7 @@ [:vm :hires :lit :level1 :load-level (vm:forever - (vm:hotswap-sync :lit :level6 :load-level) + (vm:hotswap-sync :lit :level4 :load-level) :interactive-eval-checkpoint :handle-key ) diff --git a/game/level3.fnl b/game/level3.fnl index 8637cb1..19d8cdc 100644 --- a/game/level3.fnl +++ b/game/level3.fnl @@ -6,6 +6,8 @@ (local vm level.vm) +(vm:word :level3-load vm.true :gord-sitting :set) + (vm:var :gord-introduced vm.false) (vm:word :flicker :get-responder ev.tog :entity>do 0x400 :snooze) (vm:word :gordterm ; ev -- @@ -15,10 +17,11 @@ :flicker :flicker :flicker :flicker (say :neut "]HUMAN ASSISTANCE IS REQUIRED") (say :neut "]IF HUMAN IS PRESENT" " PLEASE RESPOND") - :hide-footer + :hide-footer :set-human-tileset :full-redraw :flicker :flicker :flicker :flicker (say :gord "WHAT THE...") (say :gord "IS SOMEONE IN THE TERMINAL?") + :hide-footer :set-prog-tileset :full-redraw (say :gord "]HUMAN IS PRESENT") (say :neut "]GREETINGS, HUMAN") (say :neut "]THIS IS NEUT V0.71.4RC12") @@ -35,6 +38,23 @@ :drop ev.noop]) :term) +(vm:var :gord-jaye-met vm.false) +(vm:word :gordtable ; ev -- + ev.touch := (vm:when :transparent-entity-move + (vm:if-and [[:is-jaye?] [:gord-jaye-met :get :not]] + [vm.true :gord-jaye-met :set + (say :jaye "HEY! GORD?" "I'M JAYE.") + (vm:if + [(say :gord "JAYE, AM I GLAD TO SEE YOU." "CAN YOU MOVE THIS DESK?") + (say :jaye "LET ME TRY...") + (say :jaye ". . . ." "!!!!.....") + (say :jaye "!!!!!!!!!!!!...") + (say :jaye "NO, I DON'T THINK I CAN.") + (say :gord "I KEEP STARING AT THAT" "CLEANING ROBOT.") + (say :gord "HE LOOKS LIKE HE COULD" "LIFT A BUILDING.")] + [(say :gord "JAYE, AM I GLAD TO SEE YOU.")])] + [:drop]))) + (vm:var :rexx-introduced) (vm:word :meetrexx ; ev -- (vm:if-and [[:is-neut?] [:dup ev.touch :=] [:rexx-introduced :get :not]] @@ -60,6 +80,7 @@ (say :jaye "HERE, LET ME HELP YOU UP.") (itile :t-floor) :set-respondertile 0xff00 :gord-dir :set + vm.false :gord-sitting :set controlstate.gord :controlstate :bset :get-responder :get :move-player-to controlstate.jaye :controlstate :bset diff --git a/game/level4.fnl b/game/level4.fnl index e034b5d..164ae7d 100644 --- a/game/level4.fnl +++ b/game/level4.fnl @@ -9,7 +9,7 @@ (vm:var :gord-sat vm.false) (vm:word :tutorial-chair ; ev -- ev.touch := (vm:when - :get-responder :get :handle-special-move :drop + :transparent-entity-move :drop (vm:if-and [[:gord-sat :get :not] [:gord-sitting :get]] [vm.true :gord-sat :set (say :gord "PHEW, IT FEELS GOOD TO" "REST MY LEG FOR A BIT.") diff --git a/game/level5.fnl b/game/level5.fnl index 215d388..2d93fdd 100644 --- a/game/level5.fnl +++ b/game/level5.fnl @@ -7,7 +7,7 @@ (vm:word :randomgarbage (itile :broken-table)) (vm:var :doortimer 0) -(vm:word :start-doortimer 0x100 :doortimer :set) +(vm:word :start-doortimer 0x10 :doortimer :set) (vm:word :doortimer-tick :doortimer :get (vm:when :doortimer :get 1 :- :dup :doortimer :set diff --git a/game/map3.json b/game/map3.json index 90e4e84..d2b3beb 100644 --- a/game/map3.json +++ b/game/map3.json @@ -1 +1 @@ -{"neut":{"y":12,"x":8},"map":"616161616161616181616161616161616161612161C063C0C0C0C0C0C0C06143C0E0C2C0C043022161C0C0C0C0C0C0C0C0C022C0C0C0C0C0C0C0612161C0C0C2C0C0C0C0C0C081C0C0C0C0C0C0C0612161C08282A2C0C0C0C0436123C0C0C0C0C0030221616161616161616261616161618161616161612161C063C0C02301C3C163C0C0C0C0C0822363022122C0C0C0C0C0C0A2A1C0C0C0C0C0C0C2C0C0612181C0C0C0C0E2C0C061C0C0C0C0C0C0C0C2C061216123C0C0C0C083C061E0C2C0C0C0C0438203022161610261610261616161026161026161026161212121212121212121212121212121212121212121","jaye":{"y":11,"x":9},"tickword":"","moveword":"","objects":[{"x":1,"link":2,"func":"scan","linkword":"","name":"","y":5},{"x":1,"func":"exitdoor","linkword":"level4","name":"","y":4},{"x":7,"link":4,"func":"gordterm","linkword":"","name":"","y":6},{"x":14,"link":7,"func":"term","linkword":"","name":"","y":11},{"x":9,"link":6,"func":"switch","linkword":"","name":"gordswitch","y":6},{"x":11,"func":"door","linkword":"","name":"","y":9},{"x":10,"link":3,"func":"term","linkword":"","name":"","y":3},{"x":11,"link":9,"func":"scan","linkword":"","name":"","y":10},{"x":14,"func":"door","linkword":"","name":"","y":7},{"x":7,"func":"meetrexx","y":3,"linkword":"","name":""},{"x":8,"func":"meetgord","y":6,"linkword":"","name":""}]} \ No newline at end of file +{"neut":{"y":12,"x":8},"map":"616161616161616181616161616161616161612161C063C0C0C0C0C0C0C06143C0E0C2C0C043022161C0C0C0C0C0C0C0C0C022C0C0C0C0C0C0C0612161C0C0C2C0C0C0C0C0C081C0C0C0C0C0C0C0612161C08282A2C0C0C0C0436123C0C0C0C0C0030221616161616161616261616161618161616161612161C063C0C02301C3C163C0C0C0C0C0822363022122C0C0C0C0C0C0A2A1C0C0C0C0C0C0C2C0C0612181C0C0C0C0E2C0C061C0C0C0C0C0C0C0C2C061216123C0C0C0C083C061E0C2C0C0C0C0438203022161610261610261616161026161026161026161212121212121212121212121212121212121212121","loadword":"level3-load","jaye":{"y":11,"x":9},"tickword":"","moveword":"","objects":[{"x":1,"func":"scan","y":5,"name":"","linkword":"","link":2},{"x":1,"func":"exitdoor","y":4,"name":"","linkword":"level4"},{"x":7,"func":"gordterm","y":6,"name":"","linkword":"","link":4},{"x":14,"func":"term","y":11,"name":"","linkword":"","link":7},{"x":9,"func":"switch","y":6,"name":"gordswitch","linkword":"","link":6},{"x":11,"func":"door","y":9,"name":"","linkword":""},{"x":10,"func":"term","y":3,"name":"","linkword":"","link":3},{"x":11,"func":"scan","y":10,"name":"","linkword":"","link":9},{"x":14,"func":"door","y":7,"name":"","linkword":""},{"x":7,"func":"meetrexx","linkword":"","name":"","y":3},{"x":8,"func":"meetgord","linkword":"","name":"","y":6},{"x":8,"func":"gordtable","name":"","linkword":"","y":5}]} \ No newline at end of file diff --git a/game/map4.json b/game/map4.json index b1dfa20..8855a81 100644 --- a/game/map4.json +++ b/game/map4.json @@ -1 +1 @@ -{"neut":{"y":5,"x":20},"map":"61616161616161616261616161616161616161616143C0C0C082E082C0C0636163C0C083C0C0436161C0C0C0C0C0C2C0C0C0C0C1C0C0C0C0C0C0C06161C0C0C0C0C0C0C0C0C0C0C1C0C0C0C0C0C0C2616103C0C0A3C0C0C003C0C06163C0C0C0C082A261616161616161C1616161812261618161616161616143C0C0C0C0C0C04361C0C0C0C0C0C0C0C0636181C0C0C0C0C0C0C0C081C0C0C0C0C0C0C0C0C06122C0C0C0C0C0E2C0C0C1A2E2C0C0C0C0C0C0C08161E082828282E0C02361A2C0C0C0C0C0C003236161026161610222616102616161610261616102612121214121212121212121212121412121212121","gord-following":true,"jaye":{"y":4,"x":19},"tickword":"","moveword":"","objects":[{"x":7,"func":"term","name":"","linkword":"term-dual-link","y":11},{"link":1,"x":2,"y":3,"linkword":"","name":"term-exit","func":"term"},{"link":1,"x":7,"y":3,"linkword":"","name":"term-scan","func":"term"},{"link":2,"x":12,"y":10,"linkword":"","name":"","func":"switch"},{"link":3,"x":12,"y":9,"linkword":"","name":"","func":"switch"},{"x":11,"func":"door","name":"","linkword":"","y":7},{"link":6,"x":12,"y":7,"linkword":"","name":"","func":"scan"},{"x":15,"func":"door","name":"","linkword":"","y":7},{"link":8,"x":7,"y":7,"linkword":"","name":"","func":"switch"},{"x":10,"func":"door","name":"","linkword":"","y":5},{"link":6,"x":10,"y":4,"linkword":"","name":"","func":"switch"},{"x":16,"func":"rexx","name":"","linkword":"","y":11},{"link":10,"x":7,"y":2,"linkword":"","name":"","func":"scan"},{"link":15,"x":1,"y":4,"linkword":"","name":"","func":"scan"},{"x":1,"func":"exitdoor","name":"","linkword":"level5","y":5},{"x":5,"func":"rexx","name":"","linkword":"","y":8},{"x":7,"func":"tutorial-chair","y":10,"linkword":"","name":""}]} \ No newline at end of file +{"neut":{"y":5,"x":20},"map":"61616161616161616261616161616161616161616143C0C0C082E082C0C0636163C0C083C0C0436161C0C0C0C0C0C2C0C0C0C061C0C0C0C0C0C0C06161C0C0C0C0C0C0C0C0C0C061C0C0C0C0C0C0C2616103C0C0A3C0C0C003C0C06163C0C0C0C082A2616161616161C1C1C16161812261618161616161616143C0C0C0C0C0C04361C0C0C0C0C0C0C0C0636181C0C0C0C0C0C0C0C081C0C0C0C0C0C0C0C0C06122C0C0C0C0C0E2C0C0C1A2E2C0C0C0C0C0C0C08161E082828282E0C02361A2C0C0C0C0C0C003236161026161610222616102616161610261616102612121214121212121212121212121412121212121","loadword":"","gord-following":true,"jaye":{"y":4,"x":19},"tickword":"","moveword":"","objects":[{"x":7,"func":"term","y":11,"name":"","linkword":"term-dual-link"},{"x":2,"func":"term","y":3,"name":"term-exit","linkword":"","link":1},{"x":7,"func":"term","y":3,"name":"term-scan","linkword":"","link":1},{"x":11,"func":"door","y":7,"name":"","linkword":""},{"x":12,"func":"scan","y":7,"name":"","linkword":"","link":4},{"x":15,"func":"door","y":7,"name":"","linkword":""},{"x":7,"func":"switch","y":7,"name":"","linkword":"","link":3},{"x":10,"func":"door","y":5,"name":"","linkword":""},{"x":10,"func":"switch","y":4,"name":"","linkword":"","link":4},{"x":16,"func":"rexx","y":11,"name":"","linkword":""},{"x":7,"func":"scan","y":2,"name":"","linkword":"","link":8},{"x":1,"func":"scan","y":4,"name":"","linkword":"","link":13},{"x":1,"func":"exitdoor","y":5,"name":"","linkword":"level5"},{"x":5,"func":"rexx","y":8,"name":"","linkword":""},{"x":7,"func":"tutorial-chair","name":"","linkword":"","y":10},{"x":8,"link":6,"func":"switch","linkword":"","name":"","y":7},{"x":6,"link":2,"func":"switch","linkword":"","name":"","y":7}]} \ No newline at end of file diff --git a/game/player.fnl b/game/player.fnl index 61c4b53..b66e394 100644 --- a/game/player.fnl +++ b/game/player.fnl @@ -39,6 +39,7 @@ (vm:word :rexx-active? :rexx-yx :get 0xffff := :not) (vm:word :gord-hidden? :gord-yx :get 0xffff :=) (vm:word :gord-following? :gord-hidden? :gord-sitting :get :| :not) +(vm:word :libb-hidden? :libb-yx :get 0xffff :=) (vm:word :set-rexx ; e -- :dup (vm:if [:get controlstate.rexx] [:drop 0xffff controlstate.neut]) @@ -91,8 +92,8 @@ [:jaye-yx :get vm.false :transition-gord-sitting 0 :gord-dir :set vm.true] [vm.false])) (vm:word :move-noop :drop vm.false) -(vm:word :handle-special-move ; yx -- f - (vm:if-or [[:dup :map-specific-move] [:dup :move-rexx-trash] [:dup :move-gord-sit] [:dup :move-gord-stand]] +(vm:word :handle-general-move ; yx -- f + (vm:if-or [[:dup :map-specific-move] [:dup :move-rexx-trash] [:dup :move-gord-sit] [:dup :move-gord-stand] [:dup :movable-player-flag :flag-at? :not]] [:drop vm.true] [:move-noop])) (vm:def :yxclip? ; yx -- f @@ -110,7 +111,7 @@ (vm:word :try-move-player ; dir -- :dup :set-player-dir ; dir :player-yx :get :yx+ ; yxnew - (vm:if-or [[:dup :yxclip?] [:dup :touch-entity] [:dup :handle-special-move] [:dup :movable-player-flag :flag-at? :not]] + (vm:if-or [[:dup :yxclip?] [:dup :touch-entity] [:dup :handle-general-move]] [:drop :player-yx :get]) ; always "move" so that player can visibly change direction ; touch-entity can modify player-yx so we have to refetch diff --git a/link/mame.fnl b/link/mame.fnl index 5b15eea..01e126b 100644 --- a/link/mame.fnl +++ b/link/mame.fnl @@ -121,7 +121,7 @@ {:value #(tset (. self.breakpoints addr) :id (tonumber $2))})) (fn Machine.clear-bp [self addr] (local bpid (-?> self.breakpoints (. addr) (. :id))) - (when bpid (self:dbgcmd (.. "bpclear " (string.format "%x" bpid)))) + (when bpid (self:dbgcmd (.. "bpclear 0x" (string.format "%x" bpid)))) (tset self.breakpoints addr nil)) (fn Machine.jump [self addr] (self:eval (.. "(tset (. manager.machine.devices ::maincpu :state :PC) :value " (tostring addr) ")"))) diff --git a/todo.txt b/todo.txt index a81657e..25fad05 100644 --- a/todo.txt +++ b/todo.txt @@ -1,3 +1,8 @@ +Game: +* Ending screen +* Intro sequence (how to show earthquake?) + + FLOPPY DISK IDEAS: * I am not going to write my own DOS * I will use ProDOS - BOOTI-compatible, modern @@ -35,11 +40,6 @@ $0800-$0bff 2kb-3kb - text page 2 $0c00-$1fff 3kb-8kb - free space $2000-$4000 8kb-16kb - hgr gfx page 1 -Game: -* fix hot reload :O -* Title screen -* Ending screen - tooling ideas: * REPLy buffer (Polywell?) * save player positions & map state during hot reload