Skip to content

Instantly share code, notes, and snippets.

@carloscm
Created October 21, 2015 11:01
Show Gist options
  • Save carloscm/e0b3c099188d57ebc0eb to your computer and use it in GitHub Desktop.
Save carloscm/e0b3c099188d57ebc0eb to your computer and use it in GitHub Desktop.
(define-mod-export job-logistic-sm (state-machine
(start pre-check)
(args job-giver state-component phase)
(vars
work-ticks 0)
(state basic-info
(vars
state-component-c (ecs-get-component job-giver state-component)
job-giver-info (and state-component-c (state-component-c 'job-logistic-info))
resource-p (job-next-required-resource job-giver state-component)
required-resource (and resource-p (car resource-p))
required-amount (and resource-p (cdr resource-p))
; required-resource (and job-giver-info (job-giver-info 'required-resource))
; required-amount (and job-giver-info (job-giver-info 'required-amount))
busyc (ecs-get-component job-giver BusyComponent_Kind)
item (and busyc (ecs-deref (job-giver #@world) (busyc 'item-ref)))
own-item (and item (ecs-busy-with? item job-giver))
worker (ecs-busy-subject job-giver)
own-worker (and worker (ecs-busy-with? worker job-giver))
held-p (and own-worker required-resource (ItemHeldBy (job-giver #@world) worker required-resource))
held (if (persisting-null? held-p) #f held-p)
held-itemc (and held (ecs-get-component held ItemComponent_Kind))
held-amount (if held-itemc (held-itemc #@amount) 0)
remaining (and required-amount (if held-itemc (- required-amount held-amount) required-amount))
enough (or
(not required-resource)
(and required-amount required-resource
(if (<= required-amount -1)
(> held-amount 0)
(>= held-amount required-amount))))
))
(state cleanup
(extend basic-info)
(to pre-check #t
(set! work-ticks 0)
(when own-item (ecs-remove-component item BusyComponent_Kind))
(when own-worker (ecs-remove-component worker BusyComponent_Kind))
(ecs-remove-component job-giver BusyComponent_Kind)
;(job-reset-resources job-giver state-component)
(ecs-remove-component job-giver (job-giver-info 'job-component))
(break)))
(state pre-check
(to wait-for-resources #t))
(state must-have-findable-resource
(extend basic-info)
; pre-check to not advertise the job when it is impossible to perform
(vars
center (ecs-preferred-center job-giver)
any-item (and required-resource (ecs-query (job-giver #@world)
must: (list ItemComponent_Kind (required-resource #@hashed))
exclude: (list ChildComponent_Kind BusyComponent_Kind)
single: #t
path-from: center)))
(to cleanup (and (not any-item) required-resource)))
(state wait-for-resources
(to wait-for-resources-anywhere #t
(job-try-consume-neighbor-stacks job-giver state-component)))
(state wait-for-resources-anywhere
(extend must-have-findable-resource)
(to wait-for-worker (or any-item (not required-resource))
(ecs-make-add-component job-giver (job-giver-info 'job-component)))
(to wait-for-resources (and (not any-item) required-resource)
(break)))
(state wait-for-worker
(extend must-have-findable-resource)
(to find-item own-worker)
(to wait-for-worker (not own-worker)
(break)))
(state must-own-worker
(extend basic-info)
(to cleanup (not own-worker)))
(state find-item
(extend must-own-worker)
(vars
center (ecs-preferred-center job-giver)
found-item (and (not enough) (ecs-query (job-giver #@world)
must: (list ItemComponent_Kind (required-resource #@hashed))
exclude: (list ChildComponent_Kind BusyComponent_Kind)
single: #t
by-distance: center
path-from: center)))
(to walk-to-item (and (not enough) found-item)
(set! ((ecs-get-component job-giver BusyComponent_Kind) 'item-ref) (ecs-ref found-item))
(ecs-make-busy found-item job-giver removeCompOnInvalid: #t)
(ecs-walk-to worker (ecs-pos-center found-item)))
(to walk-to-job-giver enough
(ecs-walk-to worker center))
(to cleanup (and (not enough) (not found-item))))
(state must-own-worker-item
(extend must-own-worker)
(to cleanup (not own-item)))
(state walk-to-item
(extend must-own-worker-item)
(vars
over-item (ecs-intersect-boundary? worker item)
center (ecs-pos-center item)
walking (ecs-has-component? worker PathComponent_Kind)
max-carry-c (ecs-get-component worker MaxCarryComponent_Kind)
max-carry (if max-carry-c (max-carry-c #@maxCarry) 1000)
pick-amount (if (> remaining 0) remaining max-carry)
picked-p (and over-item center (ItemPickPos (job-giver #@world)
(center 0)
(center 1)
required-resource
pick-amount))
picked (and picked-p (if (persisting-null? picked-p) #f picked-p)))
(to find-item picked
; take care of found stack, if still existing, so deref again
([ item (and busyc (ecs-deref (job-giver #@world) (busyc 'item-ref))) ]
(when item
(ecs-remove-component item BusyComponent_Kind)))
(set! (busyc 'item-ref) #f)
; take care of picked stack
(ecs-remove-component picked BusyComponent_Kind)
(ItemDepositInHeldBy (job-giver #@world) worker picked))
(to cleanup (and (not over-item) (not walking))))
(state walk-to-job-giver
(extend must-own-worker)
(vars
walking (ecs-has-component? worker PathComponent_Kind)
center (ecs-preferred-center job-giver)
obj-center (ecs-pos-center job-giver)
over-center (ecs-intersect-point? worker center))
(to deliver-item over-center
(ecs-remove-component worker PathComponent_Kind)
(ecs-phys-stop worker)
(ecs-phys-heading-current worker obj-center 0.0)
(ecs-pose worker "action"))
(to cleanup (and (not over-center) (not walking))))
(state deliver-item
(extend must-own-worker)
(to wait-for-resources held
(ecs-pose worker "action" #f)
(job-consume-resource job-giver state-component held))
(to pre-perform-job (not required-resource)))
(state pre-perform-job
(to perform-job #t))
(state perform-job
(extend must-own-worker)
(vars
center (ecs-preferred-center job-giver)
over-center (ecs-intersect-point? worker center)
done (>= work-ticks (job-giver-info 'duration)))
(to perform-job (and (not done) over-center)
(set! work-ticks (+ work-ticks phase))
(break))
(to finalize done
(job-reset-resources job-giver state-component)
(ecs-pose worker "action" #f))
(to cleanup (not over-center)))
(state finalize
(to end #t))
))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment