2020-11-27 02:34:05 +00:00
|
|
|
(local util (require :lib.util))
|
|
|
|
(local tiles (util.require :game.tiles))
|
2020-11-27 04:46:36 +00:00
|
|
|
(local {: vm : org : itile} (require :game.defs))
|
2020-11-27 02:34:05 +00:00
|
|
|
(local {: lo : hi} util)
|
2020-11-24 04:41:00 +00:00
|
|
|
|
|
|
|
; Entity memory layout:
|
|
|
|
; +0 - yx
|
|
|
|
; +2 - event handler
|
|
|
|
; +4 - link word
|
2020-11-27 02:34:05 +00:00
|
|
|
; +6 - link pointer
|
2020-11-24 04:41:00 +00:00
|
|
|
|
|
|
|
; All entities exist in a single page in RAM - with this structure we can have up to 32
|
|
|
|
; (players are handled specially and never require a link)
|
|
|
|
; if we really need more we could have one page for entities and one page for link data
|
|
|
|
; hellmaze level 2 from MS-DOS Neut Tower has 36 entities - good excuse to simplify IMO
|
|
|
|
; The entity count for a level is stored after the map.
|
|
|
|
|
|
|
|
(local ev {
|
2020-11-29 17:12:18 +00:00
|
|
|
:touch 0
|
|
|
|
:untouch 1
|
|
|
|
:act 2
|
|
|
|
:deact 3
|
|
|
|
:tog 4
|
2020-12-10 14:11:46 +00:00
|
|
|
:noop 5
|
2020-11-24 04:41:00 +00:00
|
|
|
})
|
|
|
|
|
2020-11-27 04:33:14 +00:00
|
|
|
(vm:word :entity-count :lit :map-entity-count :bget)
|
|
|
|
(vm:def :lookup-entity ; i -- entity
|
|
|
|
[:lda vm.TOP :x]
|
|
|
|
[:asl :a] [:asl :a] [:asl :a] ; x8
|
|
|
|
[:sta vm.TOP :x]
|
|
|
|
[:lda #(hi org.entity.org)]
|
|
|
|
[:sta vm.TOPH :x])
|
|
|
|
(vm:word :entity-at ; yx -- entity|0
|
|
|
|
:>r 0 :entity-count
|
|
|
|
(vm:while [:dup] :dec ; entity|0 i
|
|
|
|
:dup :lookup-entity :get :rtop :=
|
|
|
|
(vm:when :lookup-entity :swap)
|
|
|
|
) :drop :rdrop)
|
|
|
|
(vm.code:append :responder [:dw 0])
|
|
|
|
(vm:word :get-responder :lit :responder :get)
|
|
|
|
(vm:word :responder-itile :get-responder :get :itile-at)
|
|
|
|
(vm:word :entity>do ; entity ev --
|
|
|
|
:over :lit :responder :dup :get :>r :set
|
|
|
|
:swap 2 :+ :get :execute
|
|
|
|
:r> :lit :responder :set)
|
|
|
|
|
2020-12-02 13:33:27 +00:00
|
|
|
(vm:word :linked-entity :get-responder :dup 4 :+ :get :dup (vm:if [:execute] [:drop 6 :+ :get]))
|
2020-11-27 04:33:14 +00:00
|
|
|
(vm:word :touch-entity ; yx -- f
|
|
|
|
:entity-at :dup (vm:when ev.touch :entity>do vm.true))
|
2020-11-29 17:12:18 +00:00
|
|
|
(vm:word :untouch-entity ; yx --
|
|
|
|
:entity-at :dup (vm:if [ev.untouch :entity>do] [:drop]))
|
2020-12-02 13:33:27 +00:00
|
|
|
|
2020-11-27 04:33:14 +00:00
|
|
|
(vm:word :set-entitytile ; e itile --
|
|
|
|
:swap :get :swap :update-itile)
|
2020-11-27 02:34:05 +00:00
|
|
|
|
2020-11-27 04:33:14 +00:00
|
|
|
(vm:word :set-respondertile ; itile --
|
|
|
|
:get-responder :get :swap :update-itile)
|
2020-11-27 02:34:05 +00:00
|
|
|
|
2020-11-27 04:33:14 +00:00
|
|
|
(vm:word :handle-onoff ; ev off on --
|
|
|
|
:<rot (vm:case
|
|
|
|
[ev.act :swap :drop :set-respondertile]
|
|
|
|
[ev.deact :drop :set-respondertile]
|
|
|
|
[ev.tog :dup :responder-itile := (vm:if [:drop :set-respondertile] [:set-respondertile :drop])]
|
|
|
|
[:else :drop :drop]))
|
|
|
|
(vm:word :activation-ev? ; ev -- f
|
|
|
|
:dup ev.act := :over ev.deact := :| :swap ev.tog := :|)
|
|
|
|
(vm:word :activate-link ; ev itile-on --
|
|
|
|
:swap :activation-ev? (vm:if [
|
2020-12-02 13:33:27 +00:00
|
|
|
:responder-itile := (vm:if [ev.act] [ev.deact])
|
2020-11-27 04:33:14 +00:00
|
|
|
:linked-entity :swap :entity>do
|
|
|
|
] [:drop]))
|
2020-11-27 02:34:05 +00:00
|
|
|
|
2020-11-27 04:33:14 +00:00
|
|
|
(vm:word :door ; ev --
|
2020-11-29 05:44:23 +00:00
|
|
|
(vm:if-and [[:is-jaye?] [:dup ev.touch :=] [:responder-itile (itile :dooropen) :=]]
|
2020-12-02 13:33:27 +00:00
|
|
|
[:move-to-responder :drop]
|
2020-11-29 05:44:23 +00:00
|
|
|
[(itile :doorclosed) (itile :dooropen) :handle-onoff]))
|
2020-11-27 02:34:05 +00:00
|
|
|
|
2020-12-02 13:33:27 +00:00
|
|
|
(vm:word :move-to-responder :get-responder :get :move-player-to)
|
2020-11-27 04:33:14 +00:00
|
|
|
(vm:word :switch ; ev --
|
2020-12-10 14:11:46 +00:00
|
|
|
(vm:if-and [[:is-rexx? :not] [:dup ev.touch :=]]
|
|
|
|
[:drop ev.tog :is-neut? (vm:when :move-to-responder)])
|
2020-11-27 04:33:14 +00:00
|
|
|
:dup (itile :switchoff) (itile :switchon) :handle-onoff
|
|
|
|
(itile :switchon) :activate-link)
|
2020-11-27 02:34:05 +00:00
|
|
|
|
2020-11-27 04:33:14 +00:00
|
|
|
(vm:word :term ; ev --
|
2020-11-29 05:44:23 +00:00
|
|
|
:dup ev.touch := (vm:when
|
2020-12-02 13:33:27 +00:00
|
|
|
(vm:ifchain [:is-jaye?] [:drop ev.act]
|
|
|
|
[:is-neut?] [:linked-entity
|
|
|
|
(vm:if-and [[:dup :get :itile-at (itile :termon) :=]
|
|
|
|
[:responder-itile (itile :termon) :=]]
|
|
|
|
[:get :move-player-to] [:drop])]
|
|
|
|
[]))
|
|
|
|
(itile :termoff) (itile :termon) :handle-onoff)
|
2020-11-24 04:41:00 +00:00
|
|
|
|
2020-11-29 17:12:18 +00:00
|
|
|
(vm:word :handle-scan ; ev --
|
|
|
|
:dup (itile :scanoff) (itile :scanon) :handle-onoff
|
|
|
|
:linked-entity :swap :entity>do)
|
|
|
|
|
|
|
|
(vm:word :scan ; ev --
|
|
|
|
:is-neut? (vm:if [
|
|
|
|
(vm:case
|
2020-12-02 13:33:27 +00:00
|
|
|
[ev.touch ev.act :handle-scan :move-to-responder]
|
2020-11-29 17:12:18 +00:00
|
|
|
[ev.untouch ev.deact :handle-scan]
|
|
|
|
[:else])
|
|
|
|
] [:drop]))
|
|
|
|
|
2020-12-02 22:19:23 +00:00
|
|
|
(vm:word :rexx ; ev --
|
|
|
|
ev.touch := (vm:when
|
2020-12-10 14:11:46 +00:00
|
|
|
(vm:if-and [[:is-neut?] [:responder-itile (itile :t-rexx) :=]]
|
2020-12-02 22:19:23 +00:00
|
|
|
[0xffff :move-player-to
|
|
|
|
(itile :t-rexxstop) :set-respondertile
|
|
|
|
:get-responder :set-rexx]
|
2020-12-10 14:11:46 +00:00
|
|
|
[(vm:if-and [[:is-rexx?] [:responder-itile (itile :t-rexxstop) :=]]
|
2020-12-02 22:19:23 +00:00
|
|
|
[0xffff :move-player-to
|
|
|
|
(itile :t-rexx) :set-respondertile
|
|
|
|
0 :set-rexx :move-to-responder])])))
|
|
|
|
|
2020-11-24 04:41:00 +00:00
|
|
|
(fn append-from-map [map entity-org]
|
|
|
|
(each [_ entity (ipairs map.objects)]
|
|
|
|
(when entity.name
|
|
|
|
(entity-org:append entity.name))
|
|
|
|
(entity-org:append
|
|
|
|
[:db (- entity.x 1)] [:db (- entity.y 1)]
|
|
|
|
[:ref entity.func]
|
2020-11-27 02:34:05 +00:00
|
|
|
(if (and entity.linkword (> (length entity.linkword) 0)) [:ref entity.linkword] [:dw 0])
|
|
|
|
(if entity.link [:dw (+ entity-org.org (* (- entity.link 1) 8))] [:dw 0]))))
|
2020-11-24 04:41:00 +00:00
|
|
|
|
2020-11-27 04:33:14 +00:00
|
|
|
{: ev : append-from-map}
|
2020-11-24 04:41:00 +00:00
|
|
|
|