comparison level.pas @ 0:62966dd383ed default tip

initial
author Radomir Dopieralski <sheep-devel@sheep.art.pl>
date Sun, 08 Dec 2013 19:39:15 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:62966dd383ed
1 { Level generating routines. }
2
3 {$Q+R+}
4
5 UNIT Level;
6
7 INTERFACE
8 USES Global;
9
10 PROCEDURE GenerateLevel;
11
12 IMPLEMENTATION
13
14 USES Console, Items, Creature;
15
16 CONST GEN_EMPTY=0; { level generator values }
17 GEN_DOOR=1;
18 GEN_OCCUPY=2;
19
20 TYPE TmpMap=ARRAY[0..MAPXSIZE,0..MAPYSIZE] OF BYTE;
21
22 VAR gen: TmpMap;
23 m: TmpMap;
24
25 PROCEDURE ClearMap;
26 VAR x,y: INTEGER;
27 m: pMap;
28 nothing: TileDef;
29 BEGIN
30 nothing:=FindTile(0);
31 GetMap(playchr^.x,playchr^.y)^.crt:=NIL;
32 FOR y:=0 TO MAPYSIZE DO
33 FOR x:=0 TO MAPXSIZE DO BEGIN
34 m:=GetMap(x,y);
35 IF m^.slt<>NIL THEN BEGIN
36 Dispose(m^.slt);
37 m^.slt:=NIL;
38 END;
39 IF m^.crt<>NIL THEN BEGIN
40 Dispose(m^.crt);
41 m^.crt:=NIL;
42 END;
43 m^.flg:=[];
44 m^.ter:=nothing;
45 END;
46 allmonsters:=NIL;
47 END;
48
49 PROCEDURE GenMap;
50 VAR x,y: INTEGER;
51 BEGIN
52 FOR y:=0 TO MAPYSIZE DO
53 FOR x:=0 TO MAPXSIZE DO BEGIN
54 GetMap(x,y)^.ter:=FindTile(m[x,y]);
55 END;
56 END;
57
58 PROCEDURE GenBack(lev: pLevel);
59 VAR r,i,s,x,y,a,b: INTEGER;
60 frak: TmpMap;
61
62 BEGIN
63 FOR y:=0 TO MAPYSIZE DO
64 FOR x:=0 TO MAPXSIZE DO m[x,y]:=lev^.back[0];
65 END;
66
67 PROCEDURE Erode(lev:pLevel);
68 VAR x,y,r: INTEGER;
69 BEGIN
70 FOR y:=0 TO MAPYSIZE DO
71 FOR x:=0 TO MAPXSIZE DO
72 IF lev^.erosion>Random(100) THEN BEGIN
73 r:=FindTile(m[x,y])^.dst;
74 IF r>0 THEN m[x,y]:=r;
75 END;
76 END;
77
78
79 PROCEDURE GenLevel(lev:pLevel);
80
81 VAR r,i,j,p,x1,y1,x,y: INTEGER;
82 door: BYTE;
83 rom: pRoom;
84 place: BYTE;
85 pmap: tmpmap;
86 tmpplaces: Places;
87
88 FUNCTION TryRoom(x,y: INTEGER; rom: pRoom): BOOLEAN;
89 VAR x1,y1: INTEGER;
90
91
92 BEGIN
93 IF rom=NIL THEN Exit;
94 TryRoom:=FALSE;
95 FOR y1:=0 TO 15 DO FOR x1:=0 TO 15 DO
96 IF (rom^.map[x1,y1]<>GEN_EMPTY) THEN BEGIN
97 IF (NOT InMap(x+x1,y+y1)) THEN Exit;
98 IF (gen[x+x1,y+y1]=GEN_OCCUPY) THEN Exit;
99 END;
100 TryRoom:=TRUE;
101 END;
102
103 PROCEDURE RotateRoom(rom:pRoom);
104 VAR x,y: INTEGER;
105 tmp: ARRAY[0..15,0..15] OF BYTE;
106 BEGIN
107 FOR y:=0 TO 15 DO
108 FOR x:=0 TO 15 DO
109 tmp[x,y]:=rom^.map[y,15-x];
110 FOR y:=0 TO 15 DO
111 FOR x:=0 TO 15 DO
112 rom^.map[x,y]:=tmp[x,y];
113 END;
114
115 PROCEDURE PutDoor(x,y:INTEGER);
116 VAR p: INTEGER;
117
118 BEGIN
119 gen[x,y]:=GEN_OCCUPY;
120 IF door=0 THEN Exit;
121 m[x,y]:=door;
122 END;
123
124
125 PROCEDURE PutRoom(x,y: INTEGER; rom: pRoom);
126 VAR x1,y1: INTEGER;
127 BEGIN
128 IF rom=NIL THEN Exit;
129 IF tmpplaces[place].qnt>0 THEN Dec(tmpplaces[place].qnt);
130 door:=tmpplaces[place].dor;
131 FOR y1:=0 TO 15 DO FOR x1:=0 TO 15 DO
132 IF InMap(x+x1,y+y1) AND (gen[x+x1,y+y1]<>GEN_OCCUPY) THEN BEGIN
133 CASE rom^.map[x1,y1] OF
134 GEN_EMPTY: {nothing};
135 GEN_OCCUPY: gen[x+x1,y+y1]:=GEN_EMPTY;
136 GEN_DOOR: IF gen[x+x1,y+y1]=GEN_EMPTY THEN BEGIN
137 gen[x+x1,y+y1]:=GEN_DOOR;
138 pmap[x+x1,y+y1]:=place;
139 END ELSE BEGIN
140 IF (ROOM_EASYDOOR IN rom^.flg) AND (gen[x+x1,y+y1]=GEN_DOOR) THEN PutDoor(x+x1,y+y1) ELSE
141 gen[x+x1,y+y1]:=GEN_OCCUPY;
142 END;
143 ELSE BEGIN
144 gen[x+x1,y+y1]:=GEN_OCCUPY;
145 m[x+x1,y+y1]:=rom^.map[x1,y1];
146 END;
147 END;
148 END;
149 END;
150
151
152 PROCEDURE NextRoom(x,y: INTEGER);
153 VAR a: INTEGER;
154 BEGIN
155 a:=place;
156 place:=pmap[x1,y1];
157 REPEAT
158 Inc(a);
159 IF a>MAXROOMS THEN a:=1;
160 UNTIL (tmpplaces[place].con[a]<>0) AND (tmpplaces[tmpplaces[place].con[a]].qnt<>0);
161
162 place:=tmpplaces[place].con[a];
163 rom:=FindRoom(tmpplaces[place].rom);
164
165 a:=Random(100);
166 IF (a<70) THEN RotateRoom(rom);
167 END;
168
169 PROCEDURE RandomRoom(x,y: INTEGER);
170 VAR a: INTEGER;
171 BEGIN
172 place:=pmap[x1,y1];
173 a:=Random(MAXROOMS)+1;
174 WHILE (tmpplaces[place].con[a]=0) OR (tmpplaces[tmpplaces[place].con[a]].qnt=0) DO BEGIN
175 Inc(a);
176 IF a>MAXROOMS THEN a:=1;
177 END;
178
179 place:=tmpplaces[place].con[a];
180 rom:=FindRoom(tmpplaces[place].rom);
181
182 a:=Random(100);
183 IF (a<70) THEN RotateRoom(rom);
184 END;
185
186 FUNCTION PickRoom: BOOLEAN;
187 VAR i,j,k,l: INTEGER;
188 BEGIN
189 place:=pmap[x1,y1];
190 door:=tmpplaces[place].dor;
191
192 PickRoom:=FALSE;
193
194 IF tmpplaces[place].con[1]=0 THEN Exit;
195
196 { IF (gen[x1+1,y1]<>GEN_EMPTY) AND
197 (gen[x1-1,y1]<>GEN_EMPTY) AND
198 (gen[x1,y1+1]<>GEN_EMPTY) AND
199 (gen[x1,y1-1]<>GEN_EMPTY) THEN Exit;}
200
201 PickRoom:=TRUE;
202
203 RandomRoom(x1,y1);
204
205
206 FOR k:=1 TO 4 DO BEGIN
207 x:=Random(15);
208 y:=Random(15);
209
210 FOR j:=1 TO 2 DO BEGIN
211 i:=0;
212 REPEAT
213 Inc(x);
214 IF x>15 THEN BEGIN
215 x:=0;
216 Inc(y);
217 IF y>15 THEN y:=0;
218 END;
219 Inc(i);
220 IF (i>200) THEN BEGIN
221 NextRoom(x1,y1);
222 x:=Random(15);
223 y:=Random(15);
224 END;
225 UNTIL (rom^.map[x,y]=GEN_DOOR);
226 IF TryRoom(x1-x,y1-y,rom) THEN Exit;
227 RotateRoom(rom);
228 END;
229 NextRoom(x1,y1);
230 END;
231 PickRoom:=FALSE;
232 END;
233
234
235 BEGIN
236 tmpplaces:=lev^.rooms;
237
238 FOR y:=0 TO MAPYSIZE DO
239 FOR x:=0 TO MAPXSIZE DO BEGIN
240 gen[x,y]:=GEN_EMPTY;
241 pmap[x,y]:=0;
242 END;
243
244 place:=1;
245 rom:=FindRoom(tmpplaces[place].rom);
246 door:=rom^.dor;
247
248
249 Msg('@cTrying first room...');
250 REPEAT
251
252 x:=Random(MAPXSIZE);
253 dec(x,8);
254 y:=Random(MAPYSIZE);
255 dec(y,8);
256 Msg(Concat('@cx=',Num(x),';y=',Num(y)));
257 UNTIL TryRoom(x,y,rom);
258 Msg('@cPutting first room...');
259
260 PutRoom(x,y,rom);
261
262
263 Msg('@cFirst room put...');
264
265 REPEAT
266
267 x1:=Random(MAPXSIZE);
268 y1:=Random(MAPYSIZE);
269
270 i:=0;
271 r:=Random(4);
272 CASE r OF
273 0:WHILE gen[x1,y1]<>GEN_DOOR DO BEGIN
274 Inc(x1);
275 IF x1>MAPXSIZE-1 THEN BEGIN
276 x1:=1;
277 Inc(y1);
278 IF y1>MAPYSIZE-1 THEN y1:=1;
279 END;
280 Inc(i);
281 IF i>MAPXSIZE*MAPYSIZE THEN BEGIN
282
283 Exit;
284 END;
285 END;
286 1:WHILE gen[x1,y1]<>GEN_DOOR DO BEGIN
287 Dec(x1);
288 IF x1<1 THEN BEGIN
289 x1:=MAPXSIZE-1;
290 Dec(y1);
291 IF y1<1 THEN y1:=MAPYSIZE-1;
292 END;
293 Inc(i);
294 IF i>MAPXSIZE*MAPYSIZE THEN BEGIN
295
296 Exit;
297 END;
298 END;
299 2:WHILE gen[x1,y1]<>GEN_DOOR DO BEGIN
300 Inc(y1);
301 IF y1>MAPYSIZE-1 THEN BEGIN
302 y1:=1;
303 Inc(x1);
304 IF x1>MAPXSIZE-1 THEN x1:=1;
305 END;
306 Inc(i);
307 IF i>MAPXSIZE*MAPYSIZE THEN BEGIN
308
309 Exit;
310 END;
311 END;
312 3: WHILE gen[x1,y1]<>GEN_DOOR DO BEGIN
313 Dec(y1);
314 IF y1<1 THEN BEGIN
315 y1:=MAPYSIZE-1;
316 Dec(x1);
317 IF x1<1 THEN x1:=MAPXSIZE-1;
318 END;
319 Inc(i);
320 IF i>MAPXSIZE*MAPYSIZE THEN BEGIN
321
322 Exit;
323 END;
324 END;
325 END;
326
327 Msg('@cPicking room...');
328
329 IF PickRoom THEN BEGIN
330 Msg('@cPutting room...');
331 PutDoor(x1,y1);
332 PutRoom(x1-x,y1-y,rom);
333 END ELSE BEGIN
334 gen[x1,y1]:=GEN_EMPTY;
335 END;
336
337 UNTIL FALSE;
338 END;
339
340
341 PROCEDURE GenerateLevel;
342 VAR x,y,i,a,b: INTEGER;
343 l: pLevel;
344 p: pCreat;
345 BEGIN
346 ClearMap;
347 l:=FindLevel(pc.lev);
348 Msg(Replace(msgs[12],'@v',l^.name));
349 GenBack(l);
350 Msg('@cGenerated back...');
351 GenLevel(l);
352 Msg('@cGenerated rooms...');
353 Erode(l);
354 Msg('@cEroded...');
355 GenMap;
356
357 FOR y:=0 TO MAPYSIZE DO
358 FOR x:=0 TO MAPXSIZE DO BEGIN
359 IF (TILE_ENTER IN GetMap(x,y)^.ter^.flg) THEN BEGIN
360 p:=playchr;
361 MoveMonster(x,y,p);
362 END;
363 END;
364 Inc(pc.lev);
365 END;
366
367
368 END.