Files
jak-project/goal_src/jak3/engine/common-obs/elevator.gc
T
water111 637990314b wip: better stack var support (#4222)
Closes #736

---------

Co-authored-by: Hat Kid <6624576+Hat-Kid@users.noreply.github.com>
2026-04-19 00:14:44 +02:00

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)
)