;;-*-Lisp-*-
(in-package goal)

;; name: w-parking-spot.gc
;; name in dgo: w-parking-spot
;; dgos: LPATK, LFACCAR, WASALL

;; DECOMP BEGINS

(deftype w-parking-spot (process-drawable)
  ((vehicle          handle)
   (should-spawn?    symbol)
   (should-cleanup?  symbol)
   (v-type           game-vehicle-u8)
   (minimap          connection-minimap)
   (test-sphere      sphere  :inline)
   (arrow            handle)
   )
  (:state-methods
    idle
    )
  (:methods
    (w-parking-spot-method-21 (_type_) none)
    (w-parking-spot-method-22 (_type_) none)
    (w-parking-spot-method-23 (_type_) none)
    (w-parking-spot-method-24 (_type_) none)
    (w-parking-spot-method-25 (_type_) symbol)
    (w-parking-spot-method-26 (_type_) int)
    )
  )


(defmethod w-parking-spot-method-24 ((this w-parking-spot))
  (let ((gp-0 (new 'stack-no-clear 'cquery-with-5vec)))
    (set! (-> gp-0 vec 0 quad) (-> this root trans quad))
    (vector-copy! (-> gp-0 cquery start-pos) (-> gp-0 vec 0))
    (vector-reset! (-> gp-0 vec 1))
    (set! (-> gp-0 vec 1 y) 1.0)
    (vector-z-quaternion! (-> gp-0 vec 2) (-> this root quat))
    (set! (-> gp-0 vec 2 y) 0.0)
    (vector-normalize! (-> gp-0 vec 2) 1.0)
    (set-vector! (-> gp-0 cquery move-dist) 0.0 -40960.0 0.0 1.0)
    (let ((v1-6 (-> gp-0 cquery)))
      (set! (-> v1-6 radius) 1024.0)
      (set! (-> v1-6 collide-with) (collide-spec backgnd))
      (set! (-> v1-6 ignore-process0) #f)
      (set! (-> v1-6 ignore-process1) #f)
      (set! (-> v1-6 ignore-pat)
            (new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noendlessfall #x1 :board #x1)
            )
      (set! (-> v1-6 action-mask) (collide-action solid))
      )
    (let ((f30-0 (fill-and-probe-using-line-sphere *collide-cache* (-> gp-0 cquery))))
      (when (>= f30-0 0.0)
        (vector+float*! (-> gp-0 vec 0) (-> gp-0 cquery start-pos) (-> gp-0 cquery move-dist) f30-0)
        (vector-copy! (-> gp-0 vec 1) (-> gp-0 cquery best-other-tri normal))
        (when (< (-> gp-0 vec 1 y) (cos 3640.889))
          (vector-reset! (-> gp-0 vec 1))
          (set! (-> gp-0 vec 1 y) 1.0)
          )
        (vector-copy! (-> this root trans) (-> gp-0 vec 0))
        (format #t "w-parking-spot::find-ground: ground y ~M~%" (-> gp-0 vec 0 y))
        )
      (if (< f30-0 0.0)
          (format #t "w-parking-spot::find-ground: could not find ground~%")
          )
      )
    (vector-copy! (-> this root trans) (-> gp-0 vec 0))
    (forward-up-nopitch->quaternion (-> this root quat) (-> gp-0 vec 2) (-> gp-0 vec 1))
    )
  0
  (none)
  )

(defmethod w-parking-spot-method-25 ((this w-parking-spot))
  (let ((v1-1 (handle->process (-> this vehicle))))
    (if v1-1
        (or (focus-test? (the-as vehicle v1-1) dead inactive)
            (not (logtest? (vehicle-flag waiting-for-player) (-> (the-as vehicle v1-1) v-flags)))
            (let ((f0-0 (-> this test-sphere r)))
              (< (* f0-0 f0-0) (vector-vector-distance-squared (-> (the-as vehicle v1-1) root trans) (-> this test-sphere)))
              )
            (let ((v1-5 *target*))
              (when v1-5
                (if (focus-test? v1-5 pilot-riding)
                    (= (-> v1-5 pilot vehicle) (-> this vehicle))
                    )
                )
              )
            )
        )
    )
  )

(defmethod w-parking-spot-method-21 ((this w-parking-spot))
  (let ((s5-0 (handle->process (-> this vehicle))))
    (cond
      (s5-0
        (cond
          ((w-parking-spot-method-25 this)
           (logclear! (-> (the-as vehicle s5-0) v-flags) (vehicle-flag persistent))
           (set! (-> this vehicle) (the-as handle #f))
           )
          ((and (nonzero? (-> *setting-control* user-current vehicles))
                (have-vehicle-v-type? (the-as vehicle-type (-> this v-type)))
                )
           (when (not (handle->process (-> this arrow)))
             (let ((s5-1 (new 'stack-no-clear 'task-arrow-params)))
               (vector-copy! (-> s5-1 pos) (-> this root trans))
               (quaternion-identity! (-> s5-1 quat))
               (set! (-> s5-1 flags) (task-arrow-flags taf8))
               (set! (-> s5-1 map-icon) (the-as uint 12))
               (set! (-> this arrow) (process->handle (task-arrow-spawn s5-1 this)))
               )
             )
           )
          (else
            (let ((a0-21 (handle->process (-> this arrow))))
              (if a0-21
                  (send-event a0-21 'leave)
                  )
              )
            )
          )
        )
      (else
        (let ((a0-25 (handle->process (-> this arrow))))
          (if a0-25
              (send-event a0-25 'leave)
              )
          )
        )
      )
    )
  0
  (none)
  )

(defmethod w-parking-spot-method-23 ((this w-parking-spot))
  (let ((v1-0 #t)
        (s5-0 (the-as uint (-> this v-type)))
        )
    (if (= (the-as game-vehicle-u8 s5-0) (game-vehicle-u8 v-scorpion v-toad v-fox))
        (set! s5-0 (the-as uint (-> *game-info* current-vehicle)))
        )
    (when *target*
      (let ((v1-3 (-> *vehicle-info* handle-by-vehicle-type s5-0)))
        (-> *target* pilot)
        (set! v1-0 (not (handle->process v1-3)))
        )
      )
    (when (and v1-0 (!= s5-0 27) *vehicle-manager*)
      (let ((s4-0 (new 'stack 'traffic-object-spawn-params)))
        (set! (-> s4-0 object-type) (traffic-type guard-a))
        (set! (-> s4-0 behavior) (the-as uint 0))
        (set! (-> s4-0 id) (the-as uint 0))
        (set! (-> s4-0 nav-mesh) #f)
        (set! (-> s4-0 nav-branch) #f)
        (set! (-> s4-0 proc) #f)
        (set! (-> s4-0 handle) (the-as handle #f))
        (set! (-> s4-0 user-data) (the-as uint 0))
        (set! (-> s4-0 flags) (traffic-spawn-flags tsf5))
        (set! (-> s4-0 guard-type) (the-as uint 11))
        (set! (-> s4-0 entity) #f)
        (vector-reset! (-> s4-0 velocity))
        (vector-copy! (-> s4-0 position) (-> this root trans))
        (quaternion-copy! (-> s4-0 rotation) (-> this root quat))
        (let ((a0-22 (vehicle-spawn (the-as vehicle-type s5-0) s4-0)))
          (when a0-22
            (set! (-> this vehicle) (process->handle a0-22))
            (set! (-> this should-spawn?) #f)
            )
          )
        )
      )
    )
  0
  (none)
  )

(defmethod w-parking-spot-method-26 ((this w-parking-spot))
  (let ((gp-0 0))
    (let ((v1-1
            (res-lump-value (-> this entity) 'vehicle-type-mask int :default (the-as uint128 4096) :time -1000000000.0)
            )
          )
      (while (not (logtest? v1-1 1))
        (+! gp-0 1)
        (set! v1-1 (the-as int (/ v1-1 2)))
        )
      )
    gp-0
    )
  )

(defmethod init-from-entity! ((this w-parking-spot) (arg0 entity-actor))
  "Set up a newly created process from the entity that created it."
  (set! (-> this root) (new 'process 'trsqv))
  (process-drawable-from-entity! this arg0)
  (logclear! (-> this mask) (process-mask actor-pause movie))
  (set! (-> this minimap) #f)
  (set! (-> this vehicle) (the-as handle #f))
  (set! (-> this arrow) (the-as handle #f))
  (set! (-> this should-spawn?) #t)
  (set! (-> this should-cleanup?) (= (-> this level name) 'wasdoors))
  (set! (-> this v-type) (the-as game-vehicle-u8 (w-parking-spot-method-26 this)))
  (let ((v1-9 (res-lump-struct arg0 'spawn-trans vector)))
    (cond
      (v1-9
        (vector-copy! (-> this root trans) v1-9)
        (let ((a1-5 (res-lump-struct arg0 'spawn-quat structure)))
          (when a1-5
            (quaternion-copy! (-> this root quat) (the-as quaternion a1-5))
            0
            )
          )
        )
      (else
        (w-parking-spot-method-24 this)
        )
      )
    )
  (let ((s5-1 (res-lump-struct (-> this entity) 'on-activate structure)))
    (if s5-1
        (set! (-> this should-spawn?) (the-as symbol (script-eval (the-as pair s5-1))))
        )
    )
  (set! (-> this test-sphere quad) (-> this root trans quad))
  (set! (-> this test-sphere r) 24576.0)
  (set-time! (-> this state-time))
  (go (method-of-object this idle))
  )

(defstate idle (w-parking-spot)
  :virtual #t
  :exit (behavior ()
    (w-parking-spot-method-21 self)
    (if (and (-> self should-cleanup?) (not (w-parking-spot-method-25 self)))
        (send-event (handle->process (-> self vehicle)) 'go-die)
        )
    )
  :code (behavior ()
    (suspend)
    (if (-> self should-spawn?)
        (w-parking-spot-method-23 self)
        )
    (until #f
      (suspend-for (seconds 0.25)
        )
      (w-parking-spot-method-21 self)
      (when (-> self should-spawn?)
        (let ((f0-0 (vector-vector-distance-squared (camera-pos) (-> self test-sphere)))
              (f1-0 327680.0)
              )
          (when (< (* f1-0 f1-0) f0-0)
            (let ((f1-3 614400.0))
              (if (or (< (* f1-3 f1-3) f0-0) (not (sphere-in-view-frustum? (-> self test-sphere))))
                  (w-parking-spot-method-23 self)
                  )
              )
            )
          )
        )
      )
    #f
    (sleep-code)
    )
  :post (behavior ()
    0
    )
  )
