Devilution
Diablo devolved - magic behind the 1996 computer game
themes.cpp
Go to the documentation of this file.
1 
6 #include "all.h"
7 
9 
11 BOOL armorFlag;
12 BOOL ThemeGoodIn[4];
18 int zharlib;
19 int themex;
20 int themey;
26 
28 
29 int trm5x[25] = {
30  -2, -1, 0, 1, 2,
31  -2, -1, 0, 1, 2,
32  -2, -1, 0, 1, 2,
33  -2, -1, 0, 1, 2,
34  -2, -1, 0, 1, 2
35 };
36 
37 int trm5y[25] = {
38  -2, -2, -2, -2, -2,
39  -1, -1, -1, -1, -1,
40  0, 0, 0, 0, 0,
41  1, 1, 1, 1, 1,
42  2, 2, 2, 2, 2
43 };
44 
45 int trm3x[9] = {
46  -1, 0, 1,
47  -1, 0, 1,
48  -1, 0, 1
49 };
50 
51 int trm3y[9] = {
52  -1, -1, -1,
53  0, 0, 0,
54  1, 1, 1
55 };
56 
57 BOOL TFit_Shrine(int i)
58 {
59  int xp, yp, found;
60 
61  xp = 0;
62  yp = 0;
63  found = 0;
64  while (found == 0) {
65  if (dTransVal[xp][yp] == themes[i].ttval) {
66  if (nTrapTable[dPiece[xp][yp - 1]]
67  && !nSolidTable[dPiece[xp - 1][yp]]
68  && !nSolidTable[dPiece[xp + 1][yp]]
69  && dTransVal[xp - 1][yp] == themes[i].ttval
70  && dTransVal[xp + 1][yp] == themes[i].ttval
71  && dObject[xp - 1][yp - 1] == 0
72  && dObject[xp + 1][yp - 1] == 0) {
73  found = 1;
74  }
75  if (found == 0
76  && nTrapTable[dPiece[xp - 1][yp]]
77  && !nSolidTable[dPiece[xp][yp - 1]]
78  && !nSolidTable[dPiece[xp][yp + 1]]
79  && dTransVal[xp][yp - 1] == themes[i].ttval
80  && dTransVal[xp][yp + 1] == themes[i].ttval
81  && dObject[xp - 1][yp - 1] == 0
82  && dObject[xp - 1][yp + 1] == 0) {
83  found = 2;
84  }
85  }
86  if (found == 0) {
87  xp++;
88  if (xp == MAXDUNX) {
89  xp = 0;
90  yp++;
91  if (yp == MAXDUNY)
92  return FALSE;
93  }
94  }
95  }
96  themex = xp;
97  themey = yp;
98  themeVar1 = found;
99  return TRUE;
100 }
101 
102 BOOL TFit_Obj5(int t)
103 {
104  int xp, yp;
105  int i, r, rs;
106  BOOL found;
107 
108  xp = 0;
109  yp = 0;
110  r = random_(0, 5) + 1;
111  rs = r;
112  while (r > 0) {
113  found = FALSE;
114  if (dTransVal[xp][yp] == themes[t].ttval && !nSolidTable[dPiece[xp][yp]]) {
115  found = TRUE;
116  for (i = 0; found && i < 25; i++) {
117  if (nSolidTable[dPiece[xp + trm5x[i]][yp + trm5y[i]]]) {
118  found = FALSE;
119  }
120  if (dTransVal[xp + trm5x[i]][yp + trm5y[i]] != themes[t].ttval) {
121  found = FALSE;
122  }
123  }
124  }
125 
126  if (!found) {
127  xp++;
128  if (xp == MAXDUNX) {
129  xp = 0;
130  yp++;
131  if (yp == MAXDUNY) {
132  if (r == rs) {
133  return FALSE;
134  }
135  yp = 0;
136  }
137  }
138  continue;
139  }
140 
141  r--;
142  }
143 
144  themex = xp;
145  themey = yp;
146 
147  return TRUE;
148 }
149 
150 BOOL TFit_SkelRoom(int t)
151 {
152  int i;
153 
155  return FALSE;
156  }
157 
158  for (i = 0; i < nummtypes; i++) {
159  if (IsSkel(Monsters[i].mtype)) {
160  themeVar1 = i;
161  return TFit_Obj5(t);
162  }
163  }
164 
165  return FALSE;
166 }
167 
168 BOOL TFit_GoatShrine(int t)
169 {
170  int i;
171 
172  for (i = 0; i < nummtypes; i++) {
173  if (IsGoat(Monsters[i].mtype)) {
174  themeVar1 = i;
175  return TFit_Obj5(t);
176  }
177  }
178 
179  return FALSE;
180 }
181 
182 BOOL CheckThemeObj3(int xp, int yp, int t, int f)
183 {
184  int i;
185 
186  for (i = 0; i < 9; i++) {
187  if (xp + trm3x[i] < 0 || yp + trm3y[i] < 0)
188  return FALSE;
189  if (nSolidTable[dPiece[xp + trm3x[i]][yp + trm3y[i]]])
190  return FALSE;
191  if (dTransVal[xp + trm3x[i]][yp + trm3y[i]] != themes[t].ttval)
192  return FALSE;
193  if (dObject[xp + trm3x[i]][yp + trm3y[i]])
194  return FALSE;
195  if (f != -1 && !random_(0, f))
196  return FALSE;
197  }
198 
199  return TRUE;
200 }
201 
202 BOOL TFit_Obj3(int t)
203 {
204  int xp, yp;
205  char objrnd[4] = { 4, 4, 3, 5 };
206 
207  for (yp = 1; yp < MAXDUNY - 1; yp++) {
208  for (xp = 1; xp < MAXDUNX - 1; xp++) {
209  if (CheckThemeObj3(xp, yp, t, objrnd[leveltype - 1])) {
210  themex = xp;
211  themey = yp;
212  return TRUE;
213  }
214  }
215  }
216 
217  return FALSE;
218 }
219 
220 BOOL CheckThemeReqs(int t)
221 {
222  BOOL rv;
223 
224  rv = TRUE;
225  switch (t) {
226  case THEME_SHRINE:
227  case THEME_SKELROOM:
228  case THEME_LIBRARY:
229  if (leveltype == DTYPE_CAVES || leveltype == DTYPE_HELL) {
230  rv = FALSE;
231  }
232  break;
233  case THEME_BLOODFOUNTAIN:
234  if (!bFountainFlag) {
235  rv = FALSE;
236  }
237  break;
239  if (!pFountainFlag) {
240  rv = FALSE;
241  }
242  break;
243  case THEME_ARMORSTAND:
244  if (leveltype == DTYPE_CATHEDRAL) {
245  rv = FALSE;
246  }
247  break;
248  case THEME_CAULDRON:
249  if (leveltype != DTYPE_HELL || !cauldronFlag) {
250  rv = FALSE;
251  }
252  break;
253  case THEME_MURKYFOUNTAIN:
254  if (!mFountainFlag) {
255  rv = FALSE;
256  }
257  break;
258  case THEME_TEARFOUNTAIN:
259  if (!tFountainFlag) {
260  rv = FALSE;
261  }
262  break;
263  case THEME_WEAPONRACK:
264  if (leveltype == DTYPE_CATHEDRAL) {
265  rv = FALSE;
266  }
267  break;
268  }
269 
270  return rv;
271 }
272 
273 BOOL SpecialThemeFit(int i, int t)
274 {
275  BOOL rv;
276 
277  rv = CheckThemeReqs(t);
278  switch (t) {
279  case THEME_SHRINE:
280  case THEME_LIBRARY:
281  if (rv) {
282  rv = TFit_Shrine(i);
283  }
284  break;
285  case THEME_SKELROOM:
286  if (rv) {
287  rv = TFit_SkelRoom(i);
288  }
289  break;
290  case THEME_BLOODFOUNTAIN:
291  if (rv) {
292  rv = TFit_Obj5(i);
293  }
294  if (rv) {
295  bFountainFlag = FALSE;
296  }
297  break;
299  if (rv) {
300  rv = TFit_Obj5(i);
301  }
302  if (rv) {
303  pFountainFlag = FALSE;
304  }
305  break;
306  case THEME_MURKYFOUNTAIN:
307  if (rv) {
308  rv = TFit_Obj5(i);
309  }
310  if (rv) {
311  mFountainFlag = FALSE;
312  }
313  break;
314  case THEME_TEARFOUNTAIN:
315  if (rv) {
316  rv = TFit_Obj5(i);
317  }
318  if (rv) {
319  tFountainFlag = FALSE;
320  }
321  break;
322  case THEME_CAULDRON:
323  if (rv) {
324  rv = TFit_Obj5(i);
325  }
326  if (rv) {
327  cauldronFlag = FALSE;
328  }
329  break;
330  case THEME_GOATSHRINE:
331  if (rv) {
332  rv = TFit_GoatShrine(i);
333  }
334  break;
335  case THEME_TORTURE:
336  case THEME_DECAPITATED:
337  case THEME_ARMORSTAND:
338  case THEME_BRNCROSS:
339  case THEME_WEAPONRACK:
340  if (rv) {
341  rv = TFit_Obj3(i);
342  }
343  break;
344  case THEME_TREASURE:
345  rv = treasureFlag;
346  if (rv) {
347  treasureFlag = FALSE;
348  }
349  break;
350  }
351 
352  return rv;
353 }
354 
355 BOOL CheckThemeRoom(int tv)
356 {
357  int i, j, tarea;
358 
359  for (i = 0; i < numtrigs; i++) {
360  if (dTransVal[trigs[i]._tx][trigs[i]._ty] == tv)
361  return FALSE;
362  }
363 
364  tarea = 0;
365  for (j = 0; j < MAXDUNY; j++) {
366  for (i = 0; i < MAXDUNX; i++) {
367  if (dTransVal[i][j] != tv)
368  continue;
369  if (dFlags[i][j] & BFLAG_POPULATED)
370  return FALSE;
371 
372  tarea++;
373  }
374  }
375 
376  if (leveltype == DTYPE_CATHEDRAL && (tarea < 9 || tarea > 100))
377  return FALSE;
378 
379  for (j = 0; j < MAXDUNY; j++) {
380  for (i = 0; i < MAXDUNX; i++) {
381  if (dTransVal[i][j] != tv || nSolidTable[dPiece[i][j]])
382  continue;
383  if (dTransVal[i - 1][j] != tv && !nSolidTable[dPiece[i - 1][j]])
384  return FALSE;
385  if (dTransVal[i + 1][j] != tv && !nSolidTable[dPiece[i + 1][j]])
386  return FALSE;
387  if (dTransVal[i][j - 1] != tv && !nSolidTable[dPiece[i][j - 1]])
388  return FALSE;
389  if (dTransVal[i][j + 1] != tv && !nSolidTable[dPiece[i][j + 1]])
390  return FALSE;
391  }
392  }
393 
394  return TRUE;
395 }
396 
398 {
399  int i, j;
400 
401  zharlib = -1;
402  numthemes = 0;
403  armorFlag = TRUE;
404  bFountainFlag = TRUE;
405  cauldronFlag = TRUE;
406  mFountainFlag = TRUE;
407  pFountainFlag = TRUE;
408  tFountainFlag = TRUE;
409  treasureFlag = TRUE;
410  bCrossFlag = FALSE;
411  weaponFlag = TRUE;
412 
413  if (currlevel == 16)
414  return;
415 
416  if (leveltype == DTYPE_CATHEDRAL) {
417  for (i = 0; i < sizeof(ThemeGoodIn) / sizeof(ThemeGoodIn[0]); i++)
418  ThemeGoodIn[i] = FALSE;
419 
420  for (i = 0; i < 256 && numthemes < MAXTHEMES; i++) {
421  if (CheckThemeRoom(i)) {
422  themes[numthemes].ttval = i;
423  for (j = ThemeGood[random_(0, 4)];; j = random_(0, 17)) {
424  if (SpecialThemeFit(numthemes, j)) {
425  break;
426  }
427  }
428  themes[numthemes].ttype = j;
429  numthemes++;
430  }
431  }
432  }
434  for (i = 0; i < themeCount; i++)
435  themes[i].ttype = THEME_NONE;
436  if (QuestStatus(Q_ZHAR)) {
437  for (j = 0; j < themeCount; j++) {
438  themes[j].ttval = themeLoc[j].ttval;
439  if (SpecialThemeFit(j, THEME_LIBRARY)) {
441  zharlib = j;
442  break;
443  }
444  }
445  }
446  for (i = 0; i < themeCount; i++) {
447  if (themes[i].ttype == THEME_NONE) {
448  themes[i].ttval = themeLoc[i].ttval;
449  for (j = ThemeGood[random_(0, 4)];; j = random_(0, 17)) {
450  if (SpecialThemeFit(i, j)) {
451  break;
452  }
453  }
454  themes[i].ttype = j;
455  }
456  }
458  }
459 }
460 
465 {
466  int i, x, y;
467  char v;
468 
469  if (currlevel != 16) {
470  if (leveltype == DTYPE_CATHEDRAL) {
471  for (i = 0; i < numthemes; i++) {
472  v = themes[i].ttval;
473  for (y = 0; y < MAXDUNY; y++) {
474  for (x = 0; x < MAXDUNX; x++) {
475  if (dTransVal[x][y] == v) {
476  dFlags[x][y] |= BFLAG_POPULATED;
477  }
478  }
479  }
480  }
481  } else {
483  }
484  }
485 }
486 
493 void PlaceThemeMonsts(int t, int f)
494 {
495  int xp, yp;
496  int scattertypes[111];
497  int numscattypes, mtype, i;
498 
499  numscattypes = 0;
500  for (i = 0; i < nummtypes; i++) {
501  if (Monsters[i].mPlaceFlags & 1) {
502  scattertypes[numscattypes] = i;
503  numscattypes++;
504  }
505  }
506  mtype = scattertypes[random_(0, numscattypes)];
507  for (yp = 0; yp < MAXDUNY; yp++) {
508  for (xp = 0; xp < MAXDUNX; xp++) {
509  if (dTransVal[xp][yp] == themes[t].ttval && !nSolidTable[dPiece[xp][yp]] && dItem[xp][yp] == 0 && dObject[xp][yp] == 0) {
510  if (random_(0, f) == 0) {
511  AddMonster(xp, yp, random_(0, 8), mtype, TRUE);
512  }
513  }
514  }
515  }
516 }
517 
523 void Theme_Barrel(int t)
524 {
525  int xp, yp, r;
526  char barrnd[4] = { 2, 6, 4, 8 };
527  char monstrnd[4] = { 5, 7, 3, 9 };
528 
529  for (yp = 0; yp < MAXDUNY; yp++) {
530  for (xp = 0; xp < MAXDUNX; xp++) {
531  if (dTransVal[xp][yp] == themes[t].ttval && !nSolidTable[dPiece[xp][yp]]) {
532  if (random_(0, barrnd[leveltype - 1]) == 0) {
533  if (random_(0, barrnd[leveltype - 1]) == 0) {
534  r = OBJ_BARREL;
535  } else {
536  r = OBJ_BARRELEX;
537  }
538  AddObject(r, xp, yp);
539  }
540  }
541  }
542  }
543  PlaceThemeMonsts(t, monstrnd[leveltype - 1]);
544 }
545 
551 void Theme_Shrine(int t)
552 {
553  char monstrnd[4] = { 6, 6, 3, 9 };
554 
555  TFit_Shrine(t);
556  if (themeVar1 == 1) {
560  } else {
564  }
565  PlaceThemeMonsts(t, monstrnd[leveltype - 1]);
566 }
567 
573 void Theme_MonstPit(int t)
574 {
575  int r;
576  int ixp, iyp;
577  char monstrnd[4] = { 6, 7, 3, 9 };
578 
579  r = random_(0, 100) + 1;
580  ixp = 0;
581  iyp = 0;
582  if (r > 0) {
583  while (TRUE) {
584  if (dTransVal[ixp][iyp] == themes[t].ttval && !nSolidTable[dPiece[ixp][iyp]]) {
585  --r;
586  }
587  if (r <= 0) {
588  break;
589  }
590  ixp++;
591  if (ixp == MAXDUNX) {
592  ixp = 0;
593  iyp++;
594  if (iyp == MAXDUNY) {
595  iyp = 0;
596  }
597  }
598  }
599  }
600  CreateRndItem(ixp, iyp, TRUE, FALSE, TRUE);
601  ItemNoFlippy();
602  PlaceThemeMonsts(t, monstrnd[leveltype - 1]);
603 }
604 
610 void Theme_SkelRoom(int t)
611 {
612  int xp, yp, i;
613  char monstrnd[4] = { 6, 7, 3, 9 };
614 
615  TFit_SkelRoom(t);
616 
617  xp = themex;
618  yp = themey;
619 
620  AddObject(OBJ_SKFIRE, xp, yp);
621 
622  if (random_(0, monstrnd[leveltype - 1]) != 0) {
623  i = PreSpawnSkeleton();
624  SpawnSkeleton(i, xp - 1, yp - 1);
625  } else {
626  AddObject(OBJ_BANNERL, xp - 1, yp - 1);
627  }
628 
629  i = PreSpawnSkeleton();
630  SpawnSkeleton(i, xp, yp - 1);
631 
632  if (random_(0, monstrnd[leveltype - 1]) != 0) {
633  i = PreSpawnSkeleton();
634  SpawnSkeleton(i, xp + 1, yp - 1);
635  } else {
636  AddObject(OBJ_BANNERR, xp + 1, yp - 1);
637  }
638  if (random_(0, monstrnd[leveltype - 1]) != 0) {
639  i = PreSpawnSkeleton();
640  SpawnSkeleton(i, xp - 1, yp);
641  } else {
642  AddObject(OBJ_BANNERM, xp - 1, yp);
643  }
644  if (random_(0, monstrnd[leveltype - 1]) != 0) {
645  i = PreSpawnSkeleton();
646  SpawnSkeleton(i, xp + 1, yp);
647  } else {
648  AddObject(OBJ_BANNERM, xp + 1, yp);
649  }
650  if (random_(0, monstrnd[leveltype - 1]) != 0) {
651  i = PreSpawnSkeleton();
652  SpawnSkeleton(i, xp - 1, yp + 1);
653  } else {
654  AddObject(OBJ_BANNERR, xp - 1, yp + 1);
655  }
656 
657  i = PreSpawnSkeleton();
658  SpawnSkeleton(i, xp, yp + 1);
659 
660  if (random_(0, monstrnd[leveltype - 1]) != 0) {
661  i = PreSpawnSkeleton();
662  SpawnSkeleton(i, xp + 1, yp + 1);
663  } else {
664  AddObject(OBJ_BANNERL, xp + 1, yp + 1);
665  }
666 
667  if (dObject[xp][yp - 3] == 0) {
668  AddObject(OBJ_SKELBOOK, xp, yp - 2);
669  }
670  if (dObject[xp][yp + 3] == 0) {
671  AddObject(OBJ_SKELBOOK, xp, yp + 2);
672  }
673 }
674 
680 void Theme_Treasure(int t)
681 {
682  int xp, yp;
683  int i;
684  char treasrnd[4] = { 4, 9, 7, 10 };
685  char monstrnd[4] = { 6, 8, 3, 7 };
686 
687  GetRndSeed();
688  for (yp = 0; yp < MAXDUNY; yp++) {
689  for (xp = 0; xp < MAXDUNX; xp++) {
690  if (dTransVal[xp][yp] == themes[t].ttval && !nSolidTable[dPiece[xp][yp]]) {
691  int rv = random_(0, treasrnd[leveltype - 1]);
692  // BUGFIX: the `2*` in `2*random_(0, treasrnd...) == 0` has no effect, should probably be `random_(0, 2*treasrnd...) == 0`
693  if ((2 * random_(0, treasrnd[leveltype - 1])) == 0) {
694  CreateTypeItem(xp, yp, FALSE, ITYPE_GOLD, IMISC_NONE, FALSE, TRUE);
695  ItemNoFlippy();
696  }
697  if (rv == 0) {
698  CreateRndItem(xp, yp, FALSE, FALSE, TRUE);
699  ItemNoFlippy();
700  }
701  if (rv == 0 || rv >= treasrnd[leveltype - 1] - 2) {
702  i = ItemNoFlippy();
703  if (rv >= treasrnd[leveltype - 1] - 2 && leveltype != DTYPE_CATHEDRAL) {
704  item[i]._ivalue >>= 1;
705  }
706  }
707  }
708  }
709  }
710  PlaceThemeMonsts(t, monstrnd[leveltype - 1]);
711 }
712 
718 void Theme_Library(int t)
719 {
720  int xp, yp, oi;
721  char librnd[4] = { 1, 2, 2, 5 };
722  char monstrnd[4] = { 5, 7, 3, 9 };
723 
724  TFit_Shrine(t);
725 
726  if (themeVar1 == 1) {
730  } else {
734  }
735 
736  for (yp = 1; yp < MAXDUNY - 1; yp++) {
737  for (xp = 1; xp < MAXDUNX - 1; xp++) {
738  if (CheckThemeObj3(xp, yp, t, -1) && dMonster[xp][yp] == 0 && random_(0, librnd[leveltype - 1]) == 0) {
739  AddObject(OBJ_BOOKSTAND, xp, yp);
740  if (random_(0, 2 * librnd[leveltype - 1]) != 0 && dObject[xp][yp]) {
741  oi = dObject[xp][yp] - 1;
742  object[oi]._oSelFlag = 0;
743  object[oi]._oAnimFrame += 2;
744  }
745  }
746  }
747  }
748 
749  if (QuestStatus(Q_ZHAR)) {
750  if (t == zharlib) {
751  return;
752  }
753  PlaceThemeMonsts(t, monstrnd[leveltype]);
754  } else {
755  PlaceThemeMonsts(t, monstrnd[leveltype]);
756  }
757 }
758 
764 void Theme_Torture(int t)
765 {
766  int xp, yp;
767  char tortrnd[4] = { 6, 8, 3, 8 };
768  char monstrnd[4] = { 6, 8, 3, 9 };
769 
770  for (yp = 1; yp < MAXDUNY - 1; yp++) {
771  for (xp = 1; xp < MAXDUNX - 1; xp++) {
772  if (dTransVal[xp][yp] == themes[t].ttval && !nSolidTable[dPiece[xp][yp]]) {
773  if (CheckThemeObj3(xp, yp, t, -1)) {
774  if (random_(0, tortrnd[leveltype - 1]) == 0) {
775  AddObject(OBJ_TNUDEM2, xp, yp);
776  }
777  }
778  }
779  }
780  }
781  PlaceThemeMonsts(t, monstrnd[leveltype - 1]);
782 }
783 
789 {
790  char monstrnd[4] = { 6, 8, 3, 9 };
791 
792  TFit_Obj5(t);
794  PlaceThemeMonsts(t, monstrnd[leveltype - 1]);
795 }
796 
802 void Theme_Decap(int t)
803 {
804  int xp, yp;
805  char decaprnd[4] = { 6, 8, 3, 8 };
806  char monstrnd[4] = { 6, 8, 3, 9 };
807 
808  for (yp = 1; yp < MAXDUNY - 1; yp++) {
809  for (xp = 1; xp < MAXDUNX - 1; xp++) {
810  if (dTransVal[xp][yp] == themes[t].ttval && !nSolidTable[dPiece[xp][yp]]) {
811  if (CheckThemeObj3(xp, yp, t, -1)) {
812  if (random_(0, decaprnd[leveltype - 1]) == 0) {
813  AddObject(OBJ_DECAP, xp, yp);
814  }
815  }
816  }
817  }
818  }
819  PlaceThemeMonsts(t, monstrnd[leveltype - 1]);
820 }
821 
828 {
829  char monstrnd[4] = { 6, 7, 3, 9 };
830 
831  TFit_Obj5(t);
833  PlaceThemeMonsts(t, monstrnd[leveltype - 1]);
834 }
835 
841 void Theme_ArmorStand(int t)
842 {
843  int xp, yp;
844  char armorrnd[4] = { 6, 8, 3, 8 };
845  char monstrnd[4] = { 6, 7, 3, 9 };
846 
847  if (armorFlag) {
848  TFit_Obj3(t);
850  }
851  for (yp = 0; yp < MAXDUNY; yp++) {
852  for (xp = 0; xp < MAXDUNX; xp++) {
853  if (dTransVal[xp][yp] == themes[t].ttval && !nSolidTable[dPiece[xp][yp]]) {
854  if (CheckThemeObj3(xp, yp, t, -1)) {
855  if (random_(0, armorrnd[leveltype - 1]) == 0) {
856  AddObject(OBJ_ARMORSTANDN, xp, yp);
857  }
858  }
859  }
860  }
861  }
862  PlaceThemeMonsts(t, monstrnd[leveltype - 1]);
863  armorFlag = FALSE;
864 }
865 
871 void Theme_GoatShrine(int t)
872 {
873  int xx, yy;
874 
875  TFit_GoatShrine(t);
877  for (yy = themey - 1; yy <= themey + 1; yy++) {
878  for (xx = themex - 1; xx <= themex + 1; xx++) {
879  if (dTransVal[xx][yy] == themes[t].ttval && !nSolidTable[dPiece[xx][yy]] && (xx != themex || yy != themey)) {
880  AddMonster(xx, yy, DIR_SW, themeVar1, TRUE);
881  }
882  }
883  }
884 }
885 
891 void Theme_Cauldron(int t)
892 {
893  char monstrnd[4] = { 6, 7, 3, 9 };
894 
895  TFit_Obj5(t);
897  PlaceThemeMonsts(t, monstrnd[leveltype - 1]);
898 }
899 
906 {
907  char monstrnd[4] = { 6, 7, 3, 9 };
908 
909  TFit_Obj5(t);
911  PlaceThemeMonsts(t, monstrnd[leveltype - 1]);
912 }
913 
920 {
921  char monstrnd[4] = { 6, 7, 3, 9 };
922 
923  TFit_Obj5(t);
925  PlaceThemeMonsts(t, monstrnd[leveltype - 1]);
926 }
927 
933 void Theme_BrnCross(int t)
934 {
935  int xp, yp;
936  char monstrnd[4] = { 6, 8, 3, 9 };
937  char bcrossrnd[4] = { 5, 7, 3, 8 };
938 
939  for (yp = 0; yp < MAXDUNY; yp++) {
940  for (xp = 0; xp < MAXDUNX; xp++) {
941  if (dTransVal[xp][yp] == themes[t].ttval && !nSolidTable[dPiece[xp][yp]]) {
942  if (CheckThemeObj3(xp, yp, t, -1)) {
943  if (random_(0, bcrossrnd[leveltype - 1]) == 0) {
944  AddObject(OBJ_TBCROSS, xp, yp);
945  }
946  }
947  }
948  }
949  }
950  PlaceThemeMonsts(t, monstrnd[leveltype - 1]);
951  bCrossFlag = TRUE;
952 }
953 
959 void Theme_WeaponRack(int t)
960 {
961  int xp, yp;
962  char weaponrnd[4] = { 6, 8, 5, 8 };
963  char monstrnd[4] = { 6, 7, 3, 9 };
964 
965  if (weaponFlag) {
966  TFit_Obj3(t);
968  }
969  for (yp = 0; yp < MAXDUNY; yp++) {
970  for (xp = 0; xp < MAXDUNX; xp++) {
971  if (dTransVal[xp][yp] == themes[t].ttval && !nSolidTable[dPiece[xp][yp]]) {
972  if (CheckThemeObj3(xp, yp, t, -1)) {
973  if (random_(0, weaponrnd[leveltype - 1]) == 0) {
974  AddObject(OBJ_WEAPONRACKN, xp, yp);
975  }
976  }
977  }
978  }
979  }
980  PlaceThemeMonsts(t, monstrnd[leveltype - 1]);
981  weaponFlag = FALSE;
982 }
983 
988 {
989  int i, j;
990 
991  for (j = 0; j < MAXDUNY; j++) {
992  for (i = 0; i < MAXDUNX; i++) {
993  if (dTransVal[i][j]) {
994  dTransVal[i][j] = 1;
995  }
996  }
997  }
998 }
999 
1004 {
1005  int i;
1006 
1007  if (currlevel == 16) {
1008  return;
1009  }
1010  InitObjFlag = TRUE;
1011  for (i = 0; i < numthemes; i++) {
1012  themex = 0;
1013  themey = 0;
1014  switch (themes[i].ttype) {
1015  case THEME_BARREL:
1016  Theme_Barrel(i);
1017  break;
1018  case THEME_SHRINE:
1019  Theme_Shrine(i);
1020  break;
1021  case THEME_MONSTPIT:
1022  Theme_MonstPit(i);
1023  break;
1024  case THEME_SKELROOM:
1025  Theme_SkelRoom(i);
1026  break;
1027  case THEME_TREASURE:
1028  Theme_Treasure(i);
1029  break;
1030  case THEME_LIBRARY:
1031  Theme_Library(i);
1032  break;
1033  case THEME_TORTURE:
1034  Theme_Torture(i);
1035  break;
1036  case THEME_BLOODFOUNTAIN:
1038  break;
1039  case THEME_DECAPITATED:
1040  Theme_Decap(i);
1041  break;
1044  break;
1045  case THEME_ARMORSTAND:
1046  Theme_ArmorStand(i);
1047  break;
1048  case THEME_GOATSHRINE:
1049  Theme_GoatShrine(i);
1050  break;
1051  case THEME_CAULDRON:
1052  Theme_Cauldron(i);
1053  break;
1054  case THEME_MURKYFOUNTAIN:
1056  break;
1057  case THEME_TEARFOUNTAIN:
1058  Theme_TearFountain(i);
1059  break;
1060  case THEME_BRNCROSS:
1061  Theme_BrnCross(i);
1062  break;
1063  case THEME_WEAPONRACK:
1064  Theme_WeaponRack(i);
1065  break;
1066  }
1067  }
1068  InitObjFlag = FALSE;
1069  if (leveltype == DTYPE_HELL && themeCount > 0) {
1070  UpdateL4Trans();
1071  }
1072 }
1073 
Theme_TearFountain
void Theme_TearFountain(int t)
Theme_TearFountain initializes the tear fountain theme.
Definition: themes.cpp:919
THEME_BRNCROSS
@ THEME_BRNCROSS
Definition: enums.h:1964
OBJ_SHRINER
@ OBJ_SHRINER
Definition: enums.h:2389
THEME_MONSTPIT
@ THEME_MONSTPIT
Definition: enums.h:1951
UpdateL4Trans
void UpdateL4Trans()
UpdateL4Trans sets each value of the transparency map to 1.
Definition: themes.cpp:987
Theme_PurifyingFountain
void Theme_PurifyingFountain(int t)
Theme_PurifyingFountain initializes the purifying fountain theme.
Definition: themes.cpp:827
Monsters
CMonster Monsters[MAX_LVLMTYPES]
Definition: monster.cpp:21
THEME_PURIFYINGFOUNTAIN
@ THEME_PURIFYINGFOUNTAIN
Definition: enums.h:1958
currlevel
BYTE currlevel
Definition: gendung.cpp:40
THEME_LOC::ttval
int ttval
Definition: structs.h:1116
AddMonster
int AddMonster(int x, int y, int dir, int mtype, BOOL InMap)
Definition: monster.cpp:1080
Theme_Barrel
void Theme_Barrel(int t)
Theme_Barrel initializes the barrel theme.
Definition: themes.cpp:523
QuestStatus
BOOL QuestStatus(int i)
Definition: quests.cpp:239
OBJ_SHRINEL
@ OBJ_SHRINEL
Definition: enums.h:2388
CheckThemeRoom
BOOL CheckThemeRoom(int tv)
Definition: themes.cpp:355
CheckThemeReqs
BOOL CheckThemeReqs(int t)
Definition: themes.cpp:220
OBJ_CANDLE2
@ OBJ_CANDLE2
Definition: enums.h:2338
OBJ_BLOODFTN
@ OBJ_BLOODFTN
Definition: enums.h:2395
OBJ_WEAPONRACKN
@ OBJ_WEAPONRACKN
Definition: enums.h:2422
Theme_ArmorStand
void Theme_ArmorStand(int t)
Theme_ArmorStand initializes the armor stand theme.
Definition: themes.cpp:841
DTYPE_CATACOMBS
@ DTYPE_CATACOMBS
Definition: enums.h:1870
tFountainFlag
BOOL tFountainFlag
Definition: themes.cpp:17
THEME_SKELROOM
@ THEME_SKELROOM
Definition: enums.h:1952
HoldThemeRooms
void HoldThemeRooms()
HoldThemeRooms marks theme rooms as populated.
Definition: themes.cpp:464
MAXDUNX
#define MAXDUNX
Definition: defs.h:25
Theme_GoatShrine
void Theme_GoatShrine(int t)
Theme_GoatShrine initializes the goat shrine theme.
Definition: themes.cpp:871
item
ItemStruct item[MAXITEMS+1]
Definition: items.cpp:15
treasureFlag
BOOL treasureFlag
Definition: themes.cpp:14
OBJ_BANNERM
@ OBJ_BANNERM
Definition: enums.h:2341
THEME_BLOODFOUNTAIN
@ THEME_BLOODFOUNTAIN
Definition: enums.h:1956
THEME_MURKYFOUNTAIN
@ THEME_MURKYFOUNTAIN
Definition: enums.h:1962
THEME_BARREL
@ THEME_BARREL
Definition: enums.h:1949
THEME_ARMORSTAND
@ THEME_ARMORSTAND
Definition: enums.h:1959
OBJ_GOATSHRINE
@ OBJ_GOATSHRINE
Definition: enums.h:2408
Theme_Treasure
void Theme_Treasure(int t)
Theme_Treasure initializes the treasure theme.
Definition: themes.cpp:680
OBJ_BANNERL
@ OBJ_BANNERL
Definition: enums.h:2340
ItemStruct::_ivalue
int _ivalue
Definition: structs.h:122
all.h
TFit_GoatShrine
BOOL TFit_GoatShrine(int t)
Definition: themes.cpp:168
ThemeGoodIn
BOOL ThemeGoodIn[4]
Definition: themes.cpp:12
OBJ_BOOKCASEL
@ OBJ_BOOKCASEL
Definition: enums.h:2391
nummtypes
int nummtypes
Definition: monster.cpp:24
numthemes
DEVILUTION_BEGIN_NAMESPACE int numthemes
Definition: themes.cpp:10
OBJ_ARMORSTAND
@ OBJ_ARMORSTAND
Definition: enums.h:2406
THEME_WEAPONRACK
@ THEME_WEAPONRACK
Definition: enums.h:1965
dObject
char dObject[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:19
OBJ_SKELBOOK
@ OBJ_SKELBOOK
Definition: enums.h:2390
themeCount
int themeCount
Definition: gendung.cpp:11
DIR_SW
@ DIR_SW
Definition: enums.h:2083
themes
ThemeStruct themes[MAXTHEMES]
Definition: themes.cpp:22
THEME_TREASURE
@ THEME_TREASURE
Definition: enums.h:1953
Theme_SkelRoom
void Theme_SkelRoom(int t)
Theme_SkelRoom initializes the skeleton room theme.
Definition: themes.cpp:610
MAXDUNY
#define MAXDUNY
Definition: defs.h:26
Theme_Library
void Theme_Library(int t)
Theme_Library initializes the library theme.
Definition: themes.cpp:718
TFit_Shrine
BOOL TFit_Shrine(int i)
Definition: themes.cpp:57
themex
int themex
Definition: themes.cpp:19
zharlib
int zharlib
Definition: themes.cpp:18
OBJ_BOOKSTAND
@ OBJ_BOOKSTAND
Definition: enums.h:2393
mFountainFlag
BOOL mFountainFlag
Definition: themes.cpp:15
CreateThemeRooms
void CreateThemeRooms()
CreateThemeRooms adds thematic elements to rooms.
Definition: themes.cpp:1003
dPiece
int dPiece[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:26
nSolidTable
BOOLEAN nSolidTable[2049]
List of path blocking dPieces.
Definition: gendung.cpp:45
bFountainFlag
BOOL bFountainFlag
Definition: themes.cpp:24
PreSpawnSkeleton
int PreSpawnSkeleton()
Definition: monster.cpp:5360
OBJ_BOOKCASER
@ OBJ_BOOKCASER
Definition: enums.h:2392
THEME_LIBRARY
@ THEME_LIBRARY
Definition: enums.h:1954
ThemeStruct::ttval
int ttval
Definition: structs.h:1162
DEVILUTION_END_NAMESPACE
#define DEVILUTION_END_NAMESPACE
Definition: types.h:10
ITYPE_GOLD
@ ITYPE_GOLD
Definition: enums.h:2491
trm3y
int trm3y[9]
Definition: themes.cpp:51
THEME_DECAPITATED
@ THEME_DECAPITATED
Definition: enums.h:1957
OBJ_BARRELEX
@ OBJ_BARRELEX
Definition: enums.h:2387
Theme_MurkyFountain
void Theme_MurkyFountain(int t)
Theme_MurkyFountain initializes the murky fountain theme.
Definition: themes.cpp:905
trigs
TriggerStruct trigs[MAXTRIGGERS]
Definition: trigs.cpp:8
themeLoc
THEME_LOC themeLoc[MAXTHEMES]
Definition: gendung.cpp:48
THEME_SHRINE
@ THEME_SHRINE
Definition: enums.h:1950
OBJ_TBCROSS
@ OBJ_TBCROSS
Definition: enums.h:2420
PlaceThemeMonsts
void PlaceThemeMonsts(int t, int f)
PlaceThemeMonsts places theme monsters with the specified frequency.
Definition: themes.cpp:493
TFit_Obj3
BOOL TFit_Obj3(int t)
Definition: themes.cpp:202
dItem
char dItem[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:57
OBJ_BANNERR
@ OBJ_BANNERR
Definition: enums.h:2342
OBJ_MURKYFTN
@ OBJ_MURKYFTN
Definition: enums.h:2410
ThemeStruct::ttype
char ttype
Definition: structs.h:1161
OBJ_SKFIRE
@ OBJ_SKFIRE
Definition: enums.h:2332
THEME_CAULDRON
@ THEME_CAULDRON
Definition: enums.h:1961
pFountainFlag
BOOL pFountainFlag
Definition: themes.cpp:23
nTrapTable
BOOLEAN nTrapTable[2049]
Definition: gendung.cpp:38
CreateTypeItem
void CreateTypeItem(int x, int y, BOOL onlygood, int itype, int imisc, BOOL sendmsg, BOOL delta)
Definition: items.cpp:2226
InitThemes
void InitThemes()
Definition: themes.cpp:397
GetRndSeed
int GetRndSeed()
Get the current RNG seed.
Definition: engine.cpp:739
DRLG_HoldThemeRooms
void DRLG_HoldThemeRooms()
Definition: gendung.cpp:537
TFit_Obj5
BOOL TFit_Obj5(int t)
Definition: themes.cpp:102
armorFlag
BOOL armorFlag
Definition: themes.cpp:11
Theme_Shrine
void Theme_Shrine(int t)
Theme_Shrine initializes the shrine theme.
Definition: themes.cpp:551
THEME_GOATSHRINE
@ THEME_GOATSHRINE
Definition: enums.h:1960
Theme_BrnCross
void Theme_BrnCross(int t)
Theme_BrnCross initializes the burning cross theme.
Definition: themes.cpp:933
THEME_TEARFOUNTAIN
@ THEME_TEARFOUNTAIN
Definition: enums.h:1963
InitObjFlag
BOOL InitObjFlag
Definition: objects.cpp:14
ItemNoFlippy
int ItemNoFlippy()
Definition: items.cpp:3915
DTYPE_HELL
@ DTYPE_HELL
Definition: enums.h:1872
Theme_WeaponRack
void Theme_WeaponRack(int t)
Theme_WeaponRack initializes the weapon rack theme.
Definition: themes.cpp:959
OBJ_WEAPONRACK
@ OBJ_WEAPONRACK
Definition: enums.h:2421
bCrossFlag
BOOL bCrossFlag
Definition: themes.cpp:25
TFit_SkelRoom
BOOL TFit_SkelRoom(int t)
Definition: themes.cpp:150
IMISC_NONE
@ IMISC_NONE
Definition: enums.h:2431
DTYPE_CAVES
@ DTYPE_CAVES
Definition: enums.h:1871
OBJ_TNUDEM2
@ OBJ_TNUDEM2
Definition: enums.h:2359
themey
int themey
Definition: themes.cpp:20
dTransVal
char dTransVal[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:37
CreateRndItem
void CreateRndItem(int x, int y, BOOL onlygood, BOOL sendmsg, BOOL delta)
Definition: items.cpp:2166
OBJ_DECAP
@ OBJ_DECAP
Definition: enums.h:2396
Theme_Cauldron
void Theme_Cauldron(int t)
Theme_Cauldron initializes the cauldron theme.
Definition: themes.cpp:891
ThemeGood
int ThemeGood[4]
Definition: themes.cpp:27
DTYPE_CATHEDRAL
@ DTYPE_CATHEDRAL
Definition: enums.h:1869
OBJ_BARREL
@ OBJ_BARREL
Definition: enums.h:2386
random_
int random_(BYTE idx, int v)
Main RNG function.
Definition: engine.cpp:752
THEME_NONE
@ THEME_NONE
Definition: enums.h:1966
weaponFlag
BOOL weaponFlag
Definition: themes.cpp:13
ThemeStruct
Definition: structs.h:1160
CheckThemeObj3
BOOL CheckThemeObj3(int xp, int yp, int t, int f)
Definition: themes.cpp:182
SpecialThemeFit
BOOL SpecialThemeFit(int i, int t)
Definition: themes.cpp:273
Q_ZHAR
@ Q_ZHAR
Definition: enums.h:2551
SpawnSkeleton
BOOL SpawnSkeleton(int ii, int x, int y)
Definition: monster.cpp:5305
dMonster
int dMonster[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:17
DEVILUTION_BEGIN_NAMESPACE
Definition: sha.cpp:10
BFLAG_POPULATED
@ BFLAG_POPULATED
Definition: enums.h:1880
MAXTHEMES
#define MAXTHEMES
Definition: defs.h:36
OBJ_TEARFTN
@ OBJ_TEARFTN
Definition: enums.h:2411
OBJ_CAULDRON
@ OBJ_CAULDRON
Definition: enums.h:2409
AddObject
void AddObject(int ot, int ox, int oy)
Definition: objects.cpp:1326
Theme_MonstPit
void Theme_MonstPit(int t)
Theme_MonstPit initializes the monster pit theme.
Definition: themes.cpp:573
dFlags
char dFlags[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:56
Theme_Torture
void Theme_Torture(int t)
Theme_Torture initializes the torture theme.
Definition: themes.cpp:764
numtrigs
int numtrigs
Definition: trigs.cpp:7
Theme_Decap
void Theme_Decap(int t)
Theme_Decap initializes the decapitated theme.
Definition: themes.cpp:802
trm3x
int trm3x[9]
Definition: themes.cpp:45
IsGoat
BOOL IsGoat(int mt)
Definition: monster.cpp:5260
themeVar1
int themeVar1
Definition: themes.cpp:21
OBJ_ARMORSTANDN
@ OBJ_ARMORSTANDN
Definition: enums.h:2407
leveltype
BYTE leveltype
Definition: gendung.cpp:39
trm5y
int trm5y[25]
Definition: themes.cpp:37
OBJ_BOOKCANDLE
@ OBJ_BOOKCANDLE
Definition: enums.h:2394
OBJ_PURIFYINGFTN
@ OBJ_PURIFYINGFTN
Definition: enums.h:2405
trm5x
int trm5x[25]
Definition: themes.cpp:29
cauldronFlag
BOOL cauldronFlag
Definition: themes.cpp:16
Theme_BloodFountain
void Theme_BloodFountain(int t)
Theme_BloodFountain initializes the blood fountain theme.
Definition: themes.cpp:788
IsSkel
BOOL IsSkel(int mt)
Definition: monster.cpp:5253
THEME_TORTURE
@ THEME_TORTURE
Definition: enums.h:1955