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

;; name: guard-conversation.gc
;; name in dgo: guard-conversation
;; dgos: FOR, DG1, FRA, CAS, PAE, FEA, FDB

;; DECOMP BEGINS

(deftype gconv-speech (basic)
  ((name0      basic)
   (name1      basic)
   (hold-time  uint32)
   )
  )


(deftype gconv-dialogue (basic)
  ((speeches  (array gconv-speech))
   )
  )


(deftype gconv-dialogues (basic)
  ((dialogues  (array gconv-dialogue))
   )
  )


(define *gconv-dialogues*
  (new 'static 'gconv-dialogues
    :dialogues (new 'static 'boxed-array :type gconv-dialogue
      (new 'static 'gconv-dialogue
        :speeches (new 'static 'boxed-array :type gconv-speech
          (new 'static 'gconv-speech :name0 "kg186a" :name1 "kg186b" :hold-time #x258)
          (new 'static 'gconv-speech :name0 "kg187a" :name1 "kg187b" :hold-time #x96)
          (new 'static 'gconv-speech :name0 "kg188a" :name1 "kg188b" :hold-time #x12c)
          (new 'static 'gconv-speech :name0 "kg189a" :name1 "kg189b" :hold-time #x258)
          (new 'static 'gconv-speech :name0 "kg190a" :name1 "kg190b")
          )
        )
      (new 'static 'gconv-dialogue
        :speeches (new 'static 'boxed-array :type gconv-speech
          (new 'static 'gconv-speech :name0 "kg222a" :name1 "kg222b" :hold-time #x96)
          (new 'static 'gconv-speech :name0 "kg223a" :name1 "kg223b")
          )
        )
      (new 'static 'gconv-dialogue
        :speeches (new 'static 'boxed-array :type gconv-speech
          (new 'static 'gconv-speech :name0 "kg203a" :name1 "kg203b" :hold-time #x96)
          (new 'static 'gconv-speech :name0 "kg204a" :name1 "kg204b")
          )
        )
      (new 'static 'gconv-dialogue
        :speeches (new 'static 'boxed-array :type gconv-speech
          (new 'static 'gconv-speech :name0 "kg207a" :name1 "kg207b" :hold-time #x4b)
          (new 'static 'gconv-speech :name0 "kg209a" :name1 "kg209b")
          )
        )
      (new 'static 'gconv-dialogue
        :speeches (new 'static 'boxed-array :type gconv-speech
          (new 'static 'gconv-speech :name0 "kg211a" :name1 "kg211b" :hold-time #x87)
          (new 'static 'gconv-speech :name0 "kg212a" :name1 "kg212b" :hold-time #x5a)
          (new 'static 'gconv-speech :name0 "kg213a" :name1 "kg213b")
          )
        )
      (new 'static 'gconv-dialogue
        :speeches (new 'static 'boxed-array :type gconv-speech
          (new 'static 'gconv-speech :name0 "kg179b" :name1 "kg179b" :hold-time #x12c)
          (new 'static 'gconv-speech :name0 "kg180a" :name1 "kg180b")
          )
        )
      (new 'static 'gconv-dialogue
        :speeches (new 'static 'boxed-array :type gconv-speech
          (new 'static 'gconv-speech :name0 "kg181a" :name1 "kg181b" :hold-time #x96)
          (new 'static 'gconv-speech :name0 "kg182a" :name1 "kg182b")
          )
        )
      (new 'static 'gconv-dialogue
        :speeches (new 'static 'boxed-array :type gconv-speech
          (new 'static 'gconv-speech :name0 "kg183a" :name1 "kg183b" :hold-time #x5a)
          (new 'static 'gconv-speech :name0 "kg184a" :name1 "kg184b" :hold-time #x5a)
          (new 'static 'gconv-speech :name0 "kg185a" :name1 "kg185b")
          )
        )
      (new 'static 'gconv-dialogue
        :speeches (new 'static 'boxed-array :type gconv-speech
          (new 'static 'gconv-speech :name0 "kg191a" :name1 "kg191b" :hold-time #x12c)
          (new 'static 'gconv-speech :name0 "kg192a" :name1 "kg192b")
          )
        )
      (new 'static 'gconv-dialogue
        :speeches (new 'static 'boxed-array :type gconv-speech
          (new 'static 'gconv-speech :name0 "kg194a" :name1 "kg194b" :hold-time #x177)
          (new 'static 'gconv-speech :name0 "kg195a" :name1 "kg195b")
          )
        )
      (new 'static 'gconv-dialogue
        :speeches (new 'static 'boxed-array :type gconv-speech
          (new 'static 'gconv-speech :name0 "kg197a" :name1 "kg197b" :hold-time #xd2)
          (new 'static 'gconv-speech :name0 "kg198a" :name1 "kg198b" :hold-time #x96)
          (new 'static 'gconv-speech :name0 "kg199a" :name1 "kg199b")
          )
        )
      (new 'static 'gconv-dialogue
        :speeches (new 'static 'boxed-array :type gconv-speech
          (new 'static 'gconv-speech :name0 "kg200a" :name1 "kg200b" :hold-time #x96)
          (new 'static 'gconv-speech :name0 "kg201a" :name1 "kg201b" :hold-time #x177)
          (new 'static 'gconv-speech :name0 "kg202a" :name1 "kg202b")
          )
        )
      (new 'static 'gconv-dialogue
        :speeches (new 'static 'boxed-array :type gconv-speech
          (new 'static 'gconv-speech :name0 "kg205a" :name1 "kg205b" :hold-time #x12c)
          (new 'static 'gconv-speech :name0 "kg206a" :name1 "kg206b")
          )
        )
      (new 'static 'gconv-dialogue
        :speeches (new 'static 'boxed-array :type gconv-speech
          (new 'static 'gconv-speech :name0 "kg214a" :name1 "kg214b" :hold-time #x96)
          (new 'static 'gconv-speech :name0 "kg215a" :name1 "kg215b" :hold-time #x78)
          (new 'static 'gconv-speech :name0 "kg216a" :name1 "kg216b" :hold-time #x78)
          (new 'static 'gconv-speech :name0 "kg217a" :name1 "kg217b")
          )
        )
      (new 'static 'gconv-dialogue
        :speeches (new 'static 'boxed-array :type gconv-speech
          (new 'static 'gconv-speech :name0 "kg218a" :name1 "kg218b" :hold-time #x12c)
          (new 'static 'gconv-speech :name0 "kg219a" :name1 "kg219b")
          )
        )
      (new 'static 'gconv-dialogue
        :speeches (new 'static 'boxed-array :type gconv-speech
          (new 'static 'gconv-speech :name0 "kg220a" :name1 "kg220b" :hold-time #x96)
          (new 'static 'gconv-speech :name0 "kg221a" :name1 "kg221b")
          )
        )
      (new 'static 'gconv-dialogue
        :speeches (new 'static 'boxed-array :type gconv-speech
          (new 'static 'gconv-speech :name0 "kg226a" :name1 "kg226b" :hold-time #x96)
          (new 'static 'gconv-speech :name0 "kg227a" :name1 "kg227b" :hold-time #xe1)
          (new 'static 'gconv-speech :name0 "kg228a" :name1 "kg228b" :hold-time #x258)
          (new 'static 'gconv-speech :name0 "kg229a" :name1 "kg229b")
          )
        )
      (new 'static 'gconv-dialogue
        :speeches (new 'static 'boxed-array :type gconv-speech
          (new 'static 'gconv-speech :name0 "kg230a" :name1 "kg230b" :hold-time #x12c)
          (new 'static 'gconv-speech :name0 "kg231a" :name1 "kg231b" :hold-time #xe1)
          (new 'static 'gconv-speech :name0 "kg232a" :name1 "kg232b")
          )
        )
      (new 'static 'gconv-dialogue
        :speeches (new 'static 'boxed-array :type gconv-speech
          (new 'static 'gconv-speech :name0 "kg233a" :name1 "kg233b" :hold-time #x96)
          (new 'static 'gconv-speech :name0 "kg234a" :name1 "kg234b" :hold-time #x96)
          (new 'static 'gconv-speech :name0 "kg235a" :name1 "kg235b")
          )
        )
      (new 'static 'gconv-dialogue
        :speeches (new 'static 'boxed-array :type gconv-speech (new 'static 'gconv-speech :name0 "kg210a" :name1 "kg210b"))
        )
      (new 'static 'gconv-dialogue
        :speeches (new 'static 'boxed-array :type gconv-speech
          (new 'static 'gconv-speech :name0 "kg224a" :name1 "kg224b" :hold-time #x96)
          (new 'static 'gconv-speech :name0 "kg225a" :name1 "kg225b")
          )
        )
      )
    )
  )

(deftype guard-conversation (process-drawable)
  ((triggered?         symbol)
   (actor-group        actor-group)
   (actor-count        int8)
   (remaining          int8)
   (skip-mask          uint32)
   (last-playing-time  time-frame)
   )
  (:state-methods
    dormant
    active
    notice
    die
    )
  (:methods
    (guard-conversation-method-24 (_type_) symbol)
    )
  )


(defmethod guard-conversation-method-24 ((this guard-conversation))
  (let ((v1-0 (-> this remaining)))
    (when (> v1-0 0)
      (set! (-> this remaining) (+ v1-0 -1))
      (let* ((s3-0 (rand-vu-int-count-excluding 32 (the-as int (-> this skip-mask))))
             (s5-0 (-> *gconv-dialogues* dialogues s3-0 speeches))
             (s4-1 (zero? (rand-vu-int-count 2)))
             )
        (logior! (-> this skip-mask) (ash 1 s3-0))
        (dotimes (s3-1 (-> s5-0 length))
          (let* ((v1-9 (-> s5-0 s3-1))
                 (t0-0 (if s4-1
                           (-> v1-9 name0)
                           (-> v1-9 name1)
                           )
                       )
                 )
            (add-process
              *gui-control*
              this
              (gui-channel guard)
              (gui-action play)
              (the-as string t0-0)
              -99.0
              (the-as time-frame (-> v1-9 hold-time))
              )
            )
          (set! s4-1 (not s4-1))
          )
        )
      #f
      )
    )
  )

(defstate dormant (guard-conversation)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('trigger)
       (set! (-> self triggered?) #t)
       (go-virtual active)
       )
      (('untrigger)
       (set! (-> self triggered?) #f)
       #f
       )
      )
    )
  :code sleep-code
  )

(defstate active (guard-conversation)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('trigger)
       (let ((v0-0 #t))
         (set! (-> self triggered?) v0-0)
         v0-0
         )
       )
      (('untrigger)
       (set! (-> self triggered?) #f)
       #f
       )
      )
    )
  :trans (behavior ()
    (let ((gp-0 #t))
      (countdown (s5-0 (-> self actor-count))
        (let ((v1-3 (-> self actor-group data s5-0 actor)))
          (when (not (logtest? (-> v1-3 extra perm status) (entity-perm-status dead)))
            (set! gp-0 #f)
            (let ((a0-4 (if v1-3
                            (-> v1-3 extra process)
                            )
                        )
                  )
              (when a0-4
                (if (nonzero? (-> (the-as nav-enemy a0-4) focus aware))
                    (go-virtual notice)
                    )
                )
              )
            )
          )
        )
      (if gp-0
          (go-virtual die)
          )
      )
    (if (nonzero? (get-status
                    *gui-control*
                    (lookup-gui-connection-id *gui-control* (the-as string #f) (gui-channel guard) (gui-action none))
                    )
                  )
        (set-time! (-> self last-playing-time))
        )
    (if (and (-> self triggered?) (time-elapsed? (-> self last-playing-time) (seconds 6)))
        (guard-conversation-method-24 self)
        )
    )
  :code sleep-code
  )

(defstate notice (guard-conversation)
  :virtual #t
  :code (behavior ()
    (set-action!
      *gui-control*
      (gui-action stop)
      (the-as sound-id 1)
      (gui-channel guard)
      (gui-action none)
      (the-as string #f)
      (the-as (function gui-connection symbol) #f)
      (the-as process #f)
      )
    (let ((v1-2 (rand-vu-int-count 3)))
      (add-process
        *gui-control*
        self
        (gui-channel guard)
        (gui-action play)
        (cond
          ((zero? v1-2)
           "kg137"
           )
          ((= v1-2 1)
           "kg152"
           )
          (else
            "kg160"
            )
          )
        -99.0
        0
        )
      )
    (until (= (get-status
                *gui-control*
                (lookup-gui-connection-id *gui-control* (the-as string #f) (gui-channel guard) (gui-action none))
                )
              (gui-status unknown)
              )
      (suspend)
      )
    (go-virtual die)
    )
  )

(defstate die (guard-conversation)
  :virtual #t
  :code (behavior ()
    (process-entity-status! self (entity-perm-status bit-12) #t)
    (process-entity-status! self (entity-perm-status dead) #t)
    (suspend)
    0
    )
  )

;; WARN: Return type mismatch object vs none.
(defmethod init-from-entity! ((this guard-conversation) (arg0 entity-actor))
  "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that.
This commonly includes things such as:
- stack size
- collision information
- loading the skeleton group / bones
- sounds"
  (local-vars (sv-16 res-tag))
  (set! (-> this triggered?) #f)
  (set! (-> this root) (new 'process 'trsqv))
  (process-drawable-from-entity! this arg0)
  (let ((v1-2 (res-lump-value (-> this entity) 'extra-id uint128 :time -1000000000.0)))
    (let ((a1-4 (-> *gconv-dialogues* dialogues length))
          (a0-6 0)
          )
      (dotimes (a2-1 31)
        (when (logtest? v1-2 (ash 1 a2-1))
          (if (< a2-1 a1-4)
              (+! a0-6 1)
              (set! v1-2 (logxor v1-2 (the-as uint (ash 1 a2-1))))
              )
          )
        )
      (set! (-> this remaining) a0-6)
      )
    (set! (-> this skip-mask) (the-as uint (lognot v1-2)))
    )
  (let ((s5-1 (and (-> this entity) (logtest? (-> this entity extra perm status) (entity-perm-status bit-12)))))
    (set! sv-16 (new 'static 'res-tag))
    (let ((s4-0 (res-lump-data (-> this entity) 'actor-groups (pointer actor-group) :tag-ptr (& sv-16))))
      (if (or (not s4-0) (zero? (-> sv-16 elt-count)))
          (go process-drawable-art-error "missing actors")
          )
      (let* ((s4-1 (-> s4-0 0))
             (s3-0 (-> s4-1 length))
             )
        (set! (-> this actor-group) s4-1)
        (set! (-> this actor-count) s3-0)
        (if (!= s3-0 2)
            (go process-drawable-art-error "bad actor count")
            )
        (dotimes (s2-0 s3-0)
          (let ((s1-0 (-> s4-1 data s2-0 actor)))
            (if (not s1-0)
                (go process-drawable-art-error "bad actor")
                )
            (cond
              ((logtest? (-> s1-0 extra perm status) (entity-perm-status dead))
               (set! s5-1 #t)
               )
              (else
                (let ((v1-28 (if s1-0
                                 (-> s1-0 extra process)
                                 )
                             )
                      )
                  (if (and v1-28 (nonzero? (-> (the-as nav-enemy v1-28) focus aware)))
                      (set! s5-1 #t)
                      )
                  )
                )
              )
            )
          )
        )
      )
    (if s5-1
        (go (method-of-object this die))
        (go (method-of-object this dormant))
        )
    )
  (none)
  )
