-
Notifications
You must be signed in to change notification settings - Fork 1
/
ai.fs
131 lines (111 loc) · 3.09 KB
/
ai.fs
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
map-width map-height make-nodemap constant ai-nodemap
: build-ai-nodemap { _en -- }
ai-nodemap setup-nodemap-nodes
map-height 0 ?do
map-width 0 ?do
i j get-blocker ?dup-if ( blocker )
_en <> if
i j ai-nodemap at-nodemap ( node )
node-blocked on
then
else
i j map-passable 0= if
i j ai-nodemap at-nodemap
node-blocked on
then
then
loop
loop
;
\ this returns true if move FAILED
: move-towards-using-nodemap { _en _x _y -- flag }
_en build-ai-nodemap
\ make sure the destination tile is not blocked...
_x _y ai-nodemap at-nodemap node-blocked off
_en entity-xy@ _x _y ai-nodemap bfs if ( x y )
_en clear-entity
_en entity-y !
_en entity-x !
false
else true then
;
: ai! { _ai _fn _free-fn _d0 _d1 -- }
_fn _ai ai-fn !
_free-fn _ai ai-free-fn !
_d0 _ai ai-data0 !
_d1 _ai ai-data1 !
;
: add-ai { _en _fn _free-fn _d0 _d1 -- }
_en ['] entity-ai ai% add-component
_fn _free-fn _d0 _d1 ai!
;
:noname ( addr -- )
dup @ ?dup-if ( addr ai )
dup ai-free-fn @ ?dup-if ( addr ai free-fn )
execute ( addr )
else drop then
maybe-free
else drop then
; is maybe-free-ai
: move-towards { _en _x _y -- }
_x _en entity-x @ - sgn ( mx )
_y _en entity-y @ - sgn ( mx my )
over _en entity-x @ + ( mx my dx )
over _en entity-y @ + ( mx my dx dy )
2dup get-blocker if
2drop 2drop exit
then
map-passable if
_en dup clear-entity move-entity
else 2drop then
;
:noname { _en -- }
_en entity-xy@ is-in-fov if
_en entity-xy@
player entity-xy@
distance 1 = if
_en player attack
else
_en
player entity-xy@
move-towards-using-nodemap if
_en player entity-xy@ move-towards
then
then
then
; constant 'basic-ai
: apply-basic-ai ( en -- )
dup entity-ai maybe-free-ai
'basic-ai 0 0 0 add-ai
;
\ confused ai: data0 contains previous ai, data1 contains duration
:noname { _en -- }
_en entity-ai @ ai-data1 @ 0> if
_en _en entity-xy@ ( en ox oy )
swap -1 1 randint + ( en oy dx )
swap -1 1 randint + ( en dx dy )
move-towards
-1 _en entity-ai @ ai-data1 +!
else
_en entity-ai @ dup ( ai ai )
ai-data0 @ _en entity-ai ! ( ai )
free throw
_en announce-confusion-over
then
; constant 'confused-ai
:noname ( ai -- )
ai-data0 maybe-free
; constant 'confused-ai-free
: apply-confused-ai { _en _duration -- }
_en
'confused-ai
'confused-ai-free
_en entity-ai @
0 _en entity-ai ! \ zero old ai
_duration
add-ai
;
: cleanup ( -- )
s" - freeing AI nodemap" logwriteln
ai-nodemap free-nodemap
cleanup ;