-
Notifications
You must be signed in to change notification settings - Fork 1
/
order.rkt
145 lines (127 loc) · 4.69 KB
/
order.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#lang racket/base
(require "defs.rkt"
"utils.rkt")
(provide (all-defined-out))
(define (set-space-orders-for! space faction ot)
(define (pred fo) (not (equal? (car fo) faction)))
(define otherorders (filter pred (space-orders space)))
(if ot
(set-space-orders! space (cons (list faction ot) otherorders))
(set-space-orders! space otherorders)))
(define (get-space-orders-for space faction)
(define fo (findf (lambda (fo) (equal? faction (car fo))) (space-orders space)))
(if fo (cadr fo) #f))
; return a list of chorders
(define (order-changes space order-space)
(define changes '())
; for all orders in order-space, check that the matching faction's orders are the same
(for ((fo (space-orders order-space)))
(define fac (car fo))
(define new (scrub (cadr fo)))
(define old (get-space-orders-for space fac))
(when (not (equal? new old))
(append! changes (chorders fac new))))
; clean up any leftover old orders
(for ((fo (space-orders space)))
(define fac (car fo))
(when (not (get-space-orders-for order-space fac))
(append! changes (chorders fac #f))))
changes)
; client
(define (for-orders ot doall? f)
(let loop ((ot ot) (depth 0) (highlight #t))
(when (and (or doall? (not (ord-done? ot)))
((string-length (ord-text ot)) . > . 0))
(f ot depth (and highlight (not (ord-done? ot)))))
(cond
((ordertime? ot)
(when (ordertime-ot ot)
(loop (ordertime-ot ot) (+ depth 1) highlight))
(ord-done? ot))
((order? ot)
(ord-done? ot))
((equal? 'seq (ordercomb-type ot))
(for/and ((ot (in-list (ordercomb-orders ot))))
(define d (loop ot (+ depth 1) highlight))
(when (not d) (set! highlight #f))
(or doall? d))
highlight)
((equal? 'and (ordercomb-type ot))
(for/fold ((ret #t)) ((ot (in-list (ordercomb-orders ot))))
(define d (loop ot (+ depth 1) highlight))
(and ret d)))
(else
(error "client got an unknown order combinator\n")))))
; replace all order-f with #f so this ordertree can be serialized
(define (scrub ot)
(cond
((ordertime? ot)
(struct-copy ordertime ot
(f #:parent order #f)
(ot (scrub (ordertime-ot ot)))))
((order? ot)
(struct-copy order ot (f #f)))
(else
(struct-copy ordercomb ot
(orders
(for/list ((ot (in-list (ordercomb-orders ot))))
(scrub ot)))))))
; run order functions and update ord-done?
; return #t if all orders are done, and #f if not
; can short circuit
(define (check space faction ot)
(define d
(cond
((order? ot)
(if ((order-f ot) space faction ot)
#t
#f))
((equal? 'seq (ordercomb-type ot))
(for/and ((ot (in-list (ordercomb-orders ot))))
(check space faction ot)))
((equal? 'and (ordercomb-type ot))
(for/and ((ot (in-list (ordercomb-orders ot))))
(check space faction ot)))
(else
(error "check: got an unknown ord\n"))))
(set-ord-done?! ot d)
d)
; make a waypoint scouting order
(define (scout-waypoint text x y r)
(define pv (posvel 0 x y 0 0 0 0))
(define pvo (pvobj x y))
(order #f text (list (ann-circle (next-id) 0 #t 1.0 pv #f #t text r))
(lambda (space faction o)
(for/first ((s (in-list (space-objects space)))
#:when (and (ship? s) ((faction-check faction (ship-faction s)) . > . 0)
((distance pvo s) . < . r)))
(set-order-f! o (lambda (s f o) #t))
#t))))
; kill a particular ship
(define (kill text id)
(order #f text (list (ann-ship (next-id) 0 #t 1.0 #f #f #t text id))
(lambda (space faction o)
(not (find-id space space id)))))
; keep alive
(define (alive text id)
(order #f text (list (ann-ship (next-id) 0 #t 1.0 #f #f #t text id))
(lambda (space faction o)
(find-id space space id))))
; make a timout order
(define (timeout text start total ot)
(define (f space faction o)
(define left (- (ordertime-subtotal o)
(- (space-time space) (ordertime-start o))))
(when (and (left . > . 0)
(not (ord-done? o))
(check space faction (ordertime-ot o)))
; time left and order completed, mark done
(set-ord-done?! o #t)
; don't lock the order so that you can see the time still tick down
)
(when (left . < . 0)
; no time left, lock order and stop countdown
(set-ord-text! o (format (ord-text o) "--:--"))
(set-order-f! o (lambda (s f o) (ord-done? o))))
(ord-done? o))
(ordertime #f text '() f total start ot))