1 /**
2  * @file trigs.cpp
3  *
4  * Implementation of functionality for triggering events when the player enters an area.
5  */
6 #include "all.h"
7 
8 DEVILUTION_BEGIN_NAMESPACE
9 
10 BOOL townwarps[3];
11 BOOL trigflag;
12 int numtrigs;
13 TriggerStruct trigs[MAXTRIGGERS];
14 int TWarpFrom;
15 
16 /** Specifies the dungeon piece IDs which constitute stairways leading down to the cathedral from town. */
17 int TownDownList[] = { 716, 715, 719, 720, 721, 723, 724, 725, 726, 727, -1 };
18 /** Specifies the dungeon piece IDs which constitute stairways leading down to the catacombs from town. */
19 int TownWarp1List[] = { 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1181, 1183, 1185, -1 };
20 int TownCryptList[] = { 1331, 1332, 1333, 1334, 1335, 1336, 1337, 1338, -1 };
21 int TownHiveList[] = { 1307, 1308, 1309, 1310, -1 };
22 /** Specifies the dungeon piece IDs which constitute stairways leading up from the cathedral. */
23 int L1UpList[] = { 127, 129, 130, 131, 132, 133, 135, 137, 138, 139, 140, -1 };
24 /** Specifies the dungeon piece IDs which constitute stairways leading down from the cathedral. */
25 int L1DownList[] = { 106, 107, 108, 109, 110, 112, 114, 115, 118, -1 };
26 /** Specifies the dungeon piece IDs which constitute stairways leading up from the catacombs. */
27 int L2UpList[] = { 266, 267, -1 };
28 /** Specifies the dungeon piece IDs which constitute stairways leading down from the catacombs. */
29 int L2DownList[] = { 269, 270, 271, 272, -1 };
30 /** Specifies the dungeon piece IDs which constitute stairways leading up to town from the catacombs. */
31 int L2TWarpUpList[] = { 558, 559, -1 };
32 /** Specifies the dungeon piece IDs which constitute stairways leading up from the caves. */
33 int L3UpList[] = { 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, -1 };
34 /** Specifies the dungeon piece IDs which constitute stairways leading down from the caves. */
35 int L3DownList[] = { 162, 163, 164, 165, 166, 167, 168, 169, -1 };
36 /** Specifies the dungeon piece IDs which constitute stairways leading up to town from the caves. */
37 int L3TWarpUpList[] = { 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, -1 };
38 /** Specifies the dungeon piece IDs which constitute stairways leading up from hell. */
39 int L4UpList[] = { 82, 83, 90, -1 };
40 /** Specifies the dungeon piece IDs which constitute stairways leading down from hell. */
41 int L4DownList[] = { 120, 130, 131, 132, 133, -1 };
42 /** Specifies the dungeon piece IDs which constitute stairways leading up to town from hell. */
43 int L4TWarpUpList[] = { 421, 422, 429, -1 };
44 /** Specifies the dungeon piece IDs which constitute stairways leading down to Diablo from hell. */
45 int L4PentaList[] = { 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, -1 };
46 int L5TWarpUpList[] = { 172, 173, 174, 175, 176, 177, 178, 179, 184, -1 };
47 int L5UpList[] = { 149, 150, 151, 152, 153, 154, 155, 157, 158, 159, -1 };
48 int L5DownList[] = { 125, 126, 129, 131, 132, 135, 136, 140, 142, -1 };
49 int L6TWarpUpList[] = { 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, -1 };
50 int L6UpList[] = { 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, -1 };
51 int L6DownList[] = { 57, 58, 59, 60, 61, 62, 63, 64, -1 };
52 
InitNoTriggers()53 void InitNoTriggers()
54 {
55 	numtrigs = 0;
56 	trigflag = FALSE;
57 }
58 
InitTownTriggers()59 void InitTownTriggers()
60 {
61 	int i;
62 
63 	numtrigs = 0;
64 
65 	trigs[numtrigs]._tx = 25;
66 	trigs[numtrigs]._ty = 29;
67 	trigs[numtrigs]._tmsg = WM_DIABNEXTLVL;
68 	numtrigs++;
69 
70 	for (i = 0; i < sizeof(townwarps) / sizeof(townwarps[0]); i++) {
71 		townwarps[i] = gbIsMultiplayer && !gbIsSpawn;
72 	}
73 	if (!gbIsSpawn) {
74 		if (gbIsMultiplayer || plr[myplr].pTownWarps & 1 || (gbIsHellfire && plr[myplr]._pLevel >= 10)) {
75 			townwarps[0] = TRUE;
76 			trigs[numtrigs]._tx = 49;
77 			trigs[numtrigs]._ty = 21;
78 			trigs[numtrigs]._tmsg = WM_DIABTOWNWARP;
79 			trigs[numtrigs]._tlvl = 5;
80 #ifdef _DEBUG
81 			if (debug_mode_key_j)
82 				trigs[numtrigs]._tlvl = debug_mode_key_j;
83 #endif
84 			numtrigs++;
85 		}
86 		if (gbIsMultiplayer || plr[myplr].pTownWarps & 2 || (gbIsHellfire && plr[myplr]._pLevel >= 15)) {
87 			townwarps[1] = TRUE;
88 			trigs[numtrigs]._tx = 17;
89 			trigs[numtrigs]._ty = 69;
90 			trigs[numtrigs]._tmsg = WM_DIABTOWNWARP;
91 			trigs[numtrigs]._tlvl = 9;
92 			numtrigs++;
93 		}
94 		if (gbIsMultiplayer || plr[myplr].pTownWarps & 4 || (gbIsHellfire && plr[myplr]._pLevel >= 20)) {
95 			townwarps[2] = TRUE;
96 			trigs[numtrigs]._tx = 41;
97 			trigs[numtrigs]._ty = 80;
98 			trigs[numtrigs]._tmsg = WM_DIABTOWNWARP;
99 			trigs[numtrigs]._tlvl = 13;
100 			numtrigs++;
101 		}
102 	}
103 	if (gbIsHellfire) {
104 		trigs[numtrigs]._tx = 80;
105 		trigs[numtrigs]._ty = 62;
106 		trigs[numtrigs]._tmsg = WM_DIABTOWNWARP;
107 		trigs[numtrigs]._tlvl = 17;
108 		numtrigs++;
109 		if (gbIsMultiplayer || quests[Q_GRAVE]._qactive == 3) {
110 			trigs[numtrigs]._tx = 36;
111 			trigs[numtrigs]._ty = 24;
112 			trigs[numtrigs]._tmsg = WM_DIABTOWNWARP;
113 			trigs[numtrigs]._tlvl = 21;
114 			numtrigs++;
115 		}
116 	}
117 
118 	trigflag = FALSE;
119 }
120 
InitL1Triggers()121 void InitL1Triggers()
122 {
123 	int i, j;
124 
125 	numtrigs = 0;
126 	if (currlevel < 17) {
127 		for (j = 0; j < MAXDUNY; j++) {
128 			for (i = 0; i < MAXDUNX; i++) {
129 				if (dPiece[i][j] == 129) {
130 					trigs[numtrigs]._tx = i;
131 					trigs[numtrigs]._ty = j;
132 					trigs[numtrigs]._tmsg = WM_DIABPREVLVL;
133 					numtrigs++;
134 				}
135 				if (dPiece[i][j] == 115) {
136 					trigs[numtrigs]._tx = i;
137 					trigs[numtrigs]._ty = j;
138 					trigs[numtrigs]._tmsg = WM_DIABNEXTLVL;
139 					numtrigs++;
140 				}
141 			}
142 		}
143 	} else {
144 		for (j = 0; j < MAXDUNY; j++) {
145 			for (i = 0; i < MAXDUNX; i++) {
146 				if (dPiece[i][j] == 184) {
147 					trigs[numtrigs]._tx = i;
148 					trigs[numtrigs]._ty = j;
149 					trigs[numtrigs]._tmsg = WM_DIABTWARPUP;
150 					trigs[numtrigs]._tlvl = 0;
151 					numtrigs++;
152 				}
153 				if (dPiece[i][j] == 158) {
154 					trigs[numtrigs]._tx = i;
155 					trigs[numtrigs]._ty = j;
156 					trigs[numtrigs]._tmsg = WM_DIABPREVLVL;
157 					numtrigs++;
158 				}
159 				if (dPiece[i][j] == 126) {
160 					trigs[numtrigs]._tx = i;
161 					trigs[numtrigs]._ty = j;
162 					trigs[numtrigs]._tmsg = WM_DIABNEXTLVL;
163 					numtrigs++;
164 				}
165 			}
166 		}
167 	}
168 	trigflag = FALSE;
169 }
170 
InitL2Triggers()171 void InitL2Triggers()
172 {
173 	int i, j;
174 
175 	numtrigs = 0;
176 	for (j = 0; j < MAXDUNY; j++) {
177 		for (i = 0; i < MAXDUNX; i++) {
178 			if (dPiece[i][j] == 267 && (i != quests[Q_SCHAMB]._qtx || j != quests[Q_SCHAMB]._qty)) {
179 				trigs[numtrigs]._tx = i;
180 				trigs[numtrigs]._ty = j;
181 				trigs[numtrigs]._tmsg = WM_DIABPREVLVL;
182 				numtrigs++;
183 			}
184 
185 			if (dPiece[i][j] == 559) {
186 				trigs[numtrigs]._tx = i;
187 				trigs[numtrigs]._ty = j;
188 				trigs[numtrigs]._tmsg = WM_DIABTWARPUP;
189 				trigs[numtrigs]._tlvl = 0;
190 				numtrigs++;
191 			}
192 
193 			if (dPiece[i][j] == 271) {
194 				trigs[numtrigs]._tx = i;
195 				trigs[numtrigs]._ty = j;
196 				trigs[numtrigs]._tmsg = WM_DIABNEXTLVL;
197 				numtrigs++;
198 			}
199 		}
200 	}
201 	trigflag = FALSE;
202 }
203 
InitL3Triggers()204 void InitL3Triggers()
205 {
206 	int i, j;
207 
208 	if (currlevel < 17) {
209 		numtrigs = 0;
210 		for (j = 0; j < MAXDUNY; j++) {
211 			for (i = 0; i < MAXDUNX; i++) {
212 				if (dPiece[i][j] == 171) {
213 					trigs[numtrigs]._tx = i;
214 					trigs[numtrigs]._ty = j;
215 					trigs[numtrigs]._tmsg = WM_DIABPREVLVL;
216 					numtrigs++;
217 				}
218 
219 				if (dPiece[i][j] == 168) {
220 					trigs[numtrigs]._tx = i;
221 					trigs[numtrigs]._ty = j;
222 					trigs[numtrigs]._tmsg = WM_DIABNEXTLVL;
223 					numtrigs++;
224 				}
225 
226 				if (dPiece[i][j] == 549) {
227 					trigs[numtrigs]._tx = i;
228 					trigs[numtrigs]._ty = j;
229 					trigs[numtrigs]._tmsg = WM_DIABTWARPUP;
230 					numtrigs++;
231 				}
232 			}
233 		}
234 	} else {
235 		numtrigs = 0;
236 		for (j = 0; j < MAXDUNY; j++) {
237 			for (i = 0; i < MAXDUNX; i++) {
238 				if (dPiece[i][j] == 66) {
239 					trigs[numtrigs]._tx = i;
240 					trigs[numtrigs]._ty = j;
241 					trigs[numtrigs]._tmsg = WM_DIABPREVLVL;
242 					numtrigs++;
243 				}
244 
245 				if (dPiece[i][j] == 63) {
246 					trigs[numtrigs]._tx = i;
247 					trigs[numtrigs]._ty = j;
248 					trigs[numtrigs]._tmsg = WM_DIABNEXTLVL;
249 					numtrigs++;
250 				}
251 
252 				if (dPiece[i][j] == 80) {
253 					trigs[numtrigs]._tx = i;
254 					trigs[numtrigs]._ty = j;
255 					trigs[numtrigs]._tmsg = WM_DIABTWARPUP;
256 					numtrigs++;
257 				}
258 			}
259 		}
260 	}
261 	trigflag = FALSE;
262 }
263 
InitL4Triggers()264 void InitL4Triggers()
265 {
266 	int i, j;
267 
268 	numtrigs = 0;
269 	for (j = 0; j < MAXDUNY; j++) {
270 		for (i = 0; i < MAXDUNX; i++) {
271 			if (dPiece[i][j] == 83) {
272 				trigs[numtrigs]._tx = i;
273 				trigs[numtrigs]._ty = j;
274 				trigs[numtrigs]._tmsg = WM_DIABPREVLVL;
275 				numtrigs++;
276 			}
277 
278 			if (dPiece[i][j] == 422) {
279 				trigs[numtrigs]._tx = i;
280 				trigs[numtrigs]._ty = j;
281 				trigs[numtrigs]._tmsg = WM_DIABTWARPUP;
282 				trigs[numtrigs]._tlvl = 0;
283 				numtrigs++;
284 			}
285 
286 			if (dPiece[i][j] == 120) {
287 				trigs[numtrigs]._tx = i;
288 				trigs[numtrigs]._ty = j;
289 				trigs[numtrigs]._tmsg = WM_DIABNEXTLVL;
290 				numtrigs++;
291 			}
292 		}
293 	}
294 
295 	for (j = 0; j < MAXDUNY; j++) {
296 		for (i = 0; i < MAXDUNX; i++) {
297 			if (dPiece[i][j] == 370 && quests[Q_BETRAYER]._qactive == QUEST_DONE) {
298 				trigs[numtrigs]._tx = i;
299 				trigs[numtrigs]._ty = j;
300 				trigs[numtrigs]._tmsg = WM_DIABNEXTLVL;
301 				numtrigs++;
302 			}
303 		}
304 	}
305 	trigflag = FALSE;
306 }
307 
InitSKingTriggers()308 void InitSKingTriggers()
309 {
310 	trigflag = FALSE;
311 	numtrigs = 1;
312 	trigs[0]._tx = 82;
313 	trigs[0]._ty = 42;
314 	trigs[0]._tmsg = WM_DIABRTNLVL;
315 }
316 
InitSChambTriggers()317 void InitSChambTriggers()
318 {
319 	trigflag = FALSE;
320 	numtrigs = 1;
321 	trigs[0]._tx = 70;
322 	trigs[0]._ty = 39;
323 	trigs[0]._tmsg = WM_DIABRTNLVL;
324 }
325 
InitPWaterTriggers()326 void InitPWaterTriggers()
327 {
328 	trigflag = FALSE;
329 	numtrigs = 1;
330 	trigs[0]._tx = 30;
331 	trigs[0]._ty = 83;
332 	trigs[0]._tmsg = WM_DIABRTNLVL;
333 }
334 
InitVPTriggers()335 void InitVPTriggers()
336 {
337 	trigflag = FALSE;
338 	numtrigs = 1;
339 	trigs[0]._tx = 35;
340 	trigs[0]._ty = 32;
341 	trigs[0]._tmsg = WM_DIABRTNLVL;
342 }
343 
ForceTownTrig()344 BOOL ForceTownTrig()
345 {
346 	int i, j, k, l;
347 
348 	for (i = 0; TownDownList[i] != -1; i++) {
349 		if (dPiece[cursmx][cursmy] == TownDownList[i]) {
350 			strcpy(infostr, "Down to dungeon");
351 			cursmx = 25;
352 			cursmy = 29;
353 			return TRUE;
354 		}
355 	}
356 
357 	if (townwarps[0]) {
358 		for (j = 0; TownWarp1List[j] != -1; j++) {
359 			if (dPiece[cursmx][cursmy] == TownWarp1List[j]) {
360 				strcpy(infostr, "Down to catacombs");
361 				cursmx = 49;
362 				cursmy = 21;
363 				return TRUE;
364 			}
365 		}
366 	}
367 
368 	if (townwarps[1]) {
369 		for (k = 1199; k <= 1220; k++) {
370 			if (dPiece[cursmx][cursmy] == k) {
371 				strcpy(infostr, "Down to caves");
372 				cursmx = 17;
373 				cursmy = 69;
374 				return TRUE;
375 			}
376 		}
377 	}
378 
379 	if (townwarps[2]) {
380 		for (l = 1240; l <= 1255; l++) {
381 			if (dPiece[cursmx][cursmy] == l) {
382 				strcpy(infostr, "Down to hell");
383 				cursmx = 41;
384 				cursmy = 80;
385 				return TRUE;
386 			}
387 		}
388 	}
389 
390 	if (gbIsHellfire) {
391 		for (i = 0; TownCryptList[i] != -1; i++) {
392 			if (dPiece[cursmx][cursmy] == TownCryptList[i]) {
393 				strcpy(infostr, "Down to Crypt");
394 				cursmx = 36;
395 				cursmy = 24;
396 				return TRUE;
397 			}
398 		}
399 		for (i = 0; TownHiveList[i] != -1; i++) {
400 			if (dPiece[cursmx][cursmy] == TownHiveList[i]) {
401 				strcpy(infostr, "Down to Hive");
402 				cursmx = 80;
403 				cursmy = 62;
404 				return TRUE;
405 			}
406 		}
407 	}
408 
409 	return FALSE;
410 }
411 
ForceL1Trig()412 BOOL ForceL1Trig()
413 {
414 	int i, j;
415 	int dx, dy;
416 
417 	if (currlevel < 17) {
418 		for (i = 0; L1UpList[i] != -1; i++) {
419 			if (dPiece[cursmx][cursmy] == L1UpList[i]) {
420 				if (currlevel > 1)
421 					sprintf(infostr, "Up to level %i", currlevel - 1);
422 				else
423 					strcpy(infostr, "Up to town");
424 				for (j = 0; j < numtrigs; j++) {
425 					if (trigs[j]._tmsg == WM_DIABPREVLVL) {
426 						cursmx = trigs[j]._tx;
427 						cursmy = trigs[j]._ty;
428 						return TRUE;
429 					}
430 				}
431 			}
432 		}
433 		for (i = 0; L1DownList[i] != -1; i++) {
434 			if (dPiece[cursmx][cursmy] == L1DownList[i]) {
435 				sprintf(infostr, "Down to level %i", currlevel + 1);
436 				for (j = 0; j < numtrigs; j++) {
437 					if (trigs[j]._tmsg == WM_DIABNEXTLVL) {
438 						cursmx = trigs[j]._tx;
439 						cursmy = trigs[j]._ty;
440 						return TRUE;
441 					}
442 				}
443 			}
444 		}
445 	} else {
446 		for (i = 0; L5UpList[i] != -1; i++) {
447 			if (dPiece[cursmx][cursmy] == L5UpList[i]) {
448 				sprintf(infostr, "Up to Crypt level %i", currlevel - 21);
449 				for (j = 0; j < numtrigs; j++) {
450 					if (trigs[j]._tmsg == WM_DIABPREVLVL) {
451 						cursmx = trigs[j]._tx;
452 						cursmy = trigs[j]._ty;
453 						return TRUE;
454 					}
455 				}
456 			}
457 		}
458 		if (dPiece[cursmx][cursmy] == 317) {
459 			strcpy(infostr, "Cornerstone of the World");
460 			return TRUE;
461 		}
462 		for (i = 0; L5DownList[i] != -1; i++) {
463 			if (dPiece[cursmx][cursmy] == L5DownList[i]) {
464 				sprintf(infostr, "Down to Crypt level %i", currlevel - 19);
465 				for (j = 0; j < numtrigs; j++) {
466 					if (trigs[j]._tmsg == WM_DIABNEXTLVL) {
467 						cursmx = trigs[j]._tx;
468 						cursmy = trigs[j]._ty;
469 						return TRUE;
470 					}
471 				}
472 			}
473 		}
474 		if (currlevel == 21) {
475 			for (i = 0; L5TWarpUpList[i] != -1; i++) {
476 				if (dPiece[cursmx][cursmy] == L5TWarpUpList[i]) {
477 					for (j = 0; j < numtrigs; j++) {
478 						if (trigs[j]._tmsg == WM_DIABTWARPUP) {
479 							dx = abs(trigs[j]._tx - cursmx);
480 							dy = abs(trigs[j]._ty - cursmy);
481 							if (dx < 4 && dy < 4) {
482 								strcpy(infostr, "Up to town");
483 								cursmx = trigs[j]._tx;
484 								cursmy = trigs[j]._ty;
485 								return TRUE;
486 							}
487 						}
488 					}
489 				}
490 			}
491 		}
492 	}
493 
494 	return FALSE;
495 }
496 
ForceL2Trig()497 BOOL ForceL2Trig()
498 {
499 	int i, j, dx, dy;
500 
501 	for (i = 0; L2UpList[i] != -1; i++) {
502 		if (dPiece[cursmx][cursmy] == L2UpList[i]) {
503 			for (j = 0; j < numtrigs; j++) {
504 				if (trigs[j]._tmsg == WM_DIABPREVLVL) {
505 					dx = abs(trigs[j]._tx - cursmx);
506 					dy = abs(trigs[j]._ty - cursmy);
507 					if (dx < 4 && dy < 4) {
508 						sprintf(infostr, "Up to level %i", currlevel - 1);
509 						cursmx = trigs[j]._tx;
510 						cursmy = trigs[j]._ty;
511 						return TRUE;
512 					}
513 				}
514 			}
515 		}
516 	}
517 
518 	for (i = 0; L2DownList[i] != -1; i++) {
519 		if (dPiece[cursmx][cursmy] == L2DownList[i]) {
520 			sprintf(infostr, "Down to level %i", currlevel + 1);
521 			for (j = 0; j < numtrigs; j++) {
522 				if (trigs[j]._tmsg == WM_DIABNEXTLVL) {
523 					cursmx = trigs[j]._tx;
524 					cursmy = trigs[j]._ty;
525 					return TRUE;
526 				}
527 			}
528 		}
529 	}
530 
531 	if (currlevel == 5) {
532 		for (i = 0; L2TWarpUpList[i] != -1; i++) {
533 			if (dPiece[cursmx][cursmy] == L2TWarpUpList[i]) {
534 				for (j = 0; j < numtrigs; j++) {
535 					if (trigs[j]._tmsg == WM_DIABTWARPUP) {
536 						dx = abs(trigs[j]._tx - cursmx);
537 						dy = abs(trigs[j]._ty - cursmy);
538 						if (dx < 4 && dy < 4) {
539 							strcpy(infostr, "Up to town");
540 							cursmx = trigs[j]._tx;
541 							cursmy = trigs[j]._ty;
542 							return TRUE;
543 						}
544 					}
545 				}
546 			}
547 		}
548 	}
549 
550 	return FALSE;
551 }
552 
ForceL3Trig()553 BOOL ForceL3Trig()
554 {
555 	int i, j, dx, dy;
556 
557 	if (currlevel < 17) {
558 		for (i = 0; L3UpList[i] != -1; ++i) {
559 			if (dPiece[cursmx][cursmy] == L3UpList[i]) {
560 				sprintf(infostr, "Up to level %i", currlevel - 1);
561 				for (j = 0; j < numtrigs; j++) {
562 					if (trigs[j]._tmsg == WM_DIABPREVLVL) {
563 						cursmx = trigs[j]._tx;
564 						cursmy = trigs[j]._ty;
565 						return TRUE;
566 					}
567 				}
568 			}
569 		}
570 		for (i = 0; L3DownList[i] != -1; i++) {
571 			if (dPiece[cursmx][cursmy] == L3DownList[i]
572 			    || dPiece[cursmx + 1][cursmy] == L3DownList[i]
573 			    || dPiece[cursmx + 2][cursmy] == L3DownList[i]) {
574 				sprintf(infostr, "Down to level %i", currlevel + 1);
575 				for (j = 0; j < numtrigs; j++) {
576 					if (trigs[j]._tmsg == WM_DIABNEXTLVL) {
577 						cursmx = trigs[j]._tx;
578 						cursmy = trigs[j]._ty;
579 						return TRUE;
580 					}
581 				}
582 			}
583 		}
584 	} else {
585 		for (i = 0; L6UpList[i] != -1; ++i) {
586 			if (dPiece[cursmx][cursmy] == L6UpList[i]) {
587 				sprintf(infostr, "Up to Nest level %i", currlevel - 17);
588 				for (j = 0; j < numtrigs; j++) {
589 					if (trigs[j]._tmsg == WM_DIABPREVLVL) {
590 						cursmx = trigs[j]._tx;
591 						cursmy = trigs[j]._ty;
592 						return TRUE;
593 					}
594 				}
595 			}
596 		}
597 		for (i = 0; L6DownList[i] != -1; i++) {
598 			if (dPiece[cursmx][cursmy] == L6DownList[i]
599 			    || dPiece[cursmx + 1][cursmy] == L6DownList[i]
600 			    || dPiece[cursmx + 2][cursmy] == L6DownList[i]) {
601 				sprintf(infostr, "Down to level %i", currlevel - 15);
602 				for (j = 0; j < numtrigs; j++) {
603 					if (trigs[j]._tmsg == WM_DIABNEXTLVL) {
604 						cursmx = trigs[j]._tx;
605 						cursmy = trigs[j]._ty;
606 						return TRUE;
607 					}
608 				}
609 			}
610 		}
611 	}
612 
613 	if (currlevel == 9) {
614 		for (i = 0; L3TWarpUpList[i] != -1; i++) {
615 			if (dPiece[cursmx][cursmy] == L3TWarpUpList[i]) {
616 				for (j = 0; j < numtrigs; j++) {
617 					if (trigs[j]._tmsg == WM_DIABTWARPUP) {
618 						dx = abs(trigs[j]._tx - cursmx);
619 						dy = abs(trigs[j]._ty - cursmy);
620 						if (dx < 4 && dy < 4) {
621 							strcpy(infostr, "Up to town");
622 							cursmx = trigs[j]._tx;
623 							cursmy = trigs[j]._ty;
624 							return TRUE;
625 						}
626 					}
627 				}
628 			}
629 		}
630 	}
631 	if (currlevel == 17) {
632 		for (i = 0; L6TWarpUpList[i] != -1; i++) {
633 			if (dPiece[cursmx][cursmy] == L6TWarpUpList[i]) {
634 				for (j = 0; j < numtrigs; j++) {
635 					if (trigs[j]._tmsg == WM_DIABTWARPUP) {
636 						dx = abs(trigs[j]._tx - cursmx);
637 						dy = abs(trigs[j]._ty - cursmy);
638 						if (dx < 4 && dy < 4) {
639 							strcpy(infostr, "Up to town");
640 							cursmx = trigs[j]._tx;
641 							cursmy = trigs[j]._ty;
642 							return TRUE;
643 						}
644 					}
645 				}
646 			}
647 		}
648 	}
649 
650 	return FALSE;
651 }
652 
ForceL4Trig()653 BOOL ForceL4Trig()
654 {
655 	int i, j, dx, dy;
656 
657 	for (i = 0; L4UpList[i] != -1; ++i) {
658 		if (dPiece[cursmx][cursmy] == L4UpList[i]) {
659 			sprintf(infostr, "Up to level %i", currlevel - 1);
660 			for (j = 0; j < numtrigs; j++) {
661 				if (trigs[j]._tmsg == WM_DIABPREVLVL) {
662 					cursmx = trigs[j]._tx;
663 					cursmy = trigs[j]._ty;
664 					return TRUE;
665 				}
666 			}
667 		}
668 	}
669 
670 	for (i = 0; L4DownList[i] != -1; i++) {
671 		if (dPiece[cursmx][cursmy] == L4DownList[i]) {
672 			sprintf(infostr, "Down to level %i", currlevel + 1);
673 			for (j = 0; j < numtrigs; j++) {
674 				if (trigs[j]._tmsg == WM_DIABNEXTLVL) {
675 					cursmx = trigs[j]._tx;
676 					cursmy = trigs[j]._ty;
677 					return TRUE;
678 				}
679 			}
680 		}
681 	}
682 
683 	if (currlevel == 13) {
684 		for (i = 0; L4TWarpUpList[i] != -1; i++) {
685 			if (dPiece[cursmx][cursmy] == L4TWarpUpList[i]) {
686 				for (j = 0; j < numtrigs; j++) {
687 					if (trigs[j]._tmsg == WM_DIABTWARPUP) {
688 						dx = abs(trigs[j]._tx - cursmx);
689 						dy = abs(trigs[j]._ty - cursmy);
690 						if (dx < 4 && dy < 4) {
691 							strcpy(infostr, "Up to town");
692 							cursmx = trigs[j]._tx;
693 							cursmy = trigs[j]._ty;
694 							return TRUE;
695 						}
696 					}
697 				}
698 			}
699 		}
700 	}
701 
702 	if (currlevel == 15) {
703 		for (i = 0; L4PentaList[i] != -1; i++) {
704 			if (dPiece[cursmx][cursmy] == L4PentaList[i]) {
705 				strcpy(infostr, "Down to Diablo");
706 				for (j = 0; j < numtrigs; j++) {
707 					if (trigs[j]._tmsg == WM_DIABNEXTLVL) {
708 						cursmx = trigs[j]._tx;
709 						cursmy = trigs[j]._ty;
710 						return TRUE;
711 					}
712 				}
713 			}
714 		}
715 	}
716 
717 	return FALSE;
718 }
719 
Freeupstairs()720 void Freeupstairs()
721 {
722 	int i, tx, ty, xx, yy;
723 
724 	for (i = 0; i < numtrigs; i++) {
725 		tx = trigs[i]._tx;
726 		ty = trigs[i]._ty;
727 
728 		for (yy = -2; yy <= 2; yy++) {
729 			for (xx = -2; xx <= 2; xx++) {
730 				dFlags[tx + xx][ty + yy] |= BFLAG_POPULATED;
731 			}
732 		}
733 	}
734 }
735 
ForceSKingTrig()736 BOOL ForceSKingTrig()
737 {
738 	int i;
739 
740 	for (i = 0; L1UpList[i] != -1; i++) {
741 		if (dPiece[cursmx][cursmy] == L1UpList[i]) {
742 			sprintf(infostr, "Back to Level %i", quests[Q_SKELKING]._qlevel);
743 			cursmx = trigs[0]._tx;
744 			cursmy = trigs[0]._ty;
745 
746 			return TRUE;
747 		}
748 	}
749 
750 	return FALSE;
751 }
752 
ForceSChambTrig()753 BOOL ForceSChambTrig()
754 {
755 	int i;
756 
757 	for (i = 0; L2DownList[i] != -1; i++) {
758 		if (dPiece[cursmx][cursmy] == L2DownList[i]) {
759 			sprintf(infostr, "Back to Level %i", quests[Q_SCHAMB]._qlevel);
760 			cursmx = trigs[0]._tx;
761 			cursmy = trigs[0]._ty;
762 
763 			return TRUE;
764 		}
765 	}
766 
767 	return FALSE;
768 }
769 
ForcePWaterTrig()770 BOOL ForcePWaterTrig()
771 {
772 	int i;
773 
774 	for (i = 0; L3DownList[i] != -1; i++) {
775 		if (dPiece[cursmx][cursmy] == L3DownList[i]) {
776 			sprintf(infostr, "Back to Level %i", quests[Q_PWATER]._qlevel);
777 			cursmx = trigs[0]._tx;
778 			cursmy = trigs[0]._ty;
779 
780 			return TRUE;
781 		}
782 	}
783 
784 	return FALSE;
785 }
786 
CheckTrigForce()787 void CheckTrigForce()
788 {
789 	trigflag = FALSE;
790 
791 	if (!sgbControllerActive && MouseY > PANEL_TOP - 1) {
792 		return;
793 	}
794 
795 	if (!setlevel) {
796 		switch (leveltype) {
797 		case DTYPE_TOWN:
798 			trigflag = ForceTownTrig();
799 			break;
800 		case DTYPE_CATHEDRAL:
801 			trigflag = ForceL1Trig();
802 			break;
803 		case DTYPE_CATACOMBS:
804 			trigflag = ForceL2Trig();
805 			break;
806 		case DTYPE_CAVES:
807 			trigflag = ForceL3Trig();
808 			break;
809 		case DTYPE_HELL:
810 			trigflag = ForceL4Trig();
811 			break;
812 		default:
813 			break;
814 		}
815 		if (leveltype != DTYPE_TOWN && !trigflag) {
816 			trigflag = ForceQuests();
817 		}
818 	} else {
819 		switch (setlvlnum) {
820 		case SL_SKELKING:
821 			trigflag = ForceSKingTrig();
822 			break;
823 		case SL_BONECHAMB:
824 			trigflag = ForceSChambTrig();
825 			break;
826 		case SL_POISONWATER:
827 			trigflag = ForcePWaterTrig();
828 			break;
829 		}
830 	}
831 
832 	if (trigflag) {
833 		ClearPanel();
834 	}
835 }
836 
CheckTriggers()837 void CheckTriggers()
838 {
839 	int x, y, i;
840 	BOOL abort;
841 	char abortflag;
842 
843 	if (plr[myplr]._pmode != PM_STAND)
844 		return;
845 
846 	for (i = 0; i < numtrigs; i++) {
847 		if (plr[myplr]._px != trigs[i]._tx || plr[myplr]._py != trigs[i]._ty) {
848 			continue;
849 		}
850 
851 		switch (trigs[i]._tmsg) {
852 		case WM_DIABNEXTLVL:
853 			if (gbIsSpawn && currlevel >= 2) {
854 				NetSendCmdLoc(TRUE, CMD_WALKXY, plr[myplr]._px, plr[myplr]._py + 1);
855 				PlaySFX(PS_WARR18);
856 				InitDiabloMsg(EMSG_NOT_IN_SHAREWARE);
857 			} else {
858 				StartNewLvl(myplr, trigs[i]._tmsg, currlevel + 1);
859 			}
860 			break;
861 		case WM_DIABPREVLVL:
862 			StartNewLvl(myplr, trigs[i]._tmsg, currlevel - 1);
863 			break;
864 		case WM_DIABRTNLVL:
865 			StartNewLvl(myplr, trigs[i]._tmsg, ReturnLvl);
866 			break;
867 		case WM_DIABTOWNWARP:
868 			if (gbIsMultiplayer) {
869 				abort = FALSE;
870 
871 				if (trigs[i]._tlvl == 5 && plr[myplr]._pLevel < 8) {
872 					abort = TRUE;
873 					x = plr[myplr]._px;
874 					y = plr[myplr]._py + 1;
875 					abortflag = EMSG_REQUIRES_LVL_8;
876 				}
877 
878 				if (trigs[i]._tlvl == 9 && plr[myplr]._pLevel < 13) {
879 					abort = TRUE;
880 					x = plr[myplr]._px + 1;
881 					y = plr[myplr]._py;
882 					abortflag = EMSG_REQUIRES_LVL_13;
883 				}
884 
885 				if (trigs[i]._tlvl == 13 && plr[myplr]._pLevel < 17) {
886 					abort = TRUE;
887 					x = plr[myplr]._px;
888 					y = plr[myplr]._py + 1;
889 					abortflag = EMSG_REQUIRES_LVL_17;
890 				}
891 
892 				if (abort) {
893 					if (plr[myplr]._pClass == PC_WARRIOR) {
894 						PlaySFX(PS_WARR43);
895 					} else if (plr[myplr]._pClass == PC_ROGUE) {
896 						PlaySFX(PS_ROGUE43);
897 					} else if (plr[myplr]._pClass == PC_SORCERER) {
898 						PlaySFX(PS_MAGE43);
899 					} else if (plr[myplr]._pClass == PC_MONK) {
900 						PlaySFX(PS_MONK43);
901 					} else if (plr[myplr]._pClass == PC_BARD) {
902 						PlaySFX(PS_ROGUE43);
903 					} else if (plr[myplr]._pClass == PC_BARBARIAN) {
904 						PlaySFX(PS_WARR43);
905 					}
906 
907 					InitDiabloMsg(abortflag);
908 					NetSendCmdLoc(TRUE, CMD_WALKXY, x, y);
909 					return;
910 				}
911 			}
912 
913 			StartNewLvl(myplr, trigs[i]._tmsg, trigs[i]._tlvl);
914 			break;
915 		case WM_DIABTWARPUP:
916 			TWarpFrom = currlevel;
917 			StartNewLvl(myplr, trigs[i]._tmsg, 0);
918 			break;
919 		default:
920 			app_fatal("Unknown trigger msg");
921 		}
922 	}
923 }
924 
925 DEVILUTION_END_NAMESPACE
926