mirror of
https://github.com/open-goal/jak-project
synced 2026-07-11 23:30:16 -04:00
637990314b
Closes #736 --------- Co-authored-by: Hat Kid <6624576+Hat-Kid@users.noreply.github.com>
924 lines
31 KiB
Common Lisp
924 lines
31 KiB
Common Lisp
;;-*-Lisp-*-
|
|
(in-package goal)
|
|
|
|
;; name: elevator.gc
|
|
;; name in dgo: elevator
|
|
;; dgos: GAME
|
|
|
|
;; +++elevator-flags
|
|
(defenum elevator-flags
|
|
:type uint64
|
|
:bitfield #t
|
|
(running 0)
|
|
(ef1 1)
|
|
(waiting 2)
|
|
(ef3 3)
|
|
(teleport 4)
|
|
(prevent-jump 5)
|
|
(arrived 6)
|
|
(ef7 7)
|
|
(fence 8)
|
|
(grab 9)
|
|
(dormant 10)
|
|
)
|
|
;; ---elevator-flags
|
|
|
|
|
|
;; +++elevator-status
|
|
(defenum elevator-status
|
|
:type uint64
|
|
:bitfield #t
|
|
(waiting-to-descend)
|
|
(waiting-to-ascend)
|
|
(moving)
|
|
)
|
|
;; ---elevator-status
|
|
|
|
|
|
;; DECOMP BEGINS
|
|
|
|
(deftype elevator-params (structure)
|
|
((xz-threshold float)
|
|
(y-threshold float)
|
|
(start-pos float)
|
|
(move-rate float)
|
|
(flags elevator-flags)
|
|
)
|
|
)
|
|
|
|
|
|
(deftype path-step (structure)
|
|
((next-pos float)
|
|
(dist float)
|
|
)
|
|
)
|
|
|
|
|
|
(deftype path-step-inline-array (inline-array-class)
|
|
((data path-step :inline :dynamic)
|
|
)
|
|
)
|
|
|
|
|
|
(set! (-> path-step-inline-array heap-base) (the-as uint 16))
|
|
|
|
(deftype elevator (base-plat)
|
|
((params elevator-params :inline)
|
|
(path-seq path-step-inline-array)
|
|
(path-dest float)
|
|
(bottom-top float 2)
|
|
(move-pos float 2)
|
|
(move-dist float)
|
|
(path-pos float)
|
|
(path-eased-pos float)
|
|
(ride-timer time-frame)
|
|
(sticky-player-last-ride-time time-frame)
|
|
(elevator-status elevator-status)
|
|
(on-activate pair)
|
|
(on-deactivate pair)
|
|
(on-up pair)
|
|
(on-down pair)
|
|
(on-running pair)
|
|
(on-notice pair)
|
|
(on-wait pair)
|
|
(sound-id sound-id)
|
|
(sound-running-loop sound-spec)
|
|
(sound-arrived sound-spec)
|
|
(fence-prim-index uint32)
|
|
(speed float)
|
|
(sound-start sound-spec)
|
|
(activate-test pair)
|
|
)
|
|
(:state-methods
|
|
dormant
|
|
waiting
|
|
running
|
|
arrived
|
|
unknown
|
|
die
|
|
)
|
|
(:methods
|
|
(calc-dist-between-points! (_type_ int int) none)
|
|
(go-arrived-or-waiting (_type_) none)
|
|
(init-params! (_type_) none)
|
|
(init-sound! (_type_) none)
|
|
(point-inside-shaft? (_type_ vector float float) symbol)
|
|
(elevator-method-46 (_type_) object)
|
|
(elevator-method-47 (_type_) symbol)
|
|
(elevator-method-48 (_type_) none)
|
|
(find-closest-point-in-path! (_type_ vector (pointer float) symbol symbol) symbol)
|
|
(elevator-method-50 (_type_) none)
|
|
(toggle-fence-collision (_type_ symbol) none)
|
|
)
|
|
)
|
|
|
|
|
|
(defmethod point-inside-shaft? ((this elevator) (arg0 vector) (arg1 float) (arg2 float))
|
|
#f
|
|
)
|
|
|
|
(defmethod elevator-method-50 ((this elevator))
|
|
(let ((gp-0 *target*))
|
|
(when gp-0
|
|
(let ((s4-0 (-> gp-0 control collision-spheres 0))
|
|
(s5-0 (new 'stack-no-clear 'collide-query))
|
|
)
|
|
(vector-copy! (-> s5-0 start-pos) (-> s4-0 prim-core world-sphere))
|
|
(+! (-> s5-0 start-pos y) 8192.0)
|
|
(set! (-> s5-0 start-pos w) 1.0)
|
|
(vector-reset! (-> s5-0 move-dist))
|
|
(set! (-> s5-0 move-dist y) -90112.0)
|
|
(let ((v1-6 s5-0))
|
|
(set! (-> v1-6 radius) (-> s4-0 local-sphere w))
|
|
(set! (-> v1-6 collide-with) (collide-spec hit-by-others-list pusher))
|
|
(set! (-> v1-6 ignore-process0) gp-0)
|
|
(set! (-> v1-6 ignore-process1) #f)
|
|
(set! (-> v1-6 ignore-pat) (-> gp-0 control pat-ignore-mask))
|
|
(set! (-> v1-6 action-mask) (collide-action solid))
|
|
)
|
|
(let ((f0-5 (fill-and-probe-using-line-sphere *collide-cache* s5-0)))
|
|
(when (< 0.0 f0-5)
|
|
(vector-float*! (-> s5-0 move-dist) (-> s5-0 move-dist) f0-5)
|
|
(vector+! (-> s5-0 move-dist) (-> s5-0 move-dist) (-> s5-0 start-pos))
|
|
(vector-! (-> s5-0 move-dist) (-> s5-0 move-dist) (-> s4-0 prim-core world-sphere))
|
|
(move-by-vector! (-> gp-0 control) (-> s5-0 move-dist))
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
(none)
|
|
)
|
|
|
|
;; WARN: Return type mismatch object vs none.
|
|
(defmethod toggle-fence-collision ((this elevator) (arg0 symbol))
|
|
(when (and (logtest? (-> this params flags) (elevator-flags fence)) (nonzero? (-> this fence-prim-index)))
|
|
(let ((v1-7 (-> (the-as collide-shape-prim-group (-> this root root-prim)) child (-> this fence-prim-index))))
|
|
(cond
|
|
(arg0
|
|
(set! (-> v1-7 prim-core collide-as) (collide-spec obstacle pusher))
|
|
(set! (-> v1-7 prim-core collide-with) (collide-spec jak player-list))
|
|
(set-setting! 'jump #f 0.0 0)
|
|
)
|
|
(else
|
|
(set! (-> v1-7 prim-core collide-as) (collide-spec))
|
|
(set! (-> v1-7 prim-core collide-with) (collide-spec))
|
|
(remove-setting! 'jump)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
(none)
|
|
)
|
|
|
|
(defmethod deactivate ((this elevator))
|
|
"Make a process dead, clean it up, remove it from the active pool, and return to dead pool."
|
|
(sound-stop (-> this sound-id))
|
|
(call-parent-method this)
|
|
(none)
|
|
)
|
|
|
|
(defmethod init-params! ((this elevator))
|
|
(set! (-> this params xz-threshold) (res-lump-float (-> this entity) 'elevator-xz-threshold :default 81920.0))
|
|
(set! (-> this params y-threshold) (res-lump-float (-> this entity) 'elevator-y-threshold :default 20480.0))
|
|
(set! (-> this params start-pos) (res-lump-float (-> this entity) 'elevator-start-pos))
|
|
(set! (-> this params move-rate) (res-lump-float (-> this entity) 'elevator-move-rate :default 25600.0))
|
|
(set! (-> this params flags) (res-lump-value
|
|
(-> this entity)
|
|
'elevator-flags
|
|
elevator-flags
|
|
:default (the-as uint128 1)
|
|
:time -1000000000.0
|
|
)
|
|
)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
(defun ease-value-in-out ((arg0 float) (arg1 float))
|
|
(let* ((f0-0 arg1)
|
|
(f4-0 (- 1.0 arg1))
|
|
(f3-0 (/ f0-0 (- 1.0 f4-0)))
|
|
(f2-1 (square f0-0))
|
|
(f1-6 (+ (* 2.0 f0-0 (- f4-0 f0-0)) f2-1))
|
|
(f1-7 (+ (* (- 1.0 f4-0) (- 1.0 f4-0) f3-0) f1-6))
|
|
)
|
|
(/ (cond
|
|
((< arg0 f0-0)
|
|
(* arg0 arg0)
|
|
)
|
|
((< arg0 f4-0)
|
|
(+ (* 2.0 f0-0 (- arg0 f0-0)) f2-1)
|
|
)
|
|
(else
|
|
(- f1-7 (* (square (- 1.0 arg0)) f3-0))
|
|
)
|
|
)
|
|
f1-7
|
|
)
|
|
)
|
|
)
|
|
|
|
;; WARN: disable def twice: 11. This may happen when a cond (no else) is nested inside of another conditional, but it should be rare.
|
|
(defbehavior elevator-event elevator ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
|
|
(case arg2
|
|
(('status?)
|
|
(and (= (the float (/ (the-as int (-> arg3 param 0)) 8)) (-> self move-pos 0))
|
|
(= (the float (/ (the-as int (-> arg3 param 1)) 8)) (-> self move-pos 1))
|
|
)
|
|
)
|
|
(('ridden)
|
|
(let ((v1-8 (handle->process (-> (the-as focus (-> arg3 param 0)) handle))))
|
|
(if (= (-> v1-8 type) target)
|
|
(set-time! (-> self sticky-player-last-ride-time))
|
|
)
|
|
)
|
|
#t
|
|
)
|
|
(('use-camera)
|
|
(if (-> arg3 param 0)
|
|
(set-setting! 'entity-name (-> arg3 param 0) 0.0 0)
|
|
(remove-setting! 'entity-name)
|
|
)
|
|
)
|
|
(('move-to)
|
|
(when (and (-> self next-state) (let ((v1-20 (-> self next-state name)))
|
|
(or (= v1-20 'waiting) (= v1-20 'arrived))
|
|
)
|
|
)
|
|
(set! (-> self move-pos 0) (-> self move-pos 1))
|
|
(cond
|
|
((not (logtest? (-> arg3 param 0) 7))
|
|
(set! (-> self move-pos 1) (the-as float (as-type (-> arg3 param 0) float)))
|
|
)
|
|
(else
|
|
(case (-> arg3 param 0)
|
|
(('quote 'bottom)
|
|
(set! (-> self move-pos 1) (-> self bottom-top 0))
|
|
)
|
|
(('quote 'top)
|
|
(set! (-> self move-pos 1) (-> self bottom-top 1))
|
|
)
|
|
)
|
|
)
|
|
)
|
|
(go-virtual running)
|
|
)
|
|
)
|
|
(('jump-to)
|
|
(cond
|
|
((not (logtest? (-> arg3 param 0) 7))
|
|
(set! (-> self move-pos 1) (the-as float (as-type (-> arg3 param 0) float)))
|
|
)
|
|
(else
|
|
(case (-> arg3 param 0)
|
|
(('quote 'bottom)
|
|
(set! (-> self move-pos 1) (-> self bottom-top 0))
|
|
)
|
|
(('quote 'top)
|
|
(set! (-> self move-pos 1) (-> self bottom-top 1))
|
|
)
|
|
)
|
|
)
|
|
)
|
|
(set! (-> self move-pos 0) (-> self move-pos 1))
|
|
(get-point-in-path! (-> self path) (-> self basetrans) (-> self move-pos 0) 'interp)
|
|
(go-virtual waiting)
|
|
)
|
|
(('trigger)
|
|
(when (and (-> self next-state) (let ((v1-48 (-> self next-state name)))
|
|
(or (= v1-48 'waiting) (= v1-48 'arrived))
|
|
)
|
|
)
|
|
(set! (-> self move-pos 0) (-> self move-pos 1))
|
|
(cond
|
|
((= (-> self move-pos 0) (-> self bottom-top 0))
|
|
(set! (-> self move-pos 1) (-> self bottom-top 1))
|
|
)
|
|
((= (-> self move-pos 0) (-> self bottom-top 1))
|
|
(set! (-> self move-pos 1) (-> self bottom-top 0))
|
|
)
|
|
)
|
|
(go-virtual running)
|
|
)
|
|
)
|
|
(('query)
|
|
(case (-> arg3 param 0)
|
|
(('waiting?)
|
|
(and (-> self next-state) (= (-> self next-state name) 'waiting))
|
|
)
|
|
(('arrived?)
|
|
(and (-> self next-state) (let ((v1-61 (-> self next-state name)))
|
|
(or (= v1-61 'arrived) (= v1-61 'waiting))
|
|
)
|
|
)
|
|
)
|
|
(('running?)
|
|
(and (-> self next-state) (= (-> self next-state name) 'running))
|
|
)
|
|
(('path-pos?)
|
|
(+ (-> self move-pos 0) (* (-> self path-pos) (- (-> self move-pos 1) (-> self move-pos 0))))
|
|
)
|
|
(('player-standing-on?)
|
|
(= (-> self sticky-player-last-ride-time) (current-time))
|
|
)
|
|
(('point-inside-shaft?)
|
|
(point-inside-shaft? self (the-as vector (-> arg3 param 1)) (-> self bottom-top 1) (-> self bottom-top 0))
|
|
)
|
|
(('going-down?)
|
|
(< (-> (get-point-in-path! (-> self path) (new 'stack-no-clear 'vector) (-> self move-pos 1) 'interp) y)
|
|
(-> (get-point-in-path! (-> self path) (new 'stack-no-clear 'vector) (-> self move-pos 0) 'interp) y)
|
|
)
|
|
)
|
|
(('going-up?)
|
|
(< (-> (get-point-in-path! (-> self path) (new 'stack-no-clear 'vector) (-> self move-pos 0) 'interp) y)
|
|
(-> (get-point-in-path! (-> self path) (new 'stack-no-clear 'vector) (-> self move-pos 1) 'interp) y)
|
|
)
|
|
)
|
|
(('bottom?)
|
|
(= (-> self move-pos 1) (-> self bottom-top 0))
|
|
)
|
|
(('top?)
|
|
(= (-> self move-pos 1) (-> self bottom-top 1))
|
|
)
|
|
)
|
|
)
|
|
(('reset)
|
|
(go-virtual die)
|
|
)
|
|
(('go-dormant)
|
|
(go-virtual dormant)
|
|
)
|
|
(('set-path-pos)
|
|
(set! (-> self path-pos) (the-as float (-> arg3 param 0)))
|
|
)
|
|
(else
|
|
(plat-event arg0 arg1 arg2 arg3)
|
|
)
|
|
)
|
|
)
|
|
|
|
(defmethod find-closest-point-in-path! ((this elevator) (arg0 vector) (arg1 (pointer float)) (arg2 symbol) (arg3 symbol))
|
|
(let ((s1-0 (-> this params))
|
|
(f28-0 0.0)
|
|
(f30-0 -1.0)
|
|
)
|
|
(dotimes (s0-0 (-> this path curve num-cverts))
|
|
(let ((sv-32 (get-point-in-path! (-> this path) (new 'stack-no-clear 'vector) (the float s0-0) 'interp)))
|
|
(when (and (or (not arg2) (< (vector-vector-xz-distance sv-32 arg0) (-> s1-0 xz-threshold)))
|
|
(or (not arg3)
|
|
(< (fabs (- (-> sv-32 y) (-> arg0 y))) (-> s1-0 y-threshold))
|
|
(and (= s0-0 (the int (-> this bottom-top 0))) (< (-> arg0 y) (-> sv-32 y)))
|
|
(and (= s0-0 (the int (-> this bottom-top 1))) (< (-> sv-32 y) (-> arg0 y)))
|
|
)
|
|
)
|
|
(let ((f0-12 (vector-vector-distance sv-32 arg0)))
|
|
(when (or (= f30-0 -1.0) (< f0-12 f28-0))
|
|
(set! f28-0 f0-12)
|
|
(set! f30-0 (the float s0-0))
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
(when (!= f30-0 -1.0)
|
|
(set! (-> arg1 0) f30-0)
|
|
#t
|
|
)
|
|
)
|
|
)
|
|
|
|
(defmethod elevator-method-46 ((this elevator))
|
|
(let ((a0-2 (the-as target (as-type *target* process-focusable))))
|
|
(and a0-2 (point-inside-shaft? this (get-trans a0-2 0) (-> this move-pos 0) (-> this move-pos 1)))
|
|
)
|
|
)
|
|
|
|
(defmethod elevator-method-47 ((this elevator))
|
|
#t
|
|
)
|
|
|
|
(defmethod elevator-method-48 ((this elevator))
|
|
(let ((a0-1 *target*))
|
|
(when (and a0-1
|
|
(not (logtest? (focus-status dead inactive in-air grabbed edge-grab pole pilot-riding pilot teleporting)
|
|
(-> a0-1 focus-status)
|
|
)
|
|
)
|
|
)
|
|
(let ((sv-16 (the-as float 0.0)))
|
|
(when (and (find-closest-point-in-path! this (get-trans a0-1 0) (& sv-16) #t #t) (!= (-> this move-pos 1) sv-16))
|
|
(set! (-> this move-pos 0) (-> this move-pos 1))
|
|
(set! (-> this move-pos 1) sv-16)
|
|
(logior! (-> this elevator-status) (elevator-status moving))
|
|
(go (method-of-object this running))
|
|
)
|
|
)
|
|
)
|
|
)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
(defbehavior move-post elevator ()
|
|
(when (nonzero? (-> self sound))
|
|
(let ((f0-3 (sqrtf (sin-rad (* 3.1415925 (-> self path-pos))))))
|
|
(update-vol! (-> self sound) f0-3)
|
|
)
|
|
(update-trans! (-> self sound) (-> self root trans))
|
|
(update! (-> self sound))
|
|
)
|
|
(plat-post)
|
|
(none)
|
|
)
|
|
|
|
;; WARN: Return type mismatch vector vs none.
|
|
(defbehavior teleport-check elevator ()
|
|
(when (and *target* (logtest? (-> self params flags) (elevator-flags teleport)) (focus-test? *target* teleporting))
|
|
(let ((sv-16 (the-as float 0.0)))
|
|
(when (find-closest-point-in-path! self (target-pos 0) (& sv-16) #f #t)
|
|
(set! (-> self move-pos 0) sv-16)
|
|
(set! (-> self move-pos 1) sv-16)
|
|
(get-point-in-path! (-> self path) (-> self basetrans) sv-16 'interp)
|
|
)
|
|
)
|
|
)
|
|
(none)
|
|
)
|
|
|
|
(defstate dormant (elevator)
|
|
:virtual #t
|
|
:event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
|
|
(case message
|
|
(('trigger)
|
|
(go-virtual waiting)
|
|
)
|
|
(('bonk)
|
|
#f
|
|
)
|
|
(else
|
|
(plat-event proc argc message block)
|
|
)
|
|
)
|
|
)
|
|
:trans plat-trans
|
|
:code sleep-code
|
|
:post plat-post
|
|
)
|
|
|
|
(defstate waiting (elevator)
|
|
:virtual #t
|
|
:event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
|
|
(case message
|
|
(('ridden)
|
|
(if (elevator-method-47 self)
|
|
(logior! (-> self elevator-status) (elevator-status waiting-to-descend))
|
|
)
|
|
(elevator-event proc argc message block)
|
|
)
|
|
(else
|
|
(elevator-event proc argc message block)
|
|
)
|
|
)
|
|
)
|
|
:enter (behavior ()
|
|
(if (logtest? (-> self params flags) (elevator-flags dormant))
|
|
(go-virtual dormant)
|
|
)
|
|
(set-time! (-> self ride-timer))
|
|
(logclear! (-> self elevator-status) (elevator-status waiting-to-descend moving))
|
|
(logior! (-> self mask) (process-mask actor-pause))
|
|
(if (nonzero? (-> self sound))
|
|
(update-vol! (-> self sound) 0.0)
|
|
)
|
|
(let ((gp-0 (-> self on-notice)))
|
|
(if gp-0
|
|
(script-eval gp-0 :key (* (the int (-> self move-pos 0)) 8) :vector (-> self root trans))
|
|
)
|
|
)
|
|
)
|
|
:trans (behavior ()
|
|
(teleport-check)
|
|
(plat-trans)
|
|
(when (not (logtest? (-> self elevator-status) (elevator-status waiting-to-descend)))
|
|
(set-time! (-> self ride-timer))
|
|
(-> self params)
|
|
(if (and (logtest? (-> self params flags) (elevator-flags running))
|
|
(not (logtest? (-> self params flags) (elevator-flags ef3)))
|
|
)
|
|
(elevator-method-48 self)
|
|
)
|
|
)
|
|
(when (and (not (logtest? (-> self params flags) (elevator-flags ef3)))
|
|
(time-elapsed? (-> self ride-timer) (seconds 1))
|
|
(or (not (-> self activate-test))
|
|
(script-eval (-> self activate-test) :key (* (the int (-> self move-pos 0)) 8) :vector (-> self root trans))
|
|
)
|
|
)
|
|
(set! (-> self move-pos 0) (-> self move-pos 1))
|
|
(set! (-> self move-pos 1) (-> self path-seq data (the int (-> self move-pos 1)) next-pos))
|
|
(go-virtual running)
|
|
)
|
|
(let ((gp-0 (-> self on-wait)))
|
|
(if gp-0
|
|
(script-eval gp-0 :key (* (the int (-> self move-pos 0)) 8) :vector (-> self root trans))
|
|
)
|
|
)
|
|
)
|
|
:code sleep-code
|
|
:post (behavior ()
|
|
(logclear! (-> self elevator-status) (elevator-status waiting-to-descend))
|
|
(debug-draw (-> self path))
|
|
(plat-post)
|
|
)
|
|
)
|
|
|
|
(defstate running (elevator)
|
|
:virtual #t
|
|
:event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
|
|
(case message
|
|
(('running?)
|
|
#t
|
|
)
|
|
(('player-ridden?)
|
|
(logtest? (-> self elevator-status) (elevator-status waiting-to-descend))
|
|
)
|
|
(else
|
|
(elevator-event proc argc message block)
|
|
)
|
|
)
|
|
)
|
|
:enter (behavior ()
|
|
(if (not (logtest? (-> self params flags) (elevator-flags ef7)))
|
|
(process-entity-status! self (entity-perm-status no-kill) #t)
|
|
)
|
|
(logclear! (-> self elevator-status) (elevator-status waiting-to-ascend))
|
|
(when (logtest? (-> self params flags) (elevator-flags waiting))
|
|
(logclear! (-> self params flags) (elevator-flags waiting))
|
|
(logior! (-> self params flags) (elevator-flags running))
|
|
)
|
|
(set! (-> self move-dist) 0.0)
|
|
(let ((v1-13 (the int (-> self move-pos 0)))
|
|
(a0-3 (the int (-> self move-pos 1)))
|
|
(a1-1 0)
|
|
)
|
|
(while (let ((a2-3 (abs (- a0-3 v1-13))))
|
|
(< a1-1 a2-3)
|
|
)
|
|
(+! (-> self move-dist) (-> self path-seq data (+ (min v1-13 a0-3) a1-1) dist))
|
|
(+! a1-1 1)
|
|
)
|
|
)
|
|
(logclear! (-> self mask) (process-mask actor-pause))
|
|
(set! (-> self path-pos) 0.0)
|
|
(if (nonzero? (-> self sound))
|
|
(update-vol! (-> self sound) 0.0)
|
|
)
|
|
(if (-> self sound-start)
|
|
(sound-play-by-spec (-> self sound-start) (new-sound-id) (the-as vector #t))
|
|
)
|
|
(when (logtest? (-> self params flags) (elevator-flags prevent-jump))
|
|
(set-setting! 'jump #f 0.0 0)
|
|
(apply-settings *setting-control*)
|
|
)
|
|
(when (logtest? (-> self elevator-status) (elevator-status waiting-to-descend))
|
|
(set-setting! 'board #f 0.0 0)
|
|
(set-setting! 'lightjak #f 0.0 0)
|
|
(toggle-fence-collision self #t)
|
|
(if (logtest? (-> self params flags) (elevator-flags grab))
|
|
(process-grab? *target* #f)
|
|
)
|
|
)
|
|
(let ((gp-1 (-> self on-activate)))
|
|
(if gp-1
|
|
(script-eval gp-1 :key (* (the int (-> self move-pos 0)) 8) :vector (-> self root trans))
|
|
)
|
|
)
|
|
)
|
|
:exit (behavior ()
|
|
(if (not (logtest? (-> self params flags) (elevator-flags ef7)))
|
|
(process-entity-status! self (entity-perm-status no-kill) #f)
|
|
)
|
|
(remove-setting! 'board)
|
|
(remove-setting! 'jump)
|
|
(remove-setting! 'lightjak)
|
|
(set! (-> self speed) 0.0)
|
|
)
|
|
:trans (behavior ()
|
|
(teleport-check)
|
|
(if (and (not (logtest? (-> self elevator-status) (elevator-status waiting-to-ascend)))
|
|
(= (-> self path-pos) 1.0)
|
|
)
|
|
(go-virtual arrived)
|
|
)
|
|
(if (elevator-method-46 self)
|
|
(set! (-> self path-dest) 0.0)
|
|
(set! (-> self path-dest) 1.0)
|
|
)
|
|
(if (and (logtest? (-> self params flags) (elevator-flags grab))
|
|
(and *target* (not (logtest? (-> *target* focus-status) (focus-status grabbed))))
|
|
)
|
|
(process-grab? *target* #f)
|
|
)
|
|
(if (and (logtest? (-> self elevator-status) (elevator-status waiting-to-descend)) *target*)
|
|
(process-drawable-cloth-command *target* '(set-flags local-space-y))
|
|
)
|
|
(if (>= (+ (current-time) (seconds -1)) (-> self sticky-player-last-ride-time))
|
|
(remove-setting! 'board)
|
|
(set-setting! 'board #f 0.0 0)
|
|
)
|
|
(if (logtest? (-> self params flags) (elevator-flags prevent-jump))
|
|
(elevator-method-50 self)
|
|
)
|
|
(let ((gp-0 (-> self on-running)))
|
|
(if gp-0
|
|
(script-eval gp-0 :key (* (the int (-> self move-pos 0)) 8) :vector (-> self root trans))
|
|
)
|
|
)
|
|
(plat-trans)
|
|
)
|
|
:code (behavior ()
|
|
(logior! (-> self elevator-status) (elevator-status waiting-to-ascend))
|
|
(suspend)
|
|
(let ((a1-0 (new 'stack-no-clear 'event-message-block)))
|
|
(set! (-> a1-0 from) (process->ppointer self))
|
|
(set! (-> a1-0 num-params) 1)
|
|
(set! (-> a1-0 message) 'query)
|
|
(set! (-> a1-0 param 0) (the-as uint 'player-standing-on?))
|
|
(cond
|
|
((and (send-event-function self a1-0)
|
|
(let ((a1-1 (new 'stack-no-clear 'event-message-block)))
|
|
(set! (-> a1-1 from) (process->ppointer self))
|
|
(set! (-> a1-1 num-params) 1)
|
|
(set! (-> a1-1 message) 'query)
|
|
(set! (-> a1-1 param 0) (the-as uint 'going-up?))
|
|
(and (send-event-function self a1-1) (logtest? (-> self params flags) (elevator-flags fence)))
|
|
)
|
|
)
|
|
(let ((gp-0 (-> self on-up)))
|
|
(if gp-0
|
|
(script-eval gp-0 :key (* (the int (-> self move-pos 0)) 8) :vector (-> self root trans))
|
|
)
|
|
)
|
|
)
|
|
((let ((a1-4 (new 'stack-no-clear 'event-message-block)))
|
|
(set! (-> a1-4 from) (process->ppointer self))
|
|
(set! (-> a1-4 num-params) 1)
|
|
(set! (-> a1-4 message) 'query)
|
|
(set! (-> a1-4 param 0) (the-as uint 'player-standing-on?))
|
|
(and (send-event-function self a1-4)
|
|
(let ((a1-5 (new 'stack-no-clear 'event-message-block)))
|
|
(set! (-> a1-5 from) (process->ppointer self))
|
|
(set! (-> a1-5 num-params) 1)
|
|
(set! (-> a1-5 message) 'query)
|
|
(set! (-> a1-5 param 0) (the-as uint 'going-down?))
|
|
(and (send-event-function self a1-5) (logtest? (-> self params flags) (elevator-flags fence)))
|
|
)
|
|
)
|
|
)
|
|
(let ((gp-1 (-> self on-down)))
|
|
(if gp-1
|
|
(script-eval gp-1 :key (* (the int (-> self move-pos 0)) 8) :vector (-> self root trans))
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
(until #f
|
|
(suspend)
|
|
(if (= (-> self path-pos) 1.0)
|
|
(logclear! (-> self elevator-status) (elevator-status waiting-to-ascend))
|
|
)
|
|
)
|
|
#f
|
|
)
|
|
:post (behavior ()
|
|
(when (logtest? (-> self elevator-status) (elevator-status waiting-to-ascend))
|
|
(seek!
|
|
(-> self path-pos)
|
|
(-> self path-dest)
|
|
(* (/ (-> self params move-rate) (-> self move-dist)) (seconds-per-frame))
|
|
)
|
|
(let* ((f30-0 (-> self move-pos 0))
|
|
(f28-0 (-> self move-pos 1))
|
|
(f0-9 (+ f30-0 (* (ease-value-in-out (-> self path-pos) 0.08) (- f28-0 f30-0))))
|
|
(gp-0 (new 'stack-no-clear 'vector))
|
|
)
|
|
(vector-copy! gp-0 (-> self basetrans))
|
|
(get-point-in-path! (-> self path) (-> self basetrans) f0-9 'interp)
|
|
(set! (-> self speed) (* (- (-> self basetrans y) (-> gp-0 y)) (-> self clock frames-per-second)))
|
|
)
|
|
(if (-> self sound-running-loop)
|
|
(sound-play-by-spec (-> self sound-running-loop) (-> self sound-id) (-> self root trans))
|
|
)
|
|
)
|
|
(move-post)
|
|
)
|
|
)
|
|
|
|
(defstate arrived (elevator)
|
|
:virtual #t
|
|
:event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
|
|
(case message
|
|
(('ridden)
|
|
(set-time! (-> self ride-timer))
|
|
(elevator-event proc argc message block)
|
|
)
|
|
(else
|
|
(elevator-event proc argc message block)
|
|
)
|
|
)
|
|
)
|
|
:enter (behavior ()
|
|
(set-time! (-> self ride-timer))
|
|
(if (not (-> *setting-control* user-current jump))
|
|
(remove-setting! 'jump)
|
|
)
|
|
(sound-stop (-> self sound-id))
|
|
(if (-> self sound-arrived)
|
|
(sound-play-by-spec (-> self sound-arrived) (new-sound-id) (the-as vector #t))
|
|
)
|
|
(when (logtest? (-> self elevator-status) (elevator-status waiting-to-descend))
|
|
(toggle-fence-collision self #f)
|
|
(if (and (logtest? (-> self params flags) (elevator-flags grab)) *target* (focus-test? *target* grabbed))
|
|
(process-release? *target*)
|
|
)
|
|
)
|
|
(let ((gp-1 (-> self on-deactivate)))
|
|
(if gp-1
|
|
(script-eval gp-1 :key (* (the int (-> self move-pos 1)) 8) :vector (-> self root trans))
|
|
)
|
|
)
|
|
)
|
|
:trans (behavior ()
|
|
(teleport-check)
|
|
(if (and (< (- (-> self ride-timer) (-> self sticky-player-last-ride-time)) (seconds 2))
|
|
(begin *target* *target*)
|
|
(focus-test? *target* in-air)
|
|
)
|
|
(set-time! (-> self ride-timer))
|
|
)
|
|
(if (and (logtest? (-> self params flags) (elevator-flags grab)) *target* (focus-test? *target* grabbed))
|
|
(process-release? *target*)
|
|
)
|
|
(when (or (logtest? (-> self elevator-status) (elevator-status moving))
|
|
(time-elapsed? (-> self ride-timer) (seconds 0.5))
|
|
)
|
|
(cond
|
|
((and (logtest? (-> self params flags) (elevator-flags ef1))
|
|
(!= (-> self move-pos 1) (-> self params start-pos))
|
|
)
|
|
(set! (-> self move-pos 0) (-> self move-pos 1))
|
|
(set! (-> self move-pos 1) (-> self params start-pos))
|
|
(go-virtual running)
|
|
)
|
|
(else
|
|
(go-virtual waiting)
|
|
)
|
|
)
|
|
)
|
|
(plat-trans)
|
|
)
|
|
:code sleep-code
|
|
:post plat-post
|
|
)
|
|
|
|
(defstate die (elevator)
|
|
:virtual #t
|
|
:event (the-as (function process int symbol event-message-block object) eco-door-event-handler)
|
|
:code (behavior ()
|
|
'()
|
|
)
|
|
)
|
|
|
|
(defmethod calc-dist-between-points! ((this elevator) (arg0 int) (arg1 int))
|
|
(set! (-> this path-seq data arg0 next-pos) (the float arg1))
|
|
(let ((s3-0 (get-point-in-path! (-> this path) (new 'stack-no-clear 'vector) (the float arg0) 'interp))
|
|
(a1-3 (get-point-in-path! (-> this path) (new 'stack-no-clear 'vector) (the float arg1) 'interp))
|
|
)
|
|
(set! (-> this path-seq data arg0 dist) (vector-vector-distance s3-0 a1-3))
|
|
)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
(defmethod init-sound! ((this elevator))
|
|
(set! (-> this sound) (the-as ambient-sound 0))
|
|
(if (-> this sound-running-loop)
|
|
(set! (-> this sound-id) (new-sound-id))
|
|
)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
(defmethod base-plat-method-34 ((this elevator))
|
|
0
|
|
(none)
|
|
)
|
|
|
|
(defmethod relocate ((this elevator) (offset int))
|
|
(if (nonzero? (-> this path-seq))
|
|
(&+! (-> this path-seq) offset)
|
|
)
|
|
(call-parent-method this offset)
|
|
)
|
|
|
|
;; WARN: Return type mismatch object vs none.
|
|
(defmethod go-arrived-or-waiting ((this elevator))
|
|
(if (logtest? (-> this params flags) (elevator-flags arrived))
|
|
(go (method-of-object this arrived))
|
|
(go (method-of-object this waiting))
|
|
)
|
|
(none)
|
|
)
|
|
|
|
;; WARN: Return type mismatch none vs object.
|
|
(defmethod init-from-entity! ((this elevator) (arg0 entity-actor))
|
|
"Set up a newly created process from the entity that created it."
|
|
(stack-size-set! (-> this main-thread) 1024)
|
|
(set! (-> this sound-running-loop) #f)
|
|
(set! (-> this sound-arrived) #f)
|
|
(set! (-> this sound-start) #f)
|
|
(init-params! this)
|
|
(init-collision! this)
|
|
(when (type? (-> this root root-prim) collide-shape-prim-group)
|
|
(let ((v1-9 (-> this root root-prim)))
|
|
(dotimes (a0-5 (the-as int (-> v1-9 specific 0)))
|
|
(when (= (-> (the-as collide-shape-prim-group v1-9) child a0-5 prim-id) (shl #xfe00 16))
|
|
(set! (-> this fence-prim-index) (the-as uint a0-5))
|
|
(toggle-fence-collision this #f)
|
|
#t
|
|
(goto cfg-8)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
(label cfg-8)
|
|
(process-drawable-from-entity! this arg0)
|
|
(initialize-skeleton this (the-as skeleton-group (get-art-group this)) (the-as pair 0))
|
|
(init-bounce-params! this)
|
|
(set! (-> this elevator-status) (elevator-status))
|
|
(update-transforms (-> this root))
|
|
(base-plat-method-33 this)
|
|
(set! (-> this on-activate) (res-lump-struct (-> this entity) 'on-activate pair))
|
|
(set! (-> this on-deactivate) (res-lump-struct (-> this entity) 'on-deactivate pair))
|
|
(set! (-> this on-up) (res-lump-struct (-> this entity) 'on-up pair))
|
|
(set! (-> this on-down) (res-lump-struct (-> this entity) 'on-down pair))
|
|
(set! (-> this on-running) (res-lump-struct (-> this entity) 'on-running pair))
|
|
(set! (-> this on-notice) (res-lump-struct (-> this entity) 'on-notice pair))
|
|
(set! (-> this on-wait) (res-lump-struct (-> this entity) 'on-wait pair))
|
|
(set! (-> this activate-test) (res-lump-struct (-> this entity) 'activate-test pair))
|
|
(set! (-> this path) (new 'process 'path-control this 'path 0.0 arg0 #f))
|
|
(when (logtest? (-> this path flags) (path-control-flag not-found))
|
|
(if (logtest? (-> this params flags) (elevator-flags dormant))
|
|
(go (method-of-object this dormant))
|
|
)
|
|
(go process-drawable-art-error "error in path")
|
|
)
|
|
(logior! (-> this path flags) (path-control-flag display draw-line draw-point draw-text))
|
|
(let ((s5-1 (-> this path curve num-cverts))
|
|
(s4-1 0)
|
|
(f30-0 0.0)
|
|
(f28-0 0.0)
|
|
)
|
|
(set! (-> this path-seq) (new 'process 'path-step-inline-array s5-1))
|
|
(dotimes (s3-1 s5-1)
|
|
(calc-dist-between-points! this s3-1 (mod (+ s3-1 1) s5-1))
|
|
(let ((v1-55 (get-point-in-path! (-> this path) (new 'stack-no-clear 'vector) (the float s3-1) 'interp)))
|
|
(when (or (not (logtest? s4-1 1)) (< (-> v1-55 y) f28-0))
|
|
(set! (-> this bottom-top 0) (the float s3-1))
|
|
(set! f28-0 (-> v1-55 y))
|
|
(set! s4-1 (logior s4-1 1))
|
|
)
|
|
(when (or (not (logtest? s4-1 2)) (< f30-0 (-> v1-55 y)))
|
|
(set! (-> this bottom-top 1) (the float s3-1))
|
|
(set! f30-0 (-> v1-55 y))
|
|
(set! s4-1 (logior s4-1 2))
|
|
)
|
|
)
|
|
)
|
|
)
|
|
(let ((sv-32 (the-as float 0.0))
|
|
(sv-36 (-> this path))
|
|
)
|
|
(let ((sv-40 (the-as target (as-type *target* process-focusable))))
|
|
(if (not (and sv-40
|
|
(logtest? (-> this params flags) (elevator-flags teleport))
|
|
(find-closest-point-in-path! this (get-trans sv-40 0) (& sv-32) #f #t)
|
|
)
|
|
)
|
|
(set! sv-32 (-> this params start-pos))
|
|
)
|
|
)
|
|
(set! (-> this move-pos 0) sv-32)
|
|
(set! (-> this move-pos 1) sv-32)
|
|
(get-point-in-path! sv-36 (-> this basetrans) sv-32 'interp)
|
|
)
|
|
(set! (-> this root pause-adjust-distance)
|
|
(+ 122880.0 (-> this params xz-threshold) (total-distance (-> this path)))
|
|
)
|
|
(base-plat-method-34 this)
|
|
(init-sound! this)
|
|
(go-arrived-or-waiting this)
|
|
)
|