-
Notifications
You must be signed in to change notification settings - Fork 4
/
CellAuto.Mod
191 lines (167 loc) · 3.36 KB
/
CellAuto.Mod
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
MODULE CellAuto;
IMPORT Base, Objects,Out:=KernelLog;
TYPE PT=Base.PT;
Ray = Base.Ray;
Path=Base.Path;
Voxel = Base.Voxel;
Name = Base.Name;
CONST
GREEN='g';
BLUE='b';
RED='r';
N=1000;
TYPE CAVox*=OBJECT(Voxel)
VAR
center*: PT; (* in world coordinates! *)
delta*: REAL;
PROCEDURE step;
END step;
END CAVox;
TYPE FuseVox*=OBJECT(CAVox)
VAR
greenf,burning1*, burning2*, burnt*: BOOLEAN;
color:CHAR;
PROCEDURE set(p:PT; size: INTEGER);
BEGIN
color:=GREEN;
greenf:=TRUE;
center.x:=(ENTIER(p.x*size))/size + 1/(2*size);
center.y:=(ENTIER(p.y*size))/size + 1/(2*size);
center.z:=(ENTIER(p.z*size))/size + 1/(2*size);
delta:=0.55/size;
END set;
PROCEDURE fire*;
BEGIN
IF greenf THEN
greenf:=FALSE;
burning1:=TRUE;
Engine.push(SELF)
END;
END fire;
PROCEDURE probe*(p:PT; resolution: INTEGER):Voxel;
BEGIN
fire;
Out.String("fire!");
RETURN(SELF)
END probe;
PROCEDURE passprobe*(p: PT):BOOLEAN;
BEGIN
fire;
RETURN(FALSE);
END passprobe;
PROCEDURE stroke*(p:PT; resolution: INTEGER; voxel:Voxel);
BEGIN
fire
END stroke;
PROCEDURE step*;
VAR
v: Voxel
BEGIN
IF burning1 THEN
v:=Base.world.probe(Base.mkPT(center.x+delta,center.y,center.z),1000);
v:=Base.world.probe(Base.mkPT(center.x-delta,center.y,center.z),1000);
v:=Base.world.probe(Base.mkPT(center.x,center.y+delta,center.z),1000);
v:=Base.world.probe(Base.mkPT(center.x,center.y-delta,center.z),1000);
v:=Base.world.probe(Base.mkPT(center.x,center.y,center.z+delta),1000);
v:=Base.world.probe(Base.mkPT(center.x,center.y,center.z-delta),1000);
burning1:=FALSE;
burning2:=TRUE;
color:=RED;
anonyhook;
Engine.push(SELF);
ELSIF burning2 THEN
burning2:=FALSE;
color:=GREEN;
greenf:=TRUE
END;
END step;
PROCEDURE Shade*(VAR ray: Ray);
BEGIN
CASE color OF
GREEN: gren.Shade(ray)
| RED: rd.Shade(ray)
| BLUE: blu.Shade(ray)
ELSE
gren.Shade(ray)
END
END Shade;
PROCEDURE anonyhook;
BEGIN
END anonyhook;
END FuseVox;
TYPE GroVox*=OBJECT(FuseVox)
PROCEDURE anonyhook;
VAR
v: Voxel;
g:GroVox;
path: Path;
BEGIN
v:=Base.world.probe(Base.mkPT(center.x,center.y,center.z-delta),1000);
IF (v=NIL) OR v.passable THEN
NEW(g);
center.z:=center.z-delta;
g.set(center,Base.avatarsize);
g.burning2:=TRUE;
Base.world.stroke(center,Base.avatarsize, g);
END
END anonyhook;
END GroVox;
TYPE GateFuseVox*=OBJECT(FuseVox)
PROCEDURE step;
VAR
v: Voxel
BEGIN
IF burning1 THEN
v:=Base.world.probe(Base.mkPT(center.x+delta,center.y,center.z),1000);;
burning1:=FALSE;
burning2:=TRUE;
CASE color OF
GREEN: color:=RED
| RED: color:=BLUE
| BLUE: color:=GREEN
END;
Engine.push(SELF)
ELSIF burning2 THEN
burning2:=FALSE;
greenf:=TRUE
END
END step;
PROCEDURE Shade (VAR ray: Ray);
BEGIN
CASE color OF
RED: gren.Shade(ray)
| BLUE: rd.Shade(ray)
| GREEN: blu.Shade(ray)
END
END Shade;
END GateFuseVox;
TYPE CAEngine=OBJECT
VAR
Front, F2: ARRAY N OF CAVox;
fn,i: INTEGER;
PROCEDURE push(v: CAVox);
BEGIN
IF fn<N-1 THEN F2[fn]:=v; INC(fn) END
END push;
PROCEDURE tick*;
VAR i,n: INTEGER;
BEGIN
FOR i:=0 TO fn-1 DO
Front[i]:=F2[i]
END;
n:=fn;
fn:=0;
FOR i:=0 TO n-1 DO
Front[i].step;
END;
END tick
END CAEngine;
VAR
Engine*: CAEngine;
gren,blu,rd: Voxel;
BEGIN
NEW(Engine);
gren:=Base.VoxelFromName("Ndiffuseblue");
blu:=Base.VoxelFromName("NznGx2ySiHIGrO5t9Pzcw5Q");
rd:=Base.VoxelFromName("NnviGAernhjFK40xASZZVoQ");
END CellAuto.