1 /* $Id$ */
2 /* File: monster.c */
3
4 /* Purpose: misc code for monsters */
5
6 /*
7 * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
8 *
9 * This software may be copied and distributed for educational, research, and
10 * not for profit purposes provided that this copyright and statement are
11 * included in all such copies.
12 */
13
14 #define SERVER
15
16
17 #include "angband.h"
18
19 /*
20 * Chance of cloned ego monster being the same ego type, in percent. [50]
21 */
22 #define CLONE_EGO_CHANCE 15
23
24 /*
25 * Descriptions from PernAngband. - Jir -
26 */
27 #define MAX_HORROR 20
28 #define MAX_FUNNY 22
29 #define MAX_COMMENT 5
30
31 /* Debug spawning of a particular monster */
32 //#define PMO_DEBUG RI_SAURON
33
34 /* Nerf summoning for the specific case of summoning Bloodletters of Khorne?
35 This avoids instant-ko in cases where the player might've been unlucky. */
36 #define BLOODLETTER_SUMMON_NERF
37
38
39 static cptr horror_desc[MAX_HORROR] = {
40 "abominable",
41 "abysmal",
42 "appalling",
43 "baleful",
44 "blasphemous",
45
46 "disgusting",
47 "dreadful",
48 "filthy",
49 "grisly",
50 "hideous",
51
52 "hellish",
53 "horrible",
54 "infernal",
55 "loathsome",
56 "nightmarish",
57
58 "repulsive",
59 "sacrilegious",
60 "terrible",
61 "unclean",
62 "unspeakable",
63 };
64
65 static cptr funny_desc[MAX_FUNNY] = {
66 "silly",
67 "hilarious",
68 "absurd",
69 "insipid",
70 "ridiculous",
71
72 "laughable",
73 "ludicrous",
74 "far-out",
75 "groovy",
76 "postmodern",
77
78 "fantastic",
79 "dadaistic",
80 "cubistic",
81 "cosmic",
82 "awesome",
83
84 "incomprehensible",
85 "fabulous",
86 "amazing",
87 "incredible",
88 "chaotic",
89
90 "wild",
91 "preposterous",
92 };
93
94 static cptr funny_comments[MAX_COMMENT] = {
95 "Wow, cosmic, man!",
96 "Rad!",
97 "Groovy!",
98 "Cool!",
99 "Far out!"
100 };
101
102
103 static monster_race* race_info_idx(int r_idx, int ego, int randuni);
104 int pick_ego_monster(int r_idx, int Level);
105
106
107 /* Monster gain a few levels ? */
monster_check_experience(int m_idx,bool silent)108 int monster_check_experience(int m_idx, bool silent) {
109 u32b i, try;
110 u32b levels_gained = 0, levels_gained_tmp = 0, levels_gained_melee = 0, tmp_dice, tmp;
111 monster_type *m_ptr = &m_list[m_idx];
112 monster_race *r_ptr = race_inf(m_ptr);
113 int old_level = m_ptr->level;
114 bool levup = FALSE;
115
116 /* Gain levels while possible */
117 while ((m_ptr->level < MONSTER_LEVEL_MAX) &&
118 (m_ptr->exp >= (MONSTER_EXP(m_ptr->level + 1)))) {
119 /* Gain a level */
120 m_ptr->level++;
121 levup = TRUE;
122
123 #if 0 /* Check the return code now for level ups */
124 if (m_ptr->owner ) {
125 for (i = 1; i <= NumPlayers; i++) {
126 if (Players[i]->id == m_ptr->owner)
127 msg_print(i, "\377UYour pet looks more experienced!");
128 }
129 }
130 #endif
131
132 /* Gain hp */
133 if (magik(90)) {
134 m_ptr->maxhp += (r_ptr->hside * r_ptr->hdice) / 20;//10
135 m_ptr->hp += (r_ptr->hside * r_ptr->hdice) / 20;//10
136 }
137
138 /* Gain speed */
139 if (magik(50)) { //30
140 int speed = randint(2);
141 /* adjust cur and base speed */
142 m_ptr->speed += speed;
143 m_ptr->mspeed += speed;
144
145 /* fix -- never back to 0 */
146 if (m_ptr->speed < speed) m_ptr->speed = 66;/* and never forward to insanity :) */
147 if (m_ptr->mspeed < speed) m_ptr->mspeed = 66;
148 }
149
150 /* Gain ac */
151 if (magik(30)) {
152 m_ptr->ac += (r_ptr->ac / 15)?r_ptr->ac / 15:1;
153 }
154
155 /* Gain melee power */
156 /* XXX 20d1 monster can be too horrible (20d5) */
157 // if (magik(50))
158 if (magik(80)) levels_gained++;
159 }
160
161 /* flatten the curve for very high monster levels (+27 nether realm) */
162 /* +1000: (40 -> 28, 35 -> ,) 30 -> 23, 25 -> , 20 -> 16, 15 -> , 10 -> 9, 5 -> 4 */
163 /* +1500: (40 -> 25, 35 -> 23,) 30 -> 20, 25 -> 18, 20 -> 15, 15 -> 12, 10 -> 8, 5 -> 4 */
164 /* +2000: (40 -> 22, 35 -> ,) 30 -> 18, 25 -> , 20 -> 14, 15 -> , 10 -> 7, 5 -> 4 */
165 /* +3000: (40 -> 18, 35 -> ,) 30 -> 15, 25 -> , 20 -> 12, 15 -> , 10 -> 7, 5 -> 4 */
166 /* L+40 -> x25, L+35 -> x20, L+30 -> x16, L+25 -> x12, L+20 -> x9, L+15 -> x6, L+10 -> x4, L+5 -> x2 */
167 if (levels_gained != 0) levels_gained = 100000 / ((100000 / levels_gained) + 1000);
168 /* cap stronger for higher monsters */
169 // if (levels_gained != 0) levels_gained = 100000 / ((100000 / levels_gained) + 1000 - (10000/(r_ptr->level+10)));
170
171 /* for more accurate results, add 2 figures */
172 levels_gained *= 100;
173 /* for +20 levels_gained -> double the melee damage output, store the multiplier in levels_gained */
174 levels_gained /= 25; /* +25 -> +1x */
175 /* at least x1 */
176 levels_gained += 100;
177
178 /* very low level monsters get a boost for damage output */
179 // levels_gained += 1600 / (r_ptr->level + 10);
180 levels_gained += ((levels_gained - 100) * 57) / (r_ptr->level + 10);
181
182 /* calculate square root of the factor, to apply to dice & dice sides - C. Blue */
183 tmp = levels_gained;
184 tmp *= 1000;
185 levels_gained_tmp = 1;
186 while (tmp > 1000) {
187 tmp *= 1000;
188 tmp /= 1320;
189 levels_gained_tmp *= 1149;
190 if (levels_gained_tmp >= 1000000) levels_gained_tmp /= 1000;
191 }
192 /* keep some figures for more accuracy (instead of / 1000) */
193 levels_gained_tmp /= 100; /* now is value * 100. so we have 2 extra accuracy figures */
194
195 for (i = 0; i < 4; i++) {
196 /* to fix rounding issues and prevent super monsters (2d50 -> 3d50 at +1 level) */
197 tmp_dice = m_ptr->blow[i].d_dice;
198 if (!tmp_dice) continue;
199
200 /* Add a limit for insanity attacks */
201 //disabled this, instead I just weakened Water Demons! - C. Blue - if (m_ptr->blow[i].effect == RBE_SANITY) levels_gained_melee /= 2;
202 levels_gained_melee = levels_gained_tmp;
203
204 /* take care of not messing up the cut/stun chance of that monster (ie d_dice 1 or 2).
205 Note that such a monster may gain 4/3 of the usual damage increase. (the average of (4*66)d1 is 4/3 of the average of (2*66)d2) */
206 if (m_ptr->blow[i].d_dice > 2) {
207 /* if d_side is 1 or 2, for cut/stun, load all the level boost onto the d_dice instead.
208 NOTE: Obviously for d2 attacks this is actually totally not needed, since d2 attacks are extremly
209 unlikely to ever reach critical damage, unlike 2d attacks, for which it's pretty important. */
210 if (m_ptr->blow[i].d_side == 1) {
211 levels_gained_melee = (levels_gained_tmp * levels_gained_tmp) / 100;
212
213 /* compensate the 4/3 damage increasing factor -- note: there may be extreme discrete jumps in damage
214 for the actual resulting monster, depending on level boost steps, making it not look like a 3/4 compensation.
215 We hope it's still a correct calculation on average though somehow =P */
216 if (m_ptr->blow[i].d_side == 1) levels_gained_melee = (levels_gained_melee * 3) / 4;
217
218 /* underflow protection! (white ant hits for 1d255..) */
219 if (levels_gained_melee < 100) levels_gained_melee = 100;
220 }
221
222 /* round dice downwards */
223 tmp = m_ptr->blow[i].d_dice + (m_ptr->blow[i].d_dice * (levels_gained_melee - 100) / 100);
224 /* catch overflow */
225 if (tmp > 255) tmp = 255;
226 m_ptr->blow[i].d_dice = tmp;
227
228 /* Catch rounding problems */
229 levels_gained_melee = (((m_ptr->blow[i].d_dice - tmp_dice) * 100) / tmp_dice) + 100;
230 levels_gained_melee = (levels_gained_tmp * levels_gained_tmp) / (levels_gained_melee);
231 } else {
232 levels_gained_melee = (levels_gained_tmp * levels_gained_tmp) / 100; /* if d_dice was 1, for cut/stun, load them all onto the d_side instead */
233
234 /* compensate the 4/3 damage increasing factor -- note: there may be extreme discrete jumps in damage
235 for the actual resulting monster, depending on level boost steps, making it not look like a 3/4 compensation.
236 We hope it's still a correct calculation on average though somehow =P */
237 if (m_ptr->blow[i].d_dice == 1) levels_gained_melee = (levels_gained_melee * 3) / 4;
238 /* else == 2 : d2 -> d3 is only ~9/8 increase, which is probably neglibible */
239
240 /* underflow protection! (white ant hits for 1d255..) */
241 if (levels_gained_melee < 100) levels_gained_melee = 100;
242 }
243
244 /* take care of not messing up the cut/stun chance of that monster (ie d_side 1 or 2).
245 Note that such a monster may gain 4/3 of the usual damage increase. (the average of (4*66)d1 is 4/3 of the average of (2*66)d2) */
246 if (m_ptr->blow[i].d_side != 1) {
247 /* round sides upwards sometimes */
248 if (((m_ptr->blow[i].d_side * (levels_gained_melee - 100) / 100) * 100) <
249 (m_ptr->blow[i].d_side * (levels_gained_melee - 100))) {
250 /* Don't round up for very low monsters, or they become very hard for low players at 7 levels ood */
251 tmp = m_ptr->blow[i].d_side + (m_ptr->blow[i].d_side * (levels_gained_melee - 100) / 100) + (r_ptr->level > 20 ? 1 : 0);
252 /* catch overflow */
253 if (tmp > 255) tmp = 255;
254 m_ptr->blow[i].d_side = tmp;
255 } else {
256 tmp = m_ptr->blow[i].d_side + (m_ptr->blow[i].d_side * (levels_gained_melee - 100) / 100);
257 /* catch overflow */
258 if (tmp > 255) tmp = 255;
259 m_ptr->blow[i].d_side = tmp;
260 }
261 }
262 }
263
264 /* Insanity caps */
265 for (i = 0; i < 4; i++) {
266 if ((m_ptr->blow[i].effect == RBE_SANITY) && m_ptr->blow[i].d_dice && m_ptr->blow[i].d_side) {
267 while (((m_ptr->blow[i].d_dice + 1) * m_ptr->blow[i].d_side) / 2 > 55) {
268 if (m_ptr->blow[i].d_dice >= m_ptr->blow[i].d_side)
269 m_ptr->blow[i].d_dice--;
270 else
271 m_ptr->blow[i].d_side--;
272 }
273 }
274 }
275
276 /* Sanity caps */
277 while (TRUE) {
278 tmp = 0; try = 0;
279 for (i = 0; i < 4; i++) {
280 /* Look for attacks */
281 if ((!m_ptr->blow[i].d_dice) || (!m_ptr->blow[i].d_side)) continue;
282 /* Add up to total damage counter (average) */
283 tmp += ((m_ptr->blow[i].d_dice + 1) * m_ptr->blow[i].d_side) / 2;
284 /* Skip non-powerful attacks */
285 if (((m_ptr->blow[i].d_dice + 1) * m_ptr->blow[i].d_side) / 2 <= 125) continue;
286 /* Count number of powerful attacks */
287 try++;
288 }
289 if (tmp <= AVG_MELEE_CAP) break;
290 /* Randomly pick one of the attacks to lower */
291 try = randint(try);
292 tmp = 0;
293 for (i = 0; i < 4; i++) {
294 if ((!m_ptr->blow[i].d_dice) || (!m_ptr->blow[i].d_side)) continue;
295 if (((m_ptr->blow[i].d_dice + 1) * m_ptr->blow[i].d_side) / 2 <= 125) continue;
296 tmp++;
297 if (tmp == try) {
298 /* Don't reduce by too great steps */
299 if (m_ptr->blow[i].d_dice <= 10) m_ptr->blow[i].d_side--;
300 else if (m_ptr->blow[i].d_side <= 10) m_ptr->blow[i].d_dice--;
301 /* Otherwise reduce randomly */
302 else if (rand_int(2)) m_ptr->blow[i].d_side--;
303 else m_ptr->blow[i].d_dice--;
304 }
305 }
306 }
307
308 /* Adjust monster cur speed to new base speed on levelup
309 (as a side effect, resetting possible GF_OLD_SLOW effects and similar - doesn't matter really). */
310 if (levup) m_ptr->mspeed = m_ptr->speed;
311
312 return (old_level - m_ptr->level == 0 ? 0 : 1);
313 }
314
315 /* Monster gain some xp */
monster_gain_exp(int m_idx,u32b exp,bool silent)316 int monster_gain_exp(int m_idx, u32b exp, bool silent) {
317 monster_type *m_ptr = &m_list[m_idx];
318
319 m_ptr->exp += exp;
320
321 return monster_check_experience(m_idx, silent);
322 }
323
324
325 /*
326 * Delete a monster by index.
327 *
328 * This function causes the given monster to cease to exist for
329 * all intents and purposes. The monster record is left in place
330 * but the record is wiped, marking it as "dead" (no race index)
331 * so that it can be "skipped" when scanning the monster array,
332 * and "excised" from the "m_fast" array when needed.
333 *
334 * Thus, anyone who makes direct reference to the "m_list[]" array
335 * using monster indexes that may have become invalid should be sure
336 * to verify that the "r_idx" field is non-zero. All references
337 * to "m_list[c_ptr->m_idx]" are guaranteed to be valid, see below.
338 */
delete_monster_idx(int i,bool unfound_arts)339 void delete_monster_idx(int i, bool unfound_arts) {
340 int x, y, Ind;
341 struct worldpos *wpos;
342 cave_type **zcave;
343 monster_type *m_ptr = &m_list[i];
344 u16b this_o_idx, next_o_idx = 0;
345
346 monster_race *r_ptr = race_inf(m_ptr);
347
348 /* Get location */
349 y = m_ptr->fy;
350 x = m_ptr->fx;
351 wpos = &m_ptr->wpos;
352
353 /* maybe log to be safe */
354 if (m_ptr->questor)
355 s_printf("delete_monster_idx: Deleting questor (midx%d,Q%d,qidx%d) at %d,%d,%d.\n", i, m_ptr->quest, m_ptr->questor_idx, wpos->wx, wpos->wy, wpos->wz);
356
357 #ifdef MONSTER_ASTAR
358 if ((r_ptr->flags0 & RF0_ASTAR) && (m_ptr->astar_idx != -1))
359 astar_info_open[m_ptr->astar_idx].m_idx = -1;
360 #endif
361
362 /* Hack -- Reduce the racial counter */
363 if (r_ptr->cur_num != 0) /* don't overflow - mikaelh */
364 r_ptr->cur_num--;
365
366 /* Hack -- count the number of "reproducers" */
367 if (r_ptr->flags7 & RF7_MULTIPLY) num_repro--;
368
369
370 /* Remove him from everybody's view */
371 for (Ind = 1; Ind < NumPlayers + 1; Ind++)
372 {
373 /* Skip this player if he isn't playing */
374 if (Players[Ind]->conn == NOT_CONNECTED) continue;
375 #ifdef RPG_SERVER
376 if (Players[Ind]->id == m_ptr->owner && m_ptr->pet) {
377 msg_print(Ind, "\377RYour pet has died! You feel sad.");
378 Players[Ind]->has_pet = 0;
379 }
380 #endif
381 Players[Ind]->mon_vis[i] = FALSE;
382 Players[Ind]->mon_los[i] = FALSE;
383
384 /* Hack -- remove target monster */
385 if (i == Players[Ind]->target_who) Players[Ind]->target_who = 0;
386
387 /* Hack -- remove tracked monster */
388 if (i == Players[Ind]->health_who) health_track(Ind, 0);
389 }
390
391
392 /* Monster is gone */
393 /* Make sure the level is allocated, it won't be if we are
394 * clearing an abandoned wilderness level of monsters
395 */
396 if ((zcave = getcave(wpos)))
397 zcave[y][x].m_idx = 0;
398
399 /* Visual update */
400 everyone_lite_spot(wpos, y, x);
401
402 #ifdef MONSTER_INVENTORY
403 /* Delete objects */
404 for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
405 {
406 object_type *o_ptr;
407
408 /* Acquire object */
409 o_ptr = &o_list[this_o_idx];
410
411 /* Acquire next object */
412 next_o_idx = o_ptr->next_o_idx;
413
414 /* Hack -- efficiency */
415 o_ptr->held_m_idx = 0;
416
417 /* Delete the object */
418 delete_object_idx(this_o_idx, unfound_arts);
419 }
420 #endif // MONSTER_INVENTORY
421
422 /* terminate mindcrafter charm effect */
423 if (m_ptr->charmedignore) {
424 Players[m_ptr->charmedignore]->mcharming--;
425 m_ptr->charmedignore = 0;
426 }
427
428 /* Wipe the Monster */
429 FREE(m_ptr->r_ptr, monster_race);
430 WIPE(m_ptr, monster_type);
431 }
432
433
434 /*
435 * Delete the monster, if any, at a given location
436 */
delete_monster(struct worldpos * wpos,int y,int x,bool unfound_arts)437 void delete_monster(struct worldpos *wpos, int y, int x, bool unfound_arts)
438 {
439 cave_type *c_ptr;
440
441 /* Paranoia */
442 cave_type **zcave;
443 if (!in_bounds(y, x)) return;
444 if((zcave = getcave(wpos))){
445 /* Check the grid */
446 c_ptr = &zcave[y][x];
447 /* Delete the monster (if any) */
448 if (c_ptr->m_idx > 0) delete_monster_idx(c_ptr->m_idx, unfound_arts);
449 }
450 else{ /* still delete the monster, just slower method */
451 int i;
452 for(i = 0; i < m_max; i++){
453 monster_type *m_ptr = &m_list[i];
454 if(m_ptr->r_idx && inarea(wpos, &m_ptr->wpos))
455 {
456 if(y == m_ptr->fy && x == m_ptr->fx)
457 delete_monster_idx(i, unfound_arts);
458 }
459 }
460 }
461 }
462
463
464 /*
465 * Compact and Reorder the monster list
466 *
467 * This function can be very dangerous, use with caution!
468 *
469 * When actually "compacting" monsters, we base the saving throw
470 * on a combination of monster level, distance from player, and
471 * current "desperation".
472 *
473 * After "compacting" (if needed), we "reorder" the monsters into a more
474 * compact order, and we reset the allocation info, and the "live" array.
475 */
476 /*
477 * if 'purge', non-allocated wilderness monsters will be purged.
478 */
compact_monsters(int size,bool purge)479 void compact_monsters(int size, bool purge) {
480 int i, num, cnt, Ind;
481 int cur_lev, cur_dis, chance;
482 cave_type **zcave;
483 struct worldpos *wpos;
484 quest_info *q_ptr;
485
486 u16b this_o_idx, next_o_idx = 0;
487
488 /* Message (only if compacting) */
489 if (size) s_printf("Compacting monsters...\n");
490
491 /* Compact at least 'size' objects */
492 for (num = 0, cnt = 1; num < size; cnt++) {
493 /* Get more vicious each iteration */
494 cur_lev = 5 * cnt;
495
496 /* Get closer each iteration */
497 cur_dis = 5 * (20 - cnt);
498
499 /* Check all the monsters */
500 for (i = 1; i < m_max; i++) {
501 monster_type *m_ptr = &m_list[i];
502 monster_race *r_ptr = race_inf(m_ptr);
503
504 /* Paranoia -- skip "dead" monsters */
505 if (!m_ptr->r_idx) continue;
506
507 #if 0
508 /* Skip monsters that are 'trapped' in houses */
509 // & CAVE_ICKY
510 // if((zcave = getcave(wpos))) zcave[ny][nx].m_idx = i;
511 #else
512 /* Skip golems/pets */
513 if (m_ptr->pet || m_ptr->owner) continue;
514 #endif
515
516 /* Skip questors (new quest_info) */
517 if (m_ptr->questor) continue;
518
519 /* Skip special hard-coded monsters (target dummy, invis dummy, santa) */
520 if (r_info[m_ptr->r_idx].flags8 & RF8_GENO_NO_THIN) continue;
521
522 /* Hack -- High level monsters start out "immune" */
523 if (r_ptr->level > cur_lev) continue;
524
525 /* Ignore nearby monsters */
526 if ((cur_dis > 0) && (m_ptr->cdis < cur_dis)) continue;
527
528 /* Saving throw chance */
529 chance = 90;
530
531 /* Only compact "Quest" Monsters in emergencies */
532 if ((r_ptr->flags1 & RF1_QUESTOR) && (cnt < 1000)) chance = 100;
533
534 /* Try not to compact Unique Monsters */
535 if (r_ptr->flags1 & RF1_UNIQUE) chance = 99;
536
537 /* Monsters in town don't have much of a chance */
538 if (istown(&m_ptr->wpos)) chance = 70;
539
540 // if (!getcave(&m_ptr->wpos)) chance = 0;
541
542 /* All monsters get a saving throw */
543 if (rand_int(100) < chance) continue;
544
545 /* Delete the monster */
546 delete_monster_idx(i, TRUE);
547
548 /* Count the monster */
549 num++;
550 }
551 }
552
553
554 /* Excise dead monsters (backwards!) */
555 for (i = m_max - 1; i >= 1; i--) {
556 /* Get the i'th monster */
557 monster_type *m_ptr = &m_list[i];
558
559 /* Skip real monsters */
560 /* real monsters in unreal location are not skipped. */
561 if (m_ptr->r_idx) {
562 /* Skip golems/pets/questors always
563 NOTE: This will even keep them alive in the dungeon although
564 the dungeon floor might've gotten deallocated already. */
565 if (m_ptr->pet || m_ptr->owner || m_ptr->questor) continue;
566
567 if ((!m_ptr->wpos.wz && !purge) || getcave(&m_ptr->wpos) || sustained_wpos(&m_ptr->wpos)) continue;
568
569 /* Delete the monster */
570 delete_monster_idx(i, TRUE);
571 }
572
573 /* One less monster */
574 m_max--;
575
576 /* Reorder */
577 if (i != m_max) {
578 int ny = m_list[m_max].fy;
579 int nx = m_list[m_max].fx;
580 wpos = &m_list[m_max].wpos;
581
582 /* Update the cave */
583 /* Hack -- make sure the level is allocated, as in the wilderness
584 it sometimes will not be */
585 if((zcave = getcave(wpos))) zcave[ny][nx].m_idx = i;
586
587 #ifdef MONSTER_INVENTORY
588 /* Repair objects being carried by monster */
589 #if 0
590 /* No point in this... - mikaelh */
591 for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
592 #else
593 /* Shouldn't it be this way? - mikaelh */
594 for (this_o_idx = m_list[m_max].hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
595 #endif
596 {
597 object_type *o_ptr;
598
599 /* Acquire object */
600 o_ptr = &o_list[this_o_idx];
601
602 /* Acquire next object */
603 next_o_idx = o_ptr->next_o_idx;
604
605 /* Reset monster pointer */
606 o_ptr->held_m_idx = i;
607 }
608 #endif // MONSTER_INVENTORY
609
610 /* Structure copy */
611 m_list[i] = m_list[m_max];
612
613 /* Quests: keep questor_m_idx information consistent */
614 if (m_list[i].questor) {
615 q_ptr = &q_info[m_list[i].quest];
616 /* paranoia check, after server restarted after heavy code changes or sth */
617 if (q_ptr->defined && q_ptr->questors > m_list[i].questor_idx) {
618 /* fix its index */
619 #if 0
620 s_printf("QUEST_COMPACT_MONSTERS: quest %d - questor %d m_idx %d->%d\n", m_list[i].quest, m_list[i].questor_idx, q_ptr->questor[m_list[i].questor_idx].mo_idx, i);
621 #endif
622 q_ptr->questor[m_list[i].questor_idx].mo_idx = i;
623 } else {
624 s_printf("QUEST_COMPACT_MONSTERS: deprecated questor, quest %d - questor %d m_idx %d->%d\n", m_list[i].quest, m_list[i].questor_idx, q_ptr->questor[m_list[i].questor_idx].mo_idx, i);
625 m_list[i].questor = FALSE;
626 m_list[i].quest = 0; //not necessary unlike for object-questors, but cleaner anyway!
627 /* delete it too? */
628 }
629 }
630
631 /* Copy the visibility and los flags for the players */
632 for (Ind = 1; Ind < NumPlayers + 1; Ind++) {
633 if (Players[Ind]->conn == NOT_CONNECTED) continue;
634
635 Players[Ind]->mon_vis[i] = Players[Ind]->mon_vis[m_max];
636 Players[Ind]->mon_los[i] = Players[Ind]->mon_los[m_max];
637
638 /* Hack -- Update the target */
639 if (Players[Ind]->target_who == (int)(m_max)) Players[Ind]->target_who = i;
640
641 /* Hack -- Update the health bar */
642 if (Players[Ind]->health_who == (int)(m_max)) health_track(Ind, i);
643 }
644
645 /* Wipe the hole */
646 WIPE(&m_list[m_max], monster_type);
647 }
648 }
649
650 /* Reset "m_nxt" */
651 m_nxt = m_max;
652
653
654 /* Reset "m_top" */
655 m_top = 0;
656
657 /* Collect "live" monsters */
658 for (i = 0; i < m_max; i++) {
659 /* Collect indexes */
660 m_fast[m_top++] = i;
661 }
662 }
663
664
665 /*
666 * Delete/Remove all the monsters when the player leaves the level
667 *
668 * This is an efficient method of simulating multiple calls to the
669 * "delete_monster()" function, with no visual effects.
670 *
671 * Note that this only deletes monsters that on the specified depth
672 */
wipe_m_list(struct worldpos * wpos)673 void wipe_m_list(struct worldpos *wpos) {
674 int i;
675
676 /* Delete all the monsters */
677 for (i = m_max - 1; i >= 1; i--) {
678 monster_type *m_ptr = &m_list[i];
679
680 if (inarea(&m_ptr->wpos,wpos)) {
681 if (season_halloween &&
682 (m_ptr->r_idx == RI_PUMPKIN1 || m_ptr->r_idx == RI_PUMPKIN2 || m_ptr->r_idx == RI_PUMPKIN3)) {
683 great_pumpkin_timer = rand_int(2); /* fast respawn if not killed! */
684 //s_printf("HALLOWEEN: Pumpkin set to fast respawn\n");
685 }
686 delete_monster_idx(i, TRUE);
687 }
688 }
689
690 /* Compact the monster list */
691 compact_monsters(0, FALSE);
692 }
693 /* For /geno command: Wipes all monsters except for pets, golems and questors */
wipe_m_list_admin(struct worldpos * wpos)694 void wipe_m_list_admin(struct worldpos *wpos) {
695 int i;
696
697 /* Delete all the monsters */
698 for (i = m_max - 1; i >= 1; i--) {
699 monster_type *m_ptr = &m_list[i];
700
701 if (m_ptr->pet || m_ptr->special || m_ptr->questor) continue;
702
703 if (inarea(&m_ptr->wpos,wpos)) {
704 if (season_halloween &&
705 (m_ptr->r_idx == RI_PUMPKIN1 || m_ptr->r_idx == RI_PUMPKIN2 || m_ptr->r_idx == RI_PUMPKIN3)) {
706 great_pumpkin_timer = rand_int(2); /* fast respawn if not killed! */
707 //s_printf("HALLOWEEN: Pumpkin set to fast respawn\n");
708 }
709 delete_monster_idx(i, TRUE);
710 }
711 }
712
713 /* Compact the monster list */
714 compact_monsters(0, FALSE);
715 }
716 /* Exactly like wipe_m_list() but actually makes exceptions for special dungeon floors. - C. Blue
717 Special means: Static IDDC town floor. (Could maybe be used for quests too in some way.) */
wipe_m_list_special(struct worldpos * wpos)718 void wipe_m_list_special(struct worldpos *wpos) {
719 int i;
720
721 /* main purpose: keep target dummies alive */
722 if (sustained_wpos(wpos)) return;
723
724 /* Delete all the monsters */
725 for (i = m_max - 1; i >= 1; i--) {
726 monster_type *m_ptr = &m_list[i];
727
728 if (inarea(&m_ptr->wpos,wpos)) {
729 if (season_halloween &&
730 (m_ptr->r_idx == RI_PUMPKIN1 || m_ptr->r_idx == RI_PUMPKIN2 || m_ptr->r_idx == RI_PUMPKIN3)) {
731 great_pumpkin_timer = rand_int(2); /* fast respawn if not killed! */
732 //s_printf("HALLOWEEN: Pumpkin set to fast respawn\n");
733 }
734 delete_monster_idx(i, TRUE);
735 }
736 }
737
738 /* Compact the monster list */
739 compact_monsters(0, FALSE);
740 }
741 /* Avoid overcrowding of towns - C. Blue */
thin_surface_spawns()742 void thin_surface_spawns() {
743 int i;
744 player_type *p_ptr;
745 cave_type **zcave;
746
747 /* Delete all the monsters, except for dummies and santa,
748 because those are usually in town, and this function is called periodically for towns. */
749 for (i = m_max - 1; i >= 1; i--) {
750 monster_type *m_ptr = &m_list[i];
751
752 /* Only affect surface monsters, and only 20% of them (randomly) */
753 // if ((m_ptr->wpos.wz != 0) || !magik(20)) continue; //high towns end up pretty empty, even if a player idles for hours
754 if ((m_ptr->wpos.wz != 0) || !magik(10)) continue; //<testing>
755
756 /* Skip monsters that are 'trapped' in houses */
757 if (!(zcave = getcave(&m_ptr->wpos))) continue;
758 if (zcave[m_ptr->fy][m_ptr->fx].info & CAVE_ICKY) continue;
759
760 /* Skip golems/pets/questors */
761 if (m_ptr->pet || m_ptr->owner || m_ptr->questor) continue;
762
763 /* special ones aren't to be touched */
764 if (r_info[m_ptr->r_idx].flags8 & RF8_GENO_NO_THIN) continue;
765
766 /* new: Don't affect monsters in LOS of a player, doesn't look good */
767 if (m_ptr->closest_player && m_ptr->closest_player <= NumPlayers) {
768 p_ptr = Players[m_ptr->closest_player];
769 if (p_ptr->admin_dm ||
770 (inarea(&p_ptr->wpos, &m_ptr->wpos) &&
771 los(&p_ptr->wpos, p_ptr->py, p_ptr->px, m_ptr->fy, m_ptr->fx)))
772 continue;
773 }
774
775 /* if we erase the Great Pumpkin then reset its timer */
776 if (season_halloween &&
777 (m_ptr->r_idx == RI_PUMPKIN1 || m_ptr->r_idx == RI_PUMPKIN2 || m_ptr->r_idx == RI_PUMPKIN3)) {
778 great_pumpkin_timer = rand_int(2); /* fast respawn if not killed! */
779 //s_printf("HALLOWEEN: Pumpkin set to fast respawn\n");
780 }
781
782 /* hack: don't affect non-townies in Bree at all */
783 if (in_bree(&m_ptr->wpos) && m_ptr->level)
784 continue;
785
786 /* erase the monster, poof */
787 delete_monster_idx(i, TRUE);
788 }
789
790 /* Compact the monster list */
791 compact_monsters(0, FALSE);
792 }
793 /* Wipe all monsters in towns. (For seasonal events: Halloween) */
geno_towns()794 void geno_towns() {
795 int i;
796
797 /* Delete all the monsters, except for target dummies and grid-occupying dummy */
798 for (i = m_max - 1; i >= 1; i--) {
799 monster_type *m_ptr = &m_list[i];
800
801 if (istown(&m_ptr->wpos) &&
802 !(r_info[m_ptr->r_idx].flags8 & RF8_GENO_PERSIST)) {
803 if (season_halloween && /* hardcoded -_- */
804 (m_ptr->r_idx == RI_PUMPKIN1 || m_ptr->r_idx == RI_PUMPKIN2 || m_ptr->r_idx == RI_PUMPKIN3)) {
805 great_pumpkin_timer = rand_int(2); /* fast respawn if not killed! */
806 //s_printf("HALLOWEEN: Pumpkin set to fast respawn\n");
807 }
808 delete_monster_idx(i, TRUE);
809 }
810 }
811
812 /* Compact the monster list */
813 compact_monsters(0, FALSE);
814 }
815 /* only wipes monsters not on CAVE_ICKY, on a certain dungeon/world level.
816 Created for pvp arena, to clear previous spawn on releasing next one. - C. Blue */
wipe_m_list_roaming(struct worldpos * wpos)817 void wipe_m_list_roaming(struct worldpos *wpos)
818 {
819 int i;
820 cave_type **zcave;
821 if(!(zcave = getcave(wpos))) return;
822 for (i = m_max - 1; i >= 1; i--) {
823 monster_type *m_ptr = &m_list[i];
824 if (inarea(&m_ptr->wpos,wpos)) {
825 if (zcave[m_ptr->fy][m_ptr->fx].info & CAVE_ICKY) continue;
826 delete_monster_idx(i, TRUE);
827 }
828 }
829 /* Compact the monster list */
830 compact_monsters(0, FALSE);
831 }
832
833 /*
834 * Heal up every monster on the depth, so that a player
835 * cannot abuse stair-GoI and anti-scum. - Jir -
836 */
837 #if 0
838 void heal_m_list(struct worldpos *wpos)
839 {
840 int i;
841
842 /* Heal all the monsters */
843 for (i = m_max - 1; i >= 1; i--)
844 {
845 monster_type *m_ptr = &m_list[i];
846
847 if (inarea(&m_ptr->wpos,wpos))
848 m_ptr->hp = m_ptr->maxhp;
849 // delete_monster_idx(i);
850 }
851
852 /* Compact the monster list */
853 // compact_monsters(0);
854 }
855 #endif // 0
856
857
858 /*
859 * Acquires and returns the index of a "free" monster.
860 *
861 * This routine should almost never fail, but it *can* happen.
862 *
863 * Note that this function must maintain the special "m_fast"
864 * array of indexes of "live" monsters.
865 */
m_pop(void)866 s16b m_pop(void)
867 {
868 int i, n, k;
869
870
871 /* Normal allocation */
872 if (m_max < MAX_M_IDX)
873 {
874 /* Access the next hole */
875 i = m_max;
876
877 /* Expand the array */
878 m_max++;
879
880 /* Update "m_fast" */
881 m_fast[m_top++] = i;
882
883 /* Return the index */
884 return (i);
885 }
886
887
888 /* Check for some space */
889 for (n = 1; n < MAX_M_IDX; n++)
890 {
891 /* Get next space */
892 i = m_nxt;
893
894 /* Advance (and wrap) the "next" pointer */
895 if (++m_nxt >= MAX_M_IDX) m_nxt = 1;
896
897 /* Skip monsters in use */
898 if (m_list[i].r_idx) continue;
899
900 /* Verify space XXX XXX */
901 if (m_top >= MAX_M_IDX) continue;
902
903 /* Verify not allocated */
904 for (k = 0; k < m_top; k++)
905 {
906 /* Hack -- Prevent errors */
907 if (m_fast[k] == i) i = 0;
908 }
909
910 /* Oops XXX XXX */
911 if (!i) continue;
912
913 /* Update "m_fast" */
914 m_fast[m_top++] = i;
915
916 /* Use this monster */
917 return (i);
918 }
919
920
921 /* Warn the player */
922 if (server_dungeon) s_printf("Too many monsters!\n");
923
924 /* Try not to crash */
925 return (0);
926 }
927
928
929 /*
930 * Some dungeon types restrict the possible monsters.
931 * Return TRUE is the monster is OK and FALSE otherwise
932 */
933 //bool apply_rule(monster_race *r_ptr, byte rule)
apply_rule(monster_race * r_ptr,rule_type * rule)934 static bool apply_rule(monster_race *r_ptr, rule_type *rule) {
935 switch (rule->mode) {
936 case DUNGEON_MODE_NONE:
937 return TRUE;
938
939 case DUNGEON_MODE_AND:
940 case DUNGEON_MODE_NAND:
941 {
942 int a;
943
944 if (rule->mflags1)
945 {
946 if((rule->mflags1 & r_ptr->flags1) != rule->mflags1)
947 return FALSE;
948 }
949 if (rule->mflags2)
950 {
951 if((rule->mflags2 & r_ptr->flags2) != rule->mflags2)
952 return FALSE;
953 }
954 if (rule->mflags3)
955 {
956 if((rule->mflags3 & r_ptr->flags3) != rule->mflags3)
957 return FALSE;
958 }
959 if (rule->mflags4)
960 {
961 if((rule->mflags4 & r_ptr->flags4) != rule->mflags4)
962 return FALSE;
963 }
964 if (rule->mflags5)
965 {
966 if((rule->mflags5 & r_ptr->flags5) != rule->mflags5)
967 return FALSE;
968 }
969 if (rule->mflags6)
970 {
971 if((rule->mflags6 & r_ptr->flags6) != rule->mflags6)
972 return FALSE;
973 }
974 if (rule->mflags7)
975 {
976 if((rule->mflags7 & r_ptr->flags7) != rule->mflags7)
977 return FALSE;
978 }
979 if (rule->mflags8)
980 {
981 if((rule->mflags8 & r_ptr->flags8) != rule->mflags8)
982 return FALSE;
983 }
984 if (rule->mflags9)
985 {
986 if((rule->mflags9 & r_ptr->flags9) != rule->mflags9)
987 return FALSE;
988 }
989 if (rule->mflags0)
990 {
991 if((rule->mflags0 & r_ptr->flags0) != rule->mflags0)
992 return FALSE;
993 }
994
995 for(a = 0; a < 5; a++)
996 {
997 if (rule->r_char[a] && (rule->r_char[a] != r_ptr->d_char)) return FALSE;
998 }
999
1000 /* All checks passed ? lets go ! */
1001 return TRUE;
1002 }
1003
1004 case DUNGEON_MODE_OR:
1005 case DUNGEON_MODE_NOR:
1006 {
1007 int a;
1008
1009 if (rule->mflags1 && (r_ptr->flags1 & rule->mflags1)) return TRUE;
1010 if (rule->mflags2 && (r_ptr->flags2 & rule->mflags2)) return TRUE;
1011 if (rule->mflags3 && (r_ptr->flags3 & rule->mflags3)) return TRUE;
1012 if (rule->mflags4 && (r_ptr->flags4 & rule->mflags4)) return TRUE;
1013 if (rule->mflags5 && (r_ptr->flags5 & rule->mflags5)) return TRUE;
1014 if (rule->mflags6 && (r_ptr->flags6 & rule->mflags6)) return TRUE;
1015 if (rule->mflags7 && (r_ptr->flags7 & rule->mflags7)) return TRUE;
1016 if (rule->mflags8 && (r_ptr->flags8 & rule->mflags8)) return TRUE;
1017 if (rule->mflags9 && (r_ptr->flags9 & rule->mflags9)) return TRUE;
1018 if (rule->mflags0 && (r_ptr->flags0 & rule->mflags0)) return TRUE;
1019
1020 for (a = 0; a < 5; a++)
1021 if (rule->r_char[a] == r_ptr->d_char) return TRUE;
1022
1023 /* All checks failled ? Sorry ... */
1024 return FALSE;
1025 }
1026
1027 default:
1028 return FALSE;
1029 }
1030 }
1031
1032
restrict_monster_to_dungeon(int r_idx,int dun_type)1033 int restrict_monster_to_dungeon(int r_idx, int dun_type) {
1034 dungeon_info_type *d_ptr = &d_info[dun_type];
1035 monster_race *r_ptr = &r_info[r_idx];
1036 int i, percents = 0, factor = 10000;
1037
1038 /* Process all rules */
1039 for (i = 0; i < 5; i++) {
1040 rule_type *rule = &d_ptr->rules[i];
1041
1042 /* Break if not valid */
1043 if (!rule->percent) break;
1044
1045 /* Apply the rule */
1046 bool rule_ret = apply_rule(r_ptr, rule);
1047
1048 /* I modified this so that inverse rules (NOR/NAND) actually
1049 cut down the 'percent' instead. This makes more sense and is
1050 especially more flexible in my opinion. - C. Blue */
1051 if (!rule_ret) continue;
1052 /* Rule broken? */
1053 if ((rule->mode == DUNGEON_MODE_NAND) || (rule->mode == DUNGEON_MODE_NOR))
1054 factor = (factor * (100 - rule->percent)) / 100;
1055 /* Rule ok? */
1056 else
1057 percents += rule->percent;
1058 }
1059
1060 /* Limit: at least 1% chance, if we shouldn't have 0% (just from rounding). */
1061 if (factor && percents && percents * factor < 10000) percents = 10000 / factor;
1062
1063 percents = (percents * factor) / 10000;
1064
1065 /* Return percentage */
1066 return percents;
1067 }
1068
1069
1070 /*
1071 * Apply a "monster restriction function" to the "monster allocation table"
1072 */
get_mon_num_prep(int dun_type,char * reject_monsters)1073 errr get_mon_num_prep(int dun_type, char *reject_monsters)
1074 {
1075 alloc_entry *table = alloc_race_table_dun[dun_type];
1076 long i, n, r_idx;
1077
1078 /* Select the table based on dungeon type */
1079 alloc_race_table = table;
1080
1081 /* Local copies of the hooks for speed */
1082 bool (*hook)(int r_idx) = get_mon_num_hook;
1083 bool (*hook2)(int r_idx) = get_mon_num2_hook;
1084
1085 if (hook && hook2) {
1086 /* Most of the time both hooks are set */
1087
1088 /* Scan the allocation table */
1089 for (i = 0, n = alloc_race_size; i < n; i++)
1090 {
1091 /* Get the entry */
1092 alloc_entry *entry = &table[i];
1093
1094 /* Default probability for this pass */
1095 entry->prob2 = 0;
1096
1097 /* Access the "r_idx" of the chosen monster */
1098 r_idx = entry->index;
1099
1100 /* for more efficiency: no dungeon bosses, done now in level-generation routine - C. Blue */
1101 if (r_info[r_idx].flags0 & RF0_FINAL_GUARDIAN) {
1102 /* exception: Sauron in the IDDC (real check is done in place_monster_one() anyway..) */
1103 if (r_idx != RI_SAURON) continue;
1104 }
1105
1106 /* Check the monster rejection array provided */
1107 if (reject_monsters && reject_monsters[entry->index])
1108 continue;
1109
1110 /* Accept monsters which pass the restriction, if any */
1111 if ((*hook)(r_idx) && (*hook2)(r_idx))
1112 {
1113 /* Accept this monster */
1114 entry->prob2 = entry->prob1;
1115 }
1116
1117 /* Do not use this monster */
1118 else
1119 {
1120 /* Decline this monster */
1121 continue;
1122 }
1123 }
1124 } else {
1125 /* Scan the allocation table */
1126 for (i = 0, n = alloc_race_size; i < n; i++)
1127 {
1128 /* Get the entry */
1129 alloc_entry *entry = &table[i];
1130
1131 /* Default probability for this pass */
1132 entry->prob2 = 0;
1133
1134 /* Access the "r_idx" of the chosen monster */
1135 r_idx = entry->index;
1136
1137 /* for more efficiency: no dungeon bosses, done now in level-generation routine - C. Blue */
1138 if (r_info[r_idx].flags0 & RF0_FINAL_GUARDIAN) {
1139 /* exception: Sauron in the IDDC (real check is done in place_monster_one() anyway..) */
1140 if (r_idx != RI_SAURON) continue;
1141 }
1142
1143 /* Check the monster rejection array provided */
1144 if (reject_monsters && reject_monsters[entry->index])
1145 continue;
1146
1147 /* Accept monsters which pass the restriction, if any */
1148 if ((!hook || (*hook)(r_idx)) && (!hook2 || (*hook2)(r_idx)))
1149 {
1150 /* Accept this monster */
1151 entry->prob2 = entry->prob1;
1152 }
1153
1154 /* Do not use this monster */
1155 else
1156 {
1157 /* Decline this monster */
1158 continue;
1159 }
1160 }
1161 }
1162
1163 /* Success */
1164 return (0);
1165 }
1166
1167
1168 /* TODO: do this job when creating allocation table, for efficiency */
1169 /* XXX: this function can act strange when used for non-generation checks */
mon_allowed(monster_race * r_ptr)1170 bool mon_allowed(monster_race *r_ptr)
1171 {
1172 int i = randint(100);
1173
1174 /* Pet/neutral monsters allowed? */
1175 if ((r_ptr->flags7 & (RF7_PET | RF7_NEUTRAL)) && i > cfg.pet_monsters)
1176 return(FALSE);
1177
1178 /* No quest NPCs - they are to be created explicitely by quest code */
1179 if ((r_ptr->flags1 & RF1_QUESTOR)) return(FALSE);
1180
1181 /* Base monsters allowed ? or not ? */
1182 if ((r_ptr->flags8 & RF8_ANGBAND) && i > cfg.vanilla_monsters) return(FALSE);
1183
1184 /* Zangbandish monsters allowed ? or not ? */
1185 if ((r_ptr->flags8 & RF8_ZANGBAND) && i > cfg.zang_monsters) return(FALSE);
1186
1187 /* Joke monsters allowed ? or not ? */
1188 if ((r_ptr->flags8 & RF8_JOKEANGBAND) && i > cfg.joke_monsters) return(FALSE);
1189
1190 /* Lovercraftian monsters allowed ? or not ? */
1191 if ((r_ptr->flags8 & RF8_CTHANGBAND) && i > cfg.cth_monsters) return(FALSE);
1192
1193 /* C. Blue's monsters allowed ? or not ? */
1194 if ((r_ptr->flags8 & RF8_BLUEBAND) && i > cfg.cblue_monsters) return(FALSE);
1195
1196 /* Pernian monsters allowed ? or not ? */
1197 if ((r_ptr->flags8 & RF8_PERNANGBAND) && i > cfg.pern_monsters) return(FALSE);
1198
1199 return(TRUE);
1200 }
1201
1202 /* added this one for monster_level_min implementation - C. Blue */
mon_allowed_chance(monster_race * r_ptr)1203 bool mon_allowed_chance(monster_race *r_ptr) {
1204 /* Pet/neutral monsters allowed? */
1205 if(r_ptr->flags7 & (RF7_PET | RF7_NEUTRAL)) return(cfg.pet_monsters);
1206
1207 /* No quest NPCs - they are to be created explicitely by quest code */
1208 if ((r_ptr->flags1 & RF1_QUESTOR)) return(FALSE);
1209
1210 /* Base monsters allowed ? or not ? */
1211 if (r_ptr->flags8 & RF8_ANGBAND) return(cfg.vanilla_monsters);
1212
1213 /* Zangbandish monsters allowed ? or not ? */
1214 if(r_ptr->flags8 & RF8_ZANGBAND) return(cfg.zang_monsters);
1215
1216 /* Joke monsters allowed ? or not ? */
1217 if (r_ptr->flags8 & RF8_JOKEANGBAND) return(cfg.joke_monsters);
1218
1219 /* Lovercraftian monsters allowed ? or not ? */
1220 if(r_ptr->flags8 & RF8_CTHANGBAND) return(cfg.cth_monsters);
1221
1222 /* C. Blue's monsters allowed ? or not ? */
1223 if(r_ptr->flags8 & RF8_BLUEBAND) return(cfg.cblue_monsters);
1224
1225 /* Pernian monsters allowed ? or not ? */
1226 if(r_ptr->flags8 & RF8_PERNANGBAND) return(cfg.pern_monsters);
1227
1228 return(100); /* or 0? =p */
1229 }
1230
1231 /* Similar to mon_allowed, but determine the result by TELL_MONSTER_ABOVE. */
mon_allowed_view(monster_race * r_ptr)1232 bool mon_allowed_view(monster_race *r_ptr)
1233 {
1234 int i = TELL_MONSTER_ABOVE;
1235
1236 /* Pet/neutral monsters allowed? */
1237 if(i > cfg.pet_monsters && (r_ptr->flags7 & (RF7_PET | RF7_NEUTRAL)))
1238 return(FALSE);
1239
1240 /* No quest NPCs - they are to be created explicitely by quest code */
1241 if ((r_ptr->flags1 & RF1_QUESTOR)) return(FALSE);
1242
1243 /* Base monsters allowed ? or not ? */
1244 if(i > cfg.vanilla_monsters && (r_ptr->flags8 & RF8_ANGBAND)) return(FALSE);
1245
1246 /* Zangbandish monsters allowed ? or not ? */
1247 if(i > cfg.zang_monsters && (r_ptr->flags8 & RF8_ZANGBAND)) return(FALSE);
1248
1249 /* Joke monsters allowed ? or not ? */
1250 if(i > cfg.joke_monsters && (r_ptr->flags8 & RF8_JOKEANGBAND)) return(FALSE);
1251
1252 /* Lovercraftian monsters allowed ? or not ? */
1253 if(i > cfg.cth_monsters && (r_ptr->flags8 & RF8_CTHANGBAND)) return(FALSE);
1254
1255 /* C. Blue's monsters allowed ? or not ? */
1256 if(i > cfg.cblue_monsters && (r_ptr->flags8 & RF8_BLUEBAND)) return(FALSE);
1257
1258 /* Pernian monsters allowed ? or not ? */
1259 if(i > cfg.pern_monsters && (r_ptr->flags8 & RF8_PERNANGBAND)) return(FALSE);
1260
1261 return(TRUE);
1262 }
1263
1264
1265 /*
1266 * Choose a monster race that seems "appropriate" to the given level
1267 *
1268 * This function uses the "prob2" field of the "monster allocation table",
1269 * and various local information, to calculate the "prob3" field of the
1270 * same table, which is then used to choose an "appropriate" monster, in
1271 * a relatively efficient manner.
1272 *
1273 * Note that "town" monsters will *only* be created in the town, and
1274 * "normal" monsters will *never* be created in the town, unless the
1275 * "level" is "modified", for example, by polymorph or summoning.
1276 *
1277 * There is a small chance (1/50) of "boosting" the given depth by
1278 * a small amount (up to four levels), except in the town.
1279 *
1280 * It is (slightly) more likely to acquire a monster of the given level
1281 * than one of a lower level. This is done by choosing several monsters
1282 * appropriate to the given level and keeping the "hardest" one.
1283 *
1284 * Note that if no monsters are "appropriate", then this function will
1285 * fail, and return zero, but this should *almost* never happen.
1286 */
1287
1288 /* APD I am changing this to support "negative" levels, so we can have
1289 * wilderness only monsters.
1290 *
1291 * XXX I am temporarily disabling this, as it appears to be messing
1292 * things up.
1293 *
1294 * This function is kind of a mess right now.
1295 *
1296 * C. Blue: Added check of 'monster_level_min', for
1297 * micro cell vaults (cross-shaped) actually:
1298 * -1 = auto, 0 = disabled, >0 = use specific value.
1299 * Also added 'dlevel' to allow get_mon_num() to determine
1300 * if 'monster_level' is already specifying an OoD request
1301 * and therefore must not be boosted further by get_mon_num()'s
1302 * own built-in OoD code.
1303 */
1304
1305 //s16b get_mon_num(int level)
get_mon_num(int level,int dlevel)1306 s16b get_mon_num(int level, int dlevel)
1307 {
1308 long begin, i, j, n, p; //, d1 = 0, d2 = 0;
1309 long r_idx, monster_level_min_int = 0;
1310 long value, total;
1311 monster_race *r_ptr;
1312 alloc_entry *table = alloc_race_table;
1313
1314 #if 0 // removed, but not disabled.. please see place_monster_one
1315 /* Warp level around */
1316 if (level > 100) level = level - 100;
1317 #endif // 0
1318
1319 /* Out Of Depth modification: -- but not in town (Bree) */
1320 if (level > 0) {
1321 if (rand_int(NASTY_MON) == 0) {
1322 if (dlevel < 15) level += (2 + dlevel / 2 + randint(3));
1323 else level += (10 + dlevel / 4 + randint(dlevel / 4)); /* can be quite nasty, but serves well so far >;-) */
1324 }
1325 }
1326
1327 /* Cap OoD - C. Blue
1328 (serves to catch double OoD boost:
1329 once by setting a high monster_level before calling get_mon_num(),
1330 second in here by boosting the level even further in the code above.) */
1331 if (level > dlevel + 40) level = dlevel + 40;
1332
1333 /* Reset total */
1334 total = 0L;
1335
1336 if (monster_level_min == -1) {
1337 /* Automatic minimum level */
1338 if (level >= 98) {
1339 monster_level_min_int = 69; /* 64..69 somewhere is a good start for nasty stuff - C. Blue */
1340 } else {
1341 monster_level_min_int = (level * 2) / 3;
1342 }
1343 }
1344
1345 /* Hack -- No town monsters in the dungeon */
1346 if (level > 0) {
1347 if (monster_level_min_int < 1) {
1348 monster_level_min_int = 1;
1349 }
1350 }
1351
1352 /* Cap maximum level */
1353 if (level > 254) {
1354 level = 254;
1355 }
1356
1357 /* Calculate loop bounds */
1358 begin = alloc_race_index_level[monster_level_min_int];
1359 n = alloc_race_index_level[level + 1];
1360
1361 /* Process probabilities */
1362 for (i = begin; i < n; i++)
1363 {
1364 /* Get the entry */
1365 alloc_entry *entry = &table[i];
1366
1367 /* Obtain the probability */
1368 p = entry->prob2;
1369
1370 /* Default probability for this pass */
1371 entry->prob3 = 0;
1372
1373 /* Skip monsters with zero probability */
1374 if (!p) continue;
1375
1376 /* Access the "r_idx" of the chosen monster */
1377 r_idx = entry->index;
1378
1379 /* Access the actual race */
1380 r_ptr = &r_info[r_idx];
1381
1382 /* Depth Monsters never appear out of depth */
1383 /* FIXME: This might cause FORCE_DEPTH monsters to appear out of depth */
1384 if ((r_ptr->flags1 & RF1_FORCE_DEPTH) && (entry->level > level))
1385 continue;
1386
1387 /* Depth Monsters never appear out of their depth */
1388 /* level = base_depth + depth, be careful(esp.wilderness)
1389 * Appearently only used for Moldoux atm. */
1390 if ((r_ptr->flags9 & (RF9_ONLY_DEPTH)) && (entry->level != level))
1391 continue;
1392
1393 /* Prevent certain monsters from being generated too much OoD */
1394 if ((r_ptr->flags7 & RF7_OOD_10) && (entry->level > level + 10))
1395 continue;
1396 if ((r_ptr->flags7 & RF7_OOD_15) && (entry->level > level + 15))
1397 continue;
1398 if ((r_ptr->flags7 & RF7_OOD_20) && (entry->level > level + 20))
1399 continue;
1400
1401 /* Accept */
1402 entry->prob3 = p;
1403
1404 /* Total */
1405 total += p;
1406 }
1407
1408 /* No legal monsters */
1409 if (total <= 0) {
1410 return (0);
1411 }
1412
1413 /* Pick a monster */
1414 value = rand_int(total);
1415
1416 /* Find the monster */
1417 for (i = begin; i < n; i++)
1418 {
1419 /* Found the entry */
1420 if (value < table[i].prob3) break;
1421
1422 /* Decrement */
1423 value = value - table[i].prob3;
1424 }
1425
1426
1427 /* Power boost */
1428 p = rand_int(100);
1429
1430 /* Try for a "harder" monster once (50%) or twice (10%) */
1431 if (p < 60)
1432 {
1433 /* Save old */
1434 j = i;
1435
1436 /* Pick a monster */
1437 value = rand_int(total);
1438
1439 /* Find the monster */
1440 for (i = begin; i < n; i++)
1441 {
1442 /* Found the entry */
1443 if (value < table[i].prob3) break;
1444
1445 /* Decrement */
1446 value = value - table[i].prob3;
1447 }
1448
1449 /* Keep the "best" one */
1450 if (abs(table[i].level) < abs(table[j].level)) i = j;
1451 }
1452
1453 /* Try for a "harder" monster twice (10%) */
1454 if (p < 10)
1455 {
1456 /* Save old */
1457 j = i;
1458
1459 /* Pick a monster */
1460 value = rand_int(total);
1461
1462 /* Find the monster */
1463 for (i = begin; i < n; i++)
1464 {
1465 /* Found the entry */
1466 if (value < table[i].prob3) break;
1467
1468 /* Decrement */
1469 value = value - table[i].prob3;
1470 }
1471
1472 /* Keep the "best" one */
1473 if (abs(table[i].level) < abs(table[j].level)) i = j;
1474 }
1475
1476 /* Result */
1477 return (table[i].index);
1478 }
1479
1480
1481
1482
r_name_garbled_get(int * r_idx)1483 static cptr r_name_garbled_get(int *r_idx) {
1484 int tries = 1000;
1485
1486 while (TRUE) {
1487 *r_idx = rand_int(MAX_R_IDX - 1);
1488 if (!r_info[*r_idx].name) continue;
1489 else if (!mon_allowed_chance(&r_info[*r_idx])) continue;
1490 else return (r_name + r_info[*r_idx].name);
1491
1492 if (!tries--) {
1493 *r_idx = 0;
1494 return("unnamed monster");
1495 }
1496 }
1497 }
1498
1499
1500 /*
1501 * Build a string describing a monster in some way.
1502 *
1503 * We can correctly describe monsters based on their visibility.
1504 * We can force all monsters to be treated as visible or invisible.
1505 * We can build nominatives, objectives, possessives, or reflexives.
1506 * We can selectively pronominalize hidden, visible, or all monsters.
1507 * We can use definite or indefinite descriptions for hidden monsters.
1508 * We can use definite or indefinite descriptions for visible monsters.
1509 *
1510 * Pronominalization involves the gender whenever possible and allowed,
1511 * so that by cleverly requesting pronominalization / visibility, you
1512 * can get messages like "You hit someone. She screams in agony!".
1513 *
1514 * Reflexives are acquired by requesting Objective plus Possessive.
1515 *
1516 * If no m_ptr arg is given (?), the monster is assumed to be hidden,
1517 * unless the "Assume Visible" mode is requested.
1518 *
1519 * If no r_ptr arg is given, it is extracted from m_ptr and r_info
1520 * If neither m_ptr nor r_ptr is given, the monster is assumed to
1521 * be neuter, singular, and hidden (unless "Assume Visible" is set),
1522 * in which case you may be in trouble... :-)
1523 *
1524 * I am assuming that no monster name is more than 70 characters long,
1525 * so that "char desc[80];" is sufficiently large for any result.
1526 *
1527 * Mode Flags:
1528 * 0x01 --> Objective (or Reflexive)
1529 * 0x02 --> Possessive (or Reflexive)
1530 * 0x04 --> Use indefinites for hidden monsters ("something")
1531 * 0x08 --> Use indefinites for visible monsters ("a kobold")
1532 * 0x10 --> Pronominalize hidden monsters
1533 * 0x20 --> Pronominalize visible monsters
1534 * 0x40 --> Assume the monster is hidden
1535 * 0x80 --> Assume the monster is visible
1536 *
1537 * Useful Modes:
1538 * 0x00 --> Full nominative name ("the kobold") or "it"
1539 * 0x04 --> Full nominative name ("the kobold") or "something"
1540 * 0x80 --> Genocide resistance name ("the kobold")
1541 * 0x88 --> Killing name ("a kobold")
1542 * 0x22 --> Possessive, genderized if visable ("his") or "its"
1543 * 0x23 --> Reflexive, genderized if visable ("himself") or "itself"
1544 */
1545 /*
1546 * ToME-NET Extra Flags:
1547 * 0x0100 --> Ban 'Garbled' name (for death-record)
1548 */
1549 /* FIXME: 'The The Borshin' when hallucinating */
monster_desc(int Ind,char * desc,int m_idx,int mode)1550 void monster_desc(int Ind, char *desc, int m_idx, int mode) {
1551 player_type *p_ptr;
1552 cptr res;
1553
1554 monster_type *m_ptr = &m_list[m_idx];
1555 monster_race *r_ptr = race_inf(m_ptr);
1556
1557 cptr name = r_name_get(m_ptr);
1558 bool seen, pron;
1559
1560 /* Check for bad player number */
1561 if (Ind > 0) {
1562 p_ptr = Players[Ind];
1563
1564 /* Can we "see" it (exists + forced, or visible + not unforced) */
1565 seen = (m_ptr && ((mode & 0x80) || (!(mode & 0x40) && p_ptr->mon_vis[m_idx])));
1566
1567 if (!(mode & 0x0100) && p_ptr->image) {
1568 int r_idx;
1569
1570 name = r_name_garbled_get(&r_idx);
1571 r_ptr = &r_info[r_idx];
1572 }
1573 } else
1574 seen = (m_ptr && ((mode & 0x80) || (!(mode & 0x40))));
1575
1576 /* Sexed Pronouns (seen and allowed, or unseen and allowed) */
1577 pron = (m_ptr && ((seen && (mode & 0x20)) || (!seen && (mode & 0x10))));
1578
1579
1580 /* First, try using pronouns, or describing hidden monsters */
1581 if (!seen || pron) {
1582 /* an encoding of the monster "sex" */
1583 int kind = 0x00;
1584
1585 /* Extract the gender (if applicable) */
1586 if (r_ptr->flags1 & RF1_FEMALE) kind = 0x20;
1587 else if (r_ptr->flags1 & RF1_MALE) kind = 0x10;
1588
1589 /* Ignore the gender (if desired) */
1590 if (!m_ptr || !pron) kind = 0x00;
1591
1592
1593 /* Assume simple result */
1594 res = "it";
1595
1596 /* Brute force: split on the possibilities */
1597 switch (kind + (mode & 0x07)) {
1598 /* Neuter, or unknown */
1599 case 0x00: res = "it"; break;
1600 case 0x01: res = "it"; break;
1601 case 0x02: res = "its"; break;
1602 case 0x03: res = "itself"; break;
1603 case 0x04: res = "something"; break;
1604 case 0x05: res = "something"; break;
1605 case 0x06: res = "something's"; break;
1606 case 0x07: res = "itself"; break;
1607
1608 /* Male (assume human if vague) */
1609 case 0x10: res = "he"; break;
1610 case 0x11: res = "him"; break;
1611 case 0x12: res = "his"; break;
1612 case 0x13: res = "himself"; break;
1613 case 0x14: res = "someone"; break;
1614 case 0x15: res = "someone"; break;
1615 case 0x16: res = "someone's"; break;
1616 case 0x17: res = "himself"; break;
1617
1618 /* Female (assume human if vague) */
1619 case 0x20: res = "she"; break;
1620 case 0x21: res = "her"; break;
1621 case 0x22: res = "her"; break;
1622 case 0x23: res = "herself"; break;
1623 case 0x24: res = "someone"; break;
1624 case 0x25: res = "someone"; break;
1625 case 0x26: res = "someone's"; break;
1626 case 0x27: res = "herself"; break;
1627 }
1628
1629 /* Copy the result */
1630 (void)strcpy(desc, res);
1631 }
1632
1633
1634 /* Handle visible monsters, "reflexive" request */
1635 else if ((mode & 0x02) && (mode & 0x01)) {
1636 /* The monster is visible, so use its gender */
1637 if (r_ptr->flags1 & RF1_FEMALE) strcpy(desc, "herself");
1638 else if (r_ptr->flags1 & RF1_MALE) strcpy(desc, "himself");
1639 else strcpy(desc, "itself");
1640 }
1641
1642
1643 /* Handle all other visible monster requests */
1644 else {
1645 /* It could be a Unique */
1646 if ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags8 & RF8_PSEUDO_UNIQUE)) {
1647 /* Start with the name (thus nominative and objective) */
1648 (void)strcpy(desc, name);
1649 }
1650
1651 /* It could be an indefinite monster */
1652 else if (mode & 0x08) {
1653 /* XXX Check plurality for "some" */
1654 if ((r_ptr->flags8 & RF8_PLURAL))
1655 (void)strcpy(desc, name);
1656 else {
1657 /* Indefinite monsters need an indefinite article */
1658 (void)strcpy(desc, is_a_vowel(name[0]) ? "an " : "a ");
1659 (void)strcat(desc, name);
1660 }
1661 }
1662
1663 /* It could be a normal, definite, monster */
1664 else {
1665 /* Definite monsters need a definite article */
1666 (void)strcpy(desc, "the ");
1667 (void)strcat(desc, name);
1668 }
1669
1670 /* Handle the Possessive as a special afterthought */
1671 if (mode & 0x02) {
1672 /* XXX Check for trailing "s" */
1673 if (name[strlen(name) - 1] == 's') (void)strcat(desc, "'");
1674 /* Simply append "apostrophe" and "s" */
1675 else (void)strcat(desc, "'s");
1676 }
1677 }
1678 }
1679
1680 /* added for quests: takes m_ptr instead of m_idx (and no player) */
monster_desc2(char * desc,monster_type * m_ptr,int mode)1681 void monster_desc2(char *desc, monster_type *m_ptr, int mode) {
1682 cptr res;
1683 monster_race *r_ptr = race_inf(m_ptr);
1684 cptr name = r_name_get(m_ptr);
1685 bool seen, pron;
1686
1687 seen = (m_ptr && ((mode & 0x80) || (!(mode & 0x40))));
1688
1689 /* Sexed Pronouns (seen and allowed, or unseen and allowed) */
1690 pron = (m_ptr && ((seen && (mode & 0x20)) || (!seen && (mode & 0x10))));
1691
1692
1693 /* First, try using pronouns, or describing hidden monsters */
1694 if (!seen || pron) {
1695 /* an encoding of the monster "sex" */
1696 int kind = 0x00;
1697
1698 /* Extract the gender (if applicable) */
1699 if (r_ptr->flags1 & RF1_FEMALE) kind = 0x20;
1700 else if (r_ptr->flags1 & RF1_MALE) kind = 0x10;
1701
1702 /* Ignore the gender (if desired) */
1703 if (!m_ptr || !pron) kind = 0x00;
1704
1705
1706 /* Assume simple result */
1707 res = "it";
1708
1709 /* Brute force: split on the possibilities */
1710 switch (kind + (mode & 0x07)) {
1711 /* Neuter, or unknown */
1712 case 0x00: res = "it"; break;
1713 case 0x01: res = "it"; break;
1714 case 0x02: res = "its"; break;
1715 case 0x03: res = "itself"; break;
1716 case 0x04: res = "something"; break;
1717 case 0x05: res = "something"; break;
1718 case 0x06: res = "something's"; break;
1719 case 0x07: res = "itself"; break;
1720
1721 /* Male (assume human if vague) */
1722 case 0x10: res = "he"; break;
1723 case 0x11: res = "him"; break;
1724 case 0x12: res = "his"; break;
1725 case 0x13: res = "himself"; break;
1726 case 0x14: res = "someone"; break;
1727 case 0x15: res = "someone"; break;
1728 case 0x16: res = "someone's"; break;
1729 case 0x17: res = "himself"; break;
1730
1731 /* Female (assume human if vague) */
1732 case 0x20: res = "she"; break;
1733 case 0x21: res = "her"; break;
1734 case 0x22: res = "her"; break;
1735 case 0x23: res = "herself"; break;
1736 case 0x24: res = "someone"; break;
1737 case 0x25: res = "someone"; break;
1738 case 0x26: res = "someone's"; break;
1739 case 0x27: res = "herself"; break;
1740 }
1741
1742 /* Copy the result */
1743 (void)strcpy(desc, res);
1744 }
1745
1746
1747 /* Handle visible monsters, "reflexive" request */
1748 else if ((mode & 0x02) && (mode & 0x01)) {
1749 /* The monster is visible, so use its gender */
1750 if (r_ptr->flags1 & RF1_FEMALE) strcpy(desc, "herself");
1751 else if (r_ptr->flags1 & RF1_MALE) strcpy(desc, "himself");
1752 else strcpy(desc, "itself");
1753 }
1754
1755
1756 /* Handle all other visible monster requests */
1757 else {
1758 /* It could be a Unique */
1759 if ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags8 & RF8_PSEUDO_UNIQUE)) {
1760 /* Start with the name (thus nominative and objective) */
1761 (void)strcpy(desc, name);
1762 }
1763
1764 /* It could be an indefinite monster */
1765 else if (mode & 0x08) {
1766 /* XXX Check plurality for "some" */
1767 if ((r_ptr->flags8 & RF8_PLURAL))
1768 (void)strcpy(desc, name);
1769 else {
1770 /* Indefinite monsters need an indefinite article */
1771 (void)strcpy(desc, is_a_vowel(name[0]) ? "an " : "a ");
1772 (void)strcat(desc, name);
1773 }
1774 }
1775
1776 /* It could be a normal, definite, monster */
1777 else {
1778 /* Definite monsters need a definite article */
1779 (void)strcpy(desc, "the ");
1780 (void)strcat(desc, name);
1781 }
1782
1783 /* Handle the Possessive as a special afterthought */
1784 if (mode & 0x02) {
1785 /* XXX Check for trailing "s" */
1786 if (name[strlen(name) - 1] == 's') (void)strcat(desc, "'");
1787 /* Simply append "apostrophe" and "s" */
1788 else (void)strcat(desc, "'s");
1789 }
1790 }
1791 }
1792
monster_race_desc(int Ind,char * desc,int r_idx,int mode)1793 void monster_race_desc(int Ind, char *desc, int r_idx, int mode) {
1794 player_type *p_ptr;
1795 cptr res;
1796 monster_race *r_ptr = &r_info[r_idx];
1797 cptr name = r_name + r_ptr->name;
1798 bool seen = FALSE, pron = FALSE;
1799
1800 /* Check for bad player number */
1801 if (Ind > 0) {
1802 p_ptr = Players[Ind];
1803
1804 seen = TRUE;
1805
1806 if (!(mode & 0x0100) && p_ptr->image) {
1807 int r_idx;
1808
1809 name = r_name_garbled_get(&r_idx);
1810 r_ptr = &r_info[r_idx];
1811 }
1812 } else
1813 seen = ((mode & 0x80) || (!(mode & 0x40)));
1814
1815 /* Sexed Pronouns (seen and allowed, or unseen and allowed) */
1816 pron = ((seen && (mode & 0x20)) || (!seen && (mode & 0x10)));
1817
1818
1819 /* First, try using pronouns, or describing hidden monsters */
1820 if (!seen || pron) {
1821 /* an encoding of the monster "sex" */
1822 int kind = 0x00;
1823
1824 /* Extract the gender (if applicable) */
1825 if (r_ptr->flags1 & RF1_FEMALE) kind = 0x20;
1826 else if (r_ptr->flags1 & RF1_MALE) kind = 0x10;
1827
1828 /* Ignore the gender (if desired) */
1829 if (!pron) kind = 0x00;
1830
1831
1832 /* Assume simple result */
1833 res = "it";
1834
1835 /* Brute force: split on the possibilities */
1836 switch (kind + (mode & 0x07)) {
1837 /* Neuter, or unknown */
1838 case 0x00: res = "it"; break;
1839 case 0x01: res = "it"; break;
1840 case 0x02: res = "its"; break;
1841 case 0x03: res = "itself"; break;
1842 case 0x04: res = "something"; break;
1843 case 0x05: res = "something"; break;
1844 case 0x06: res = "something's"; break;
1845 case 0x07: res = "itself"; break;
1846
1847 /* Male (assume human if vague) */
1848 case 0x10: res = "he"; break;
1849 case 0x11: res = "him"; break;
1850 case 0x12: res = "his"; break;
1851 case 0x13: res = "himself"; break;
1852 case 0x14: res = "someone"; break;
1853 case 0x15: res = "someone"; break;
1854 case 0x16: res = "someone's"; break;
1855 case 0x17: res = "himself"; break;
1856
1857 /* Female (assume human if vague) */
1858 case 0x20: res = "she"; break;
1859 case 0x21: res = "her"; break;
1860 case 0x22: res = "her"; break;
1861 case 0x23: res = "herself"; break;
1862 case 0x24: res = "someone"; break;
1863 case 0x25: res = "someone"; break;
1864 case 0x26: res = "someone's"; break;
1865 case 0x27: res = "herself"; break;
1866 }
1867
1868 /* Copy the result */
1869 (void)strcpy(desc, res);
1870 }
1871
1872
1873 /* Handle visible monsters, "reflexive" request */
1874 else if ((mode & 0x02) && (mode & 0x01)) {
1875 /* The monster is visible, so use its gender */
1876 if (r_ptr->flags1 & RF1_FEMALE) strcpy(desc, "herself");
1877 else if (r_ptr->flags1 & RF1_MALE) strcpy(desc, "himself");
1878 else strcpy(desc, "itself");
1879 }
1880 /* Handle all other visible monster requests */
1881 else {
1882 /* It could be a Unique */
1883 if ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags8 & RF8_PSEUDO_UNIQUE)) {
1884 /* Start with the name (thus nominative and objective) */
1885 (void)strcpy(desc, name);
1886 }
1887 /* It could be an indefinite monster */
1888 else if (mode & 0x08) {
1889 /* XXX Check plurality for "some" */
1890 if ((r_ptr->flags8 & RF8_PLURAL))
1891 (void)strcpy(desc, name);
1892 else {
1893 /* Indefinite monsters need an indefinite article */
1894 (void)strcpy(desc, is_a_vowel(name[0]) ? "an " : "a ");
1895 (void)strcat(desc, name);
1896 }
1897 }
1898 /* It could be a normal, definite, monster */
1899 else {
1900 /* Definite monsters need a definite article */
1901 (void)strcpy(desc, "the ");
1902 (void)strcat(desc, name);
1903 }
1904
1905 /* Handle the Possessive as a special afterthought */
1906 if (mode & 0x02) {
1907 /* XXX Check for trailing "s" */
1908 if (name[strlen(name) - 1] == 's') (void)strcat(desc, "'");
1909 /* Simply append "apostrophe" and "s" */
1910 else (void)strcat(desc, "'s");
1911 }
1912 }
1913 }
1914
1915 /* Similar to monster_desc, but it handles the players instead. - Jir - */
player_desc(int Ind,char * desc,int Ind2,int mode)1916 void player_desc(int Ind, char *desc, int Ind2, int mode) {
1917 player_type *p_ptr, *q_ptr = Players[Ind2];
1918 cptr res;
1919 cptr name = q_ptr->name;
1920 bool seen, pron;
1921
1922 /* Check for bad player number */
1923 if (Ind > 0) {
1924 p_ptr = Players[Ind];
1925
1926 /* Can we "see" it (exists + forced, or visible + not unforced) */
1927 seen = (q_ptr && ((mode & 0x80) || (!(mode & 0x40) && p_ptr->play_vis[Ind2])));
1928
1929 if (!(mode & 0x0100) && p_ptr->image)
1930 #if 0
1931 name = r_name_garbled_get();
1932 #else
1933 {
1934 monster_race_desc(Ind, desc, 0, mode);
1935 return;
1936 }
1937 #endif
1938 } else
1939 seen = (q_ptr && ((mode & 0x80) || (!(mode & 0x40))));
1940
1941 /* Sexed Pronouns (seen and allowed, or unseen and allowed) */
1942 pron = (q_ptr && ((seen && (mode & 0x20)) || (!seen && (mode & 0x10))));
1943
1944
1945 /* First, try using pronouns, or describing hidden monsters */
1946 if (!seen || pron) {
1947 /* an encoding of the monster "sex" */
1948 int kind = 0x00;
1949
1950 /* Extract the gender (if applicable) */
1951 if (q_ptr->male) kind = 0x10;
1952 else kind = 0x20;
1953
1954 /* Ignore the gender (if desired) */
1955 if (!q_ptr || !pron) kind = 0x00;
1956
1957
1958 /* Assume simple result */
1959 res = "it";
1960
1961 /* Brute force: split on the possibilities */
1962 switch (kind + (mode & 0x07)) {
1963 /* Neuter, or unknown */
1964 case 0x00: res = "it"; break;
1965 case 0x01: res = "it"; break;
1966 case 0x02: res = "its"; break;
1967 case 0x03: res = "itself"; break;
1968 case 0x04: res = "something"; break;
1969 case 0x05: res = "something"; break;
1970 case 0x06: res = "something's"; break;
1971 case 0x07: res = "itself"; break;
1972
1973 /* Male (assume human if vague) */
1974 case 0x10: res = "he"; break;
1975 case 0x11: res = "him"; break;
1976 case 0x12: res = "his"; break;
1977 case 0x13: res = "himself"; break;
1978 case 0x14: res = "someone"; break;
1979 case 0x15: res = "someone"; break;
1980 case 0x16: res = "someone's"; break;
1981 case 0x17: res = "himself"; break;
1982
1983 /* Female (assume human if vague) */
1984 case 0x20: res = "she"; break;
1985 case 0x21: res = "her"; break;
1986 case 0x22: res = "her"; break;
1987 case 0x23: res = "herself"; break;
1988 case 0x24: res = "someone"; break;
1989 case 0x25: res = "someone"; break;
1990 case 0x26: res = "someone's"; break;
1991 case 0x27: res = "herself"; break;
1992 }
1993
1994 /* Copy the result */
1995 (void)strcpy(desc, res);
1996 }
1997
1998
1999 /* Handle visible monsters, "reflexive" request */
2000 else if ((mode & 0x02) && (mode & 0x01)) {
2001 /* The monster is visible, so use its gender */
2002 if (!q_ptr->male) strcpy(desc, "herself");
2003 else strcpy(desc, "himself");
2004 // else strcpy(desc, "itself");
2005 }
2006
2007 /* Handle all other visible monster requests */
2008 else {
2009 /* Start with the name (thus nominative and objective) */
2010 (void)strcpy(desc, name);
2011
2012 /* Handle the Possessive as a special afterthought */
2013 if (mode & 0x02) {
2014 /* XXX Check for trailing "s" */
2015 if (name[strlen(name) - 1] == 's') (void)strcat(desc, "'");
2016 /* Simply append "apostrophe" and "s" */
2017 else (void)strcat(desc, "'s");
2018 }
2019 }
2020 }
2021
2022
2023
2024 /*
2025 * Learn about a monster (by "probing" it)
2026 */
lore_do_probe(int m_idx)2027 void lore_do_probe(int m_idx)
2028 {
2029 #ifdef OLD_MONSTER_LORE
2030 monster_type *m_ptr = &m_list[m_idx];
2031
2032 monster_race *r_ptr = race_inf(m_ptr);
2033
2034 /* Hack -- Memorize some flags */
2035 r_ptr->r_flags1 = r_ptr->flags1;
2036 r_ptr->r_flags2 = r_ptr->flags2;
2037 r_ptr->r_flags3 = r_ptr->flags3;
2038 #endif
2039
2040 /* Window stuff */
2041 /*p_ptr->window |= (PW_MONSTER);*/
2042 }
2043
2044
2045 /*
2046 * Take note that the given monster just dropped some treasure
2047 *
2048 * Note that learning the "GOOD"/"GREAT" flags gives information
2049 * about the treasure (even when the monster is killed for the first
2050 * time, such as uniques, and the treasure has not been examined yet).
2051 *
2052 * This "indirect" method is used to prevent the player from learning
2053 * exactly how much treasure a monster can drop from observing only
2054 * a single example of a drop. This method actually observes how much
2055 * gold and items are dropped, and remembers that information to be
2056 * described later by the monster recall code.
2057 */
lore_treasure(int m_idx,int num_item,int num_gold)2058 void lore_treasure(int m_idx, int num_item, int num_gold)
2059 {
2060 #ifdef OLD_MONSTER_LORE
2061 monster_type *m_ptr = &m_list[m_idx];
2062
2063 monster_race *r_ptr = race_inf(m_ptr);
2064
2065 /* Note the number of things dropped */
2066 if (num_item > r_ptr->r_drop_item) r_ptr->r_drop_item = num_item;
2067 if (num_gold > r_ptr->r_drop_gold) r_ptr->r_drop_gold = num_gold;
2068
2069 /* Hack -- memorize the good/great flags */
2070 if (r_ptr->flags1 & RF1_DROP_GOOD) r_ptr->r_flags1 |= RF1_DROP_GOOD;
2071 if (r_ptr->flags1 & RF1_DROP_GREAT) r_ptr->r_flags1 |= RF1_DROP_GREAT;
2072 #endif
2073 }
2074
2075 /*
2076 * Here comes insanity from PernAngband.. hehehe.. - Jir -
2077 */
2078 //void sanity_blast(int Ind, monster_type * m_ptr, bool necro)
sanity_blast(int Ind,int m_idx,bool necro)2079 static void sanity_blast(int Ind, int m_idx, bool necro) {
2080 player_type *p_ptr = Players[Ind];
2081 monster_type *m_ptr = &m_list[m_idx];
2082 bool happened = FALSE;
2083 int power = 100;
2084
2085 /* Don't blast the master */
2086 if (p_ptr->admin_dm) return;
2087
2088 if (!necro) {
2089 char m_name[MNAME_LEN];
2090 monster_race *r_ptr;
2091
2092 if (m_ptr != NULL) r_ptr = race_inf(m_ptr);
2093 else return;
2094
2095 power = (m_ptr->level)+10;
2096
2097 monster_desc(Ind, m_name, m_idx, 0);
2098
2099 if (!(r_ptr->flags1 & RF1_UNIQUE)) {
2100 if (r_ptr->flags1 & RF1_FRIENDS) power /= 2;
2101 } else power *= 2;
2102
2103 /* No effect yet, just loaded... */
2104 // if (!hack_mind) return;
2105
2106 // if (!(m_ptr->ml))
2107 if (!p_ptr->mon_vis[m_idx])
2108 return; /* Cannot see it for some reason */
2109
2110 if (!(r_ptr->flags2 & RF2_ELDRITCH_HORROR))
2111 return; /* oops */
2112
2113
2114 /* Pet eldritch horrors are safe most of the time */
2115 // if ((is_friend(m_ptr) > 0) && (randint(8) != 1)) return;
2116
2117
2118 if (randint(power) < p_ptr->skill_sav)
2119 return; /* Save, no adverse effects */
2120
2121
2122 if (p_ptr->image) {
2123 /* Something silly happens... */
2124 msg_format(Ind, "You behold the %s visage of %s!",
2125 funny_desc[(randint(MAX_FUNNY))-1], m_name);
2126 if (randint(3) == 1) {
2127 msg_print(Ind, funny_comments[randint(MAX_COMMENT)-1]);
2128 p_ptr->image = (p_ptr->image + randint(m_ptr->level));
2129 }
2130 return; /* Never mind; we can't see it clearly enough */
2131 }
2132
2133 /* Something frightening happens... */
2134 msg_format(Ind, "You behold the %s visage of %s!",
2135 horror_desc[(randint(MAX_HORROR))-1], m_name);
2136
2137 #ifdef OLD_MONSTER_LORE
2138 r_ptr->r_flags2 |= RF2_ELDRITCH_HORROR;
2139 #endif
2140
2141
2142 /* Undead characters are 50% likely to be unaffected */
2143 #if 0
2144 if ((PRACE_FLAG(PR1_UNDEAD))||(p_ptr->mimic_form == MIMIC_VAMPIRE)) {
2145 if (randint(100) < (25 + (p_ptr->lev))) return;
2146 }
2147 #endif // 0
2148 }
2149 else msg_print(Ind, "Your sanity is shaken by reading the Necronomicon!");
2150
2151 if (randint(power) < p_ptr->skill_sav) { /* Mind blast */
2152 if (!p_ptr->resist_conf)
2153 (void)set_confused(Ind, p_ptr->confused + rand_int(4) + 4);
2154 if ((!p_ptr->resist_chaos) && (randint(3) == 1))
2155 (void) set_image(Ind, p_ptr->image + rand_int(250) + 150);
2156 return;
2157 }
2158
2159 if (randint(power) < p_ptr->skill_sav) { /* Lose int & wis */
2160 do_dec_stat (Ind, A_INT, STAT_DEC_NORMAL);
2161 do_dec_stat (Ind, A_WIS, STAT_DEC_NORMAL);
2162 return;
2163 }
2164
2165
2166 if (randint(power) < p_ptr->skill_sav) { /* Brain smash */
2167 if (!p_ptr->resist_conf)
2168 (void)set_confused(Ind, p_ptr->confused + rand_int(4) + 4);
2169 if (!p_ptr->free_act)
2170 (void)set_paralyzed(Ind, p_ptr->paralyzed + rand_int(4) + 4);
2171 while (rand_int(100) > p_ptr->skill_sav && p_ptr->stat_cur[A_INT] > 3)
2172 (void)do_dec_stat(Ind, A_INT, STAT_DEC_NORMAL);
2173 while (rand_int(100) > p_ptr->skill_sav && p_ptr->stat_cur[A_WIS] > 3)
2174 (void)do_dec_stat(Ind, A_WIS, STAT_DEC_NORMAL);
2175 if (!p_ptr->resist_chaos)
2176 (void) set_image(Ind, p_ptr->image + rand_int(250) + 150);
2177 return;
2178 }
2179
2180 if (randint(power) < p_ptr->skill_sav) { /* Permanent lose int & wis */
2181 if (dec_stat(Ind, A_INT, 10, TRUE)) happened = TRUE;
2182 if (dec_stat(Ind, A_WIS, 10, TRUE)) happened = TRUE;
2183 if (happened) msg_print(Ind, "You feel much less sane than before.");
2184 return;
2185 }
2186
2187
2188 if (randint(power)<p_ptr->skill_sav && /* Amnesia */
2189 !(p_ptr->pclass == CLASS_MINDCRAFTER && magik(50))) {
2190 if (lose_all_info(Ind)) msg_print(Ind, "You forget everything in your utmost terror!");
2191 return;
2192 }
2193
2194 /* Else gain permanent insanity */
2195 #if 0
2196 if ((p_ptr->muta3 & MUT3_MORONIC) && (p_ptr->muta2 & MUT2_BERS_RAGE) &&
2197 ((p_ptr->muta2 & MUT2_COWARDICE) || (p_ptr->resist_fear)) &&
2198 ((p_ptr->muta2 & MUT2_HALLU) || (p_ptr->resist_chaos))) {
2199 /* The poor bastard already has all possible insanities! */
2200 return;
2201 }
2202
2203 while (!happened) {
2204 switch(randint(4)) {
2205 case 1:
2206 if (!(p_ptr->muta3 & MUT3_MORONIC)) {
2207 msg_print("You turn into an utter moron!");
2208 if (p_ptr->muta3 & MUT3_HYPER_INT) {
2209 msg_print("Your brain is no longer a living computer.");
2210 p_ptr->muta3 &= ~(MUT3_HYPER_INT);
2211 }
2212 p_ptr->muta3 |= MUT3_MORONIC;
2213 happened = TRUE;
2214 }
2215 break;
2216 case 2:
2217 if (!(p_ptr->muta2 & MUT2_COWARDICE) && !(p_ptr->resist_fear)) {
2218 msg_print("You become paranoid!");
2219
2220 /* Duh, the following should never happen, but anyway... */
2221 if (p_ptr->muta3 & MUT3_FEARLESS) {
2222 msg_print("You are no longer fearless.");
2223 p_ptr->muta3 &= ~(MUT3_FEARLESS);
2224 }
2225
2226 p_ptr->muta2 |= MUT2_COWARDICE;
2227 happened = TRUE;
2228 }
2229 break;
2230 case 3:
2231 if (!(p_ptr->muta2 & MUT2_HALLU) && !(p_ptr->resist_chaos)) {
2232 msg_print("You are afflicted by a hallucinatory insanity!");
2233 p_ptr->muta2 |= MUT2_HALLU;
2234 happened = TRUE;
2235 }
2236 break;
2237 default:
2238 if (!(p_ptr->muta2 & MUT2_BERS_RAGE)) {
2239 msg_print("You become subject to fits of berserk rage!");
2240 p_ptr->muta2 |= MUT2_BERS_RAGE;
2241 happened = TRUE;
2242 }
2243 break;
2244 }
2245 }
2246 #endif // 0
2247
2248 p_ptr->update |= PU_BONUS;
2249 handle_stuff(Ind);
2250 }
2251
2252
2253
2254 /*
2255 * This function updates the monster record of the given monster
2256 *
2257 * This involves extracting the distance to the player, checking
2258 * for visibility (natural, infravision, see-invis, telepathy),
2259 * updating the monster visibility flag, redrawing or erasing the
2260 * monster when the visibility changes, and taking note of any
2261 * "visual" features of the monster (cold-blooded, invisible, etc).
2262 *
2263 * The only monster fields that are changed here are "cdis" (the
2264 * distance from the player), "los" (clearly visible to player),
2265 * and "ml" (visible to the player in any way).
2266 *
2267 * There are a few cases where the calling routine knows that the
2268 * distance from the player to the monster has not changed, and so
2269 * we have a special parameter to request distance computation.
2270 * This lets many calls to this function run very quickly.
2271 *
2272 * Note that every time a monster moves, we must call this function
2273 * for that monster, and update distance. Note that every time the
2274 * player moves, we must call this function for every monster, and
2275 * update distance. Note that every time the player "state" changes
2276 * in certain ways (including "blindness", "infravision", "telepathy",
2277 * and "see invisible"), we must call this function for every monster.
2278 *
2279 * The routines that actually move the monsters call this routine
2280 * directly, and the ones that move the player, or notice changes
2281 * in the player state, call "update_monsters()".
2282 *
2283 * Routines that change the "illumination" of grids must also call
2284 * this function, since the "visibility" of some monsters may be
2285 * based on the illumination of their grid.
2286 *
2287 * Note that this function is called once per monster every time the
2288 * player moves, so it is important to optimize it for monsters which
2289 * are far away. Note the optimization which skips monsters which
2290 * are far away and were completely invisible last turn.
2291 *
2292 * Note the optimized "inline" version of the "distance()" function.
2293 *
2294 * Note that only monsters on the current panel can be "visible",
2295 * and then only if they are (1) in line of sight and illuminated
2296 * by light or infravision, or (2) nearby and detected by telepathy.
2297 *
2298 * The player can choose to be disturbed by several things, including
2299 * "disturb_move" (monster which is viewable moves in some way), and
2300 * "disturb_near" (monster which is "easily" viewable moves in some
2301 * way). Note that "moves" includes "appears" and "disappears".
2302 */
update_mon(int m_idx,bool dist)2303 void update_mon(int m_idx, bool dist) {
2304 monster_type *m_ptr = &m_list[m_idx];
2305 monster_race *r_ptr = race_inf(m_ptr);
2306 player_type *p_ptr;
2307
2308 /* The current monster location */
2309 int fy = m_ptr->fy;
2310 int fx = m_ptr->fx;
2311
2312 struct worldpos *wpos = &m_ptr->wpos;
2313 cave_type **zcave, *c_ptr;
2314 byte *w_ptr;
2315
2316 int Ind;// = m_ptr->closest_player;
2317 int n, d;
2318 int dy, dx;
2319 dun_level *l_ptr = getfloor(wpos);
2320
2321 /* Local copy for speed - mikaelh */
2322 player_type **_Players = Players;
2323
2324 /* Seen at all */
2325 bool flag;
2326 /* Seen by vision */
2327 bool easy;
2328 /* Seen by telepathy */
2329 bool hard;
2330
2331 #ifdef OLD_MONSTER_LORE
2332 /* Various extra flags */
2333 bool do_no_esp;
2334 bool do_empty_mind;
2335 bool do_weird_mind;
2336 #endif
2337 bool do_invisible;
2338 bool do_cold_blood;
2339
2340 d = 0;
2341
2342 /* Check for each player */
2343 for (Ind = 1, n = NumPlayers; Ind <= n; Ind++) {
2344 p_ptr = _Players[Ind];
2345
2346 /* Reset the flags */
2347 flag = easy = hard = FALSE;
2348 #ifdef OLD_MONSTER_LORE
2349 do_no_esp = do_empty_mind = do_weird_mind = FALSE;
2350 #endif
2351 do_invisible = do_cold_blood = FALSE;
2352
2353 /* If he's not playing, skip him */
2354 if (p_ptr->conn == NOT_CONNECTED)
2355 continue;
2356
2357 /* If he's not on this depth, skip him */
2358 if (!inarea(wpos, &p_ptr->wpos)) {
2359 p_ptr->mon_vis[m_idx] = FALSE;
2360 p_ptr->mon_los[m_idx] = FALSE;
2361 continue;
2362 }
2363
2364 /* If our wilderness level has been deallocated, stop here...
2365 * we are "detatched" monsters.
2366 */
2367
2368 if (!(zcave = getcave(wpos))) continue;
2369
2370 /* Calculate distance */
2371 if (dist) {
2372 /* Distance components */
2373 dy = (p_ptr->py > fy) ? (p_ptr->py - fy) : (fy - p_ptr->py);
2374 dx = (p_ptr->px > fx) ? (p_ptr->px - fx) : (fx - p_ptr->px);
2375
2376 /* Approximate distance */
2377 d = (dy > dx) ? (dy + (dx>>1)) : (dx + (dy>>1));
2378
2379 /* Save the distance (in a byte) */
2380 m_ptr->cdis = (d < 255) ? d : 255;
2381 } else if (l_ptr && (l_ptr->flags2 & LF2_LIMIT_ESP)) {
2382 /* Distance components */
2383 dy = (p_ptr->py > fy) ? (p_ptr->py - fy) : (fy - p_ptr->py);
2384 dx = (p_ptr->px > fx) ? (p_ptr->px - fx) : (fx - p_ptr->px);
2385
2386 /* Approximate distance */
2387 d = (dy > dx) ? (dy + (dx>>1)) : (dx + (dy>>1));
2388 }
2389
2390
2391 /* Process "distant" monsters */
2392 #if 0
2393 if (m_ptr->cdis > MAX_SIGHT) {
2394 /* Ignore unseen monsters */
2395 if (!p_ptr->mon_vis[m_idx]) return;
2396 }
2397 #endif
2398
2399 /* Process "nearby" monsters on the current "panel" */
2400 if (panel_contains(fy, fx)) {
2401 c_ptr = &zcave[fy][fx];
2402 w_ptr = &p_ptr->cave_flag[fy][fx];
2403
2404 /* Normal line of sight, and player is not blind */
2405 if ((*w_ptr & CAVE_VIEW) && (!p_ptr->blind)) {
2406 /* The monster is carrying/emitting light? */
2407 if ((r_ptr->flags9 & RF9_HAS_LITE) &&
2408 !(m_ptr->csleep) &&
2409 !(r_ptr->flags2 & RF2_INVISIBLE)) easy = flag = TRUE;
2410
2411 /* Use "infravision" */
2412 if (m_ptr->cdis <= (byte)(p_ptr->see_infra)) {
2413 /* Infravision only works on "warm" creatures */
2414 /* Below, we will need to know that infravision failed */
2415 if (r_ptr->flags2 & RF2_COLD_BLOOD) do_cold_blood = TRUE;
2416
2417 /* Infravision works */
2418 if (!do_cold_blood) easy = flag = TRUE;
2419 }
2420
2421 /* Use "illumination" */
2422 if ((c_ptr->info & CAVE_LITE) || (c_ptr->info & CAVE_GLOW)) {
2423 /* Take note of invisibility */
2424 if (r_ptr->flags2 & RF2_INVISIBLE) do_invisible = TRUE;
2425
2426 /* Visible, or detectable, monsters get seen */
2427 if (!do_invisible || p_ptr->see_inv) easy = flag = TRUE;
2428 }
2429 }
2430
2431 /* Telepathy can see all "nearby" monsters with "minds" */
2432 if ((p_ptr->telepathy || (p_ptr->prace == RACE_DRACONIAN)) &&
2433 !(in_sector00(wpos) && (sector00flags2 & LF2_NO_ESP)) &&
2434 !(l_ptr && (l_ptr->flags2 & LF2_NO_ESP)) &&
2435 !(l_ptr && (l_ptr->flags2 & LF2_LIMIT_ESP) && d > 10)
2436 ) {
2437 bool see = FALSE, drsee = FALSE;
2438
2439 /* Different ESP */
2440 if (p_ptr->prace == RACE_DRACONIAN) drsee = TRUE;
2441 if ((p_ptr->telepathy & ESP_ORC) && (r_ptr->flags3 & RF3_ORC)) see = TRUE;
2442 if ((p_ptr->telepathy & ESP_SPIDER) && (r_ptr->flags7 & RF7_SPIDER)) see = TRUE;
2443 if ((p_ptr->telepathy & ESP_TROLL) && (r_ptr->flags3 & RF3_TROLL)) see = TRUE;
2444 if ((p_ptr->telepathy & ESP_DRAGON) && (r_ptr->flags3 & RF3_DRAGON)) see = TRUE;
2445 if ((p_ptr->telepathy & ESP_DRAGON) && (r_ptr->flags3 & RF3_DRAGONRIDER)) see = TRUE;
2446 if ((p_ptr->telepathy & ESP_GIANT) && (r_ptr->flags3 & RF3_GIANT)) see = TRUE;
2447 if ((p_ptr->telepathy & ESP_DEMON) && (r_ptr->flags3 & RF3_DEMON)) see = TRUE;
2448 if ((p_ptr->telepathy & ESP_UNDEAD) && (r_ptr->flags3 & RF3_UNDEAD)) see = TRUE;
2449 if ((p_ptr->telepathy & ESP_EVIL) && (r_ptr->flags3 & RF3_EVIL)) see = TRUE;
2450 if ((p_ptr->telepathy & ESP_ANIMAL) && (r_ptr->flags3 & RF3_ANIMAL)) see = TRUE;
2451 if ((p_ptr->telepathy & ESP_DRAGONRIDER) && (r_ptr->flags3 & RF3_DRAGONRIDER)) see = TRUE;
2452 if ((p_ptr->telepathy & ESP_GOOD) && (r_ptr->flags3 & RF3_GOOD)) see = TRUE;
2453 if ((p_ptr->telepathy & ESP_NONLIVING) && (r_ptr->flags3 & RF3_NONLIVING)) see = TRUE;
2454 if ((p_ptr->telepathy & ESP_UNIQUE) && ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags3 & RF3_UNIQUE_4))) see = TRUE;
2455 if (p_ptr->telepathy & ESP_ALL) see = TRUE;
2456
2457 if (see && (p_ptr->mode & MODE_HARD) && (m_ptr->cdis > MAX_SIGHT)) see = FALSE;
2458 /* Draconian ESP */
2459 if (drsee && !see &&
2460 p_ptr->lev >= 6 && m_ptr->cdis <= (5 + p_ptr->lev / 2))
2461 see = TRUE;// 3+lev/3
2462
2463 if (see) {
2464 /* Empty mind, no telepathy */
2465 if (r_ptr->flags2 & RF2_EMPTY_MIND) {
2466 #ifdef OLD_MONSTER_LORE
2467 do_empty_mind = TRUE;
2468 #endif
2469 }
2470 /* possesses powers to hide from ESP? */
2471 else if ((r_ptr->flags7 & RF7_NO_ESP)
2472 && p_ptr->pclass != CLASS_MINDCRAFTER) {
2473 #ifdef OLD_MONSTER_LORE
2474 do_no_esp = TRUE;
2475 #endif
2476 }
2477
2478 /* Weird mind, occasional telepathy */
2479 else if (r_ptr->flags2 & RF2_WEIRD_MIND) {
2480 #ifdef OLD_MONSTER_LORE
2481 do_weird_mind = TRUE;
2482 #endif
2483 if (!m_ptr->no_esp_phase) hard = flag = TRUE;
2484 }
2485
2486 /* Normal mind, allow telepathy */
2487 else hard = flag = TRUE;
2488
2489 #ifdef OLD_MONSTER_LORE
2490 /* Apply telepathy */
2491 if (hard) {
2492 /* Hack -- Memorize mental flags */
2493 if (r_ptr->flags2 & RF2_SMART) r_ptr->r_flags2 |= RF2_SMART;
2494 if (r_ptr->flags2 & RF2_STUPID) r_ptr->r_flags2 |= RF2_STUPID;
2495 }
2496 #endif
2497 }
2498 }
2499
2500 /* Hack -- Wizards have "perfect telepathy" */
2501 if (p_ptr->admin_dm || player_sees_dm(Ind)) flag = TRUE;
2502
2503 /* Arena Monster Challenge event provides wizard-esp too */
2504 if (ge_special_sector && p_ptr->wpos.wx == WPOS_ARENA_X && p_ptr->wpos.wy == WPOS_ARENA_Y && p_ptr->wpos.wz == WPOS_ARENA_Z)
2505 flag = TRUE;
2506
2507 if ((in_sector00(wpos) && (sector00flags2 & LF2_ESP)) ||
2508 (l_ptr && (l_ptr->flags2 & LF2_ESP)))
2509 flag = TRUE;
2510 }
2511
2512
2513 /* The monster is now visible */
2514 if (flag) {
2515 /* It was previously unseen */
2516 if (!p_ptr->mon_vis[m_idx]) {
2517 /* Mark as visible */
2518 p_ptr->mon_vis[m_idx] = TRUE;
2519
2520 /* Draw the monster */
2521 lite_spot(Ind, fy, fx);
2522
2523 /* Update health bar as needed */
2524 if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
2525
2526 /* Hack -- Count "fresh" sightings */
2527 if (!is_admin(p_ptr)) r_ptr->r_sights++;
2528
2529 /* Disturb on appearance */
2530 if (!m_list[m_idx].special && !(r_ptr->flags8 & RF8_ALLOW_RUNNING))
2531 if (p_ptr->disturb_move) disturb(Ind, 1, 0);
2532 }
2533
2534 /* Memorize various observable flags */
2535 #ifdef OLD_MONSTER_LORE
2536 if (do_no_esp) r_ptr->r_flags7 |= RF7_NO_ESP;
2537 if (do_empty_mind) r_ptr->r_flags2 |= RF2_EMPTY_MIND;
2538 if (do_weird_mind) r_ptr->r_flags2 |= RF2_WEIRD_MIND;
2539 if (do_cold_blood) r_ptr->r_flags2 |= RF2_COLD_BLOOD;
2540 if (do_invisible) r_ptr->r_flags2 |= RF2_INVISIBLE;
2541 #endif
2542
2543 /* Efficiency -- Notice multi-hued monsters */
2544 // if (r_ptr->flags1 & RF1_ATTR_MULTI) scan_monsters = TRUE;
2545 #ifdef RANDUNIS
2546 if ((r_ptr->flags1 & RF1_ATTR_MULTI) ||
2547 #ifdef SLOW_ATTR_BNW
2548 (r_ptr->flags7 & RF7_ATTR_BNW) ||
2549 #endif
2550 (r_ptr->flags2 & RF2_SHAPECHANGER) ||
2551 (r_ptr->flags2 & RF2_WEIRD_MIND) ||
2552 (r_ptr->flags1 & RF1_UNIQUE) ||
2553 m_ptr->ego)
2554 scan_monsters = TRUE;
2555 #else
2556 if ((r_ptr->flags1 & RF1_ATTR_MULTI) ||
2557 #ifdef SLOW_ATTR_BNW
2558 (r_ptr->flags7 & RF7_ATTR_BNW) ||
2559 #endif
2560 (r_ptr->flags2 & RF2_SHAPECHANGER) ||
2561 (r_ptr->flags2 & RF2_WEIRD_MIND) ||
2562 (r_ptr->flags1 & RF1_UNIQUE))
2563 scan_monsters = TRUE;
2564 #endif // RANDUNIS
2565 }
2566
2567 /* The monster is not visible */
2568 else {
2569 /* It was previously seen */
2570 if (p_ptr->mon_vis[m_idx]) {
2571 /* Mark as not visible */
2572 p_ptr->mon_vis[m_idx] = FALSE;
2573
2574 /* Erase the monster */
2575 lite_spot(Ind, fy, fx);
2576
2577 /* Update health bar as needed */
2578 if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
2579
2580 /* Disturb on disappearance*/
2581 if (!m_list[m_idx].special && !(r_ptr->flags8 & RF8_ALLOW_RUNNING))
2582 if (p_ptr->disturb_move) disturb(Ind, 1, 0);
2583 }
2584 }
2585
2586
2587 /* The monster is now easily visible */
2588 if (easy) {
2589 /* Change */
2590 if (!p_ptr->mon_los[m_idx]) {
2591 /* Mark as easily visible */
2592 p_ptr->mon_los[m_idx] = TRUE;
2593
2594 /* Disturb on appearance */
2595 if (!m_list[m_idx].special && !(r_ptr->flags8 & RF8_ALLOW_RUNNING))
2596 if (p_ptr->disturb_near) disturb(Ind, 1, 0);
2597
2598 /* well, is it the right place to be? */
2599 if (r_ptr->flags2 & RF2_ELDRITCH_HORROR) {
2600 sanity_blast(Ind, m_idx, FALSE);
2601 }
2602
2603 }
2604 }
2605
2606 /* The monster is not easily visible */
2607 else {
2608 /* Change */
2609 if (p_ptr->mon_los[m_idx]) {
2610 /* Mark as not easily visible */
2611 p_ptr->mon_los[m_idx] = FALSE;
2612
2613 /* Disturb on disappearance */
2614 if (!m_list[m_idx].special && !(r_ptr->flags8 & RF8_ALLOW_RUNNING))
2615 if (p_ptr->disturb_near) disturb(Ind, 1, 0);
2616 }
2617 }
2618 }
2619 }
2620 /* does nothing except handling flickering animation for WEIRD_MIND on esp.
2621 Note: We assume (just for efficiency reasons) that we're only called if
2622 monster is actually RF2_WEIRD_MIND. */
update_mon_flicker(int m_idx)2623 void update_mon_flicker(int m_idx) {
2624 monster_type *m_ptr = &m_list[m_idx];
2625 monster_race *r_ptr = race_inf(m_ptr);
2626
2627 m_ptr->no_esp_phase = FALSE;
2628
2629 /* Weird mind, occasional telepathy */
2630 if (r_ptr->flags2 & RF2_WEIRD_MIND) {
2631 if (rand_int(10)) m_ptr->no_esp_phase = TRUE;
2632 }
2633
2634 }
2635
2636
2637
2638
2639 /*
2640 * This function simply updates all the (non-dead) monsters (see above).
2641 */
update_monsters(bool dist)2642 void update_monsters(bool dist) {
2643 int i;
2644
2645 /* Efficiency -- Clear multihued flag */
2646 scan_monsters = FALSE;
2647
2648 /* Update each (live) monster */
2649 for (i = 1; i < m_max; i++) {
2650 monster_type *m_ptr = &m_list[i];
2651
2652 /* Skip dead monsters */
2653 if (!m_ptr->r_idx) continue;
2654
2655 /* Update the monster */
2656 update_mon(i, dist);
2657 }
2658 }
2659
2660
2661 /*
2662 * This function updates the visiblity flags for everyone who may see
2663 * this player.
2664 */
update_player(int Ind)2665 void update_player(int Ind) {
2666 player_type *p_ptr, *q_ptr = Players[Ind];
2667
2668 int i;
2669 cave_type **zcave;
2670
2671 /* Current player location */
2672 int py = q_ptr->py;
2673 int px = q_ptr->px;
2674
2675 /* Distance */
2676 int dis;
2677
2678 /* Seen at all */
2679 bool flag = FALSE;
2680
2681 /* Seen by vision */
2682 bool easy = FALSE;
2683
2684 /* Seen by telepathy */
2685 bool hard = FALSE;
2686
2687 /* Toned down invisibility for PvP */
2688 bool hostile, c_hostile;
2689
2690
2691 /* Check for every other player */
2692 for (i = 1; i <= NumPlayers; i++) {
2693 p_ptr = Players[i];
2694 zcave = getcave(&p_ptr->wpos);
2695
2696 /* Skip disconnected players */
2697 if (p_ptr->conn == NOT_CONNECTED) continue;
2698
2699 /* Skip players not on this depth */
2700 if(!inarea(&p_ptr->wpos, &q_ptr->wpos)) continue;
2701
2702 /* Player can always see himself */
2703 if (Ind == i) continue;
2704
2705 /* Reset the flags */
2706 flag = easy = hard = FALSE;
2707
2708 /* Compute distance */
2709 dis = distance(py, px, p_ptr->py, p_ptr->px);
2710
2711 c_hostile = check_hostile(i, Ind);
2712 hostile = ((p_ptr->wpos.wx == WPOS_PVPARENA_X &&
2713 p_ptr->wpos.wy == WPOS_PVPARENA_Y && p_ptr->wpos.wz == WPOS_PVPARENA_Z) ||
2714 ((p_ptr->mode & MODE_PVP) && (q_ptr->mode & MODE_PVP)) ||
2715 c_hostile);
2716
2717 /* Process players on current panel */
2718 if (panel_contains(py, px) && zcave) {
2719 cave_type *c_ptr = &zcave[py][px];
2720 byte *w_ptr = &p_ptr->cave_flag[py][px];
2721
2722 /* Normal line of sight, and player is not blind */
2723
2724 /* -APD- this line needs to be seperated to support seeing party
2725 members who are out of line of sight */
2726 /* if ((*w_ptr & CAVE_VIEW) && (!p_ptr->blind)) */
2727
2728 if (!p_ptr->blind) {
2729 if ((player_in_party(q_ptr->party, i)) && (q_ptr->party)) easy = flag = TRUE;
2730
2731 if (*w_ptr & CAVE_VIEW) {
2732 /* Check infravision */
2733 if (dis <= (byte)(p_ptr->see_infra)) {
2734 /* Visible */
2735 easy = flag = TRUE;
2736 }
2737
2738 /* Check illumination */
2739 if ((c_ptr->info & CAVE_LITE) || (c_ptr->info & CAVE_GLOW)) {
2740 /* Check for invisibility */
2741 if (!q_ptr->ghost || p_ptr->see_inv) {
2742 /* Visible */
2743 easy = flag = TRUE;
2744 }
2745 }
2746
2747 } /* end yucky hack */
2748 }
2749
2750 /* Telepathy can see all players */
2751 if ((p_ptr->telepathy & ESP_ALL) || (p_ptr->prace == RACE_DRACONIAN)) {
2752 bool see = FALSE;
2753
2754 if (!(p_ptr->mode & MODE_HARD)) see = TRUE;
2755 if ((p_ptr->mode & MODE_HARD) && (dis < MAX_SIGHT)) see = TRUE;
2756 /* Draconian ESP */
2757 if (!(p_ptr->telepathy & ESP_ALL) && (p_ptr->prace == RACE_DRACONIAN) &&
2758 (p_ptr->lev < 6 || (dis > (5 + p_ptr->lev / 2)))) // 3+lev/3
2759
2760 see = FALSE;
2761 if (see) {
2762 /* Visible */
2763 hard = flag = TRUE;
2764 }
2765 }
2766
2767 /* Can we see invisible players ? */
2768 if (q_ptr->invis && !player_in_party(p_ptr->party, Ind) &&
2769 (!p_ptr->see_inv ||
2770 ((q_ptr->inventory[INVEN_OUTER].k_idx) &&
2771 (q_ptr->inventory[INVEN_OUTER].tval == TV_CLOAK) &&
2772 (q_ptr->inventory[INVEN_OUTER].sval == SV_SHADOW_CLOAK))))
2773 {
2774 /* in PvP, invis shouldn't help too greatly probably */
2775 if ((q_ptr->lev > p_ptr->lev && !hostile) ||
2776 q_ptr->invis_phase >= (hostile ? 85 : 20))
2777 flag = FALSE;
2778 }
2779
2780 /* Hack: Currently cloaking is set to be effectless for PvP-mode chars here */
2781 if (q_ptr->cloaked == 1 && !q_ptr->cloak_neutralized &&
2782 !player_in_party(p_ptr->party, Ind)
2783 && !(q_ptr->mode & MODE_PVP)) flag = FALSE;
2784
2785 /* Dungeon masters can see invisible players */
2786 if (p_ptr->admin_dm || player_sees_dm(i)) flag = TRUE;
2787
2788 /* Arena Monster Challenge event provides wizard-esp too */
2789 if (ge_special_sector && p_ptr->wpos.wx == WPOS_ARENA_X && p_ptr->wpos.wy == WPOS_ARENA_Y && p_ptr->wpos.wz == WPOS_ARENA_Z)
2790 flag = TRUE;
2791
2792 #if 0 /* uses p_ptr->invis_phase too now, see 'hostile' above */
2793 /* PvP-Arena provides wizard-esp too */
2794 if (p_ptr->wpos.wx == WPOS_PVPARENA_X && p_ptr->wpos.wy == WPOS_PVPARENA_Y && p_ptr->wpos.wz == WPOS_PVPARENA_Z) flag = TRUE;
2795
2796 /* hack: PvP-mode players can ESP each other */
2797 if ((p_ptr->mode & MODE_PVP) && (q_ptr->mode & MODE_PVP)) flag = TRUE;
2798 #endif
2799
2800 /* hack -- dungeon masters are invisible */
2801 if (q_ptr->admin_dm && !player_sees_dm(i)) flag = FALSE;
2802 }
2803
2804 /* Player is now visible */
2805 if (flag) {
2806 /* It was previously unseen */
2807 if (!p_ptr->play_vis[Ind]) {
2808 /* Mark as visible */
2809 p_ptr->play_vis[Ind] = TRUE;
2810
2811 /* Draw the player */
2812 lite_spot(i, py, px);
2813
2814 #ifdef HOSTILITY_ABORTS_RUNNING
2815 /* Disturb on appearance */
2816 if (p_ptr->disturb_move && hostile) {
2817 /* Disturb */
2818 disturb(i, 1, 0);
2819 }
2820 #endif
2821 }
2822 }
2823
2824 /* The player is not visible */
2825 else {
2826 /* It was previously seen */
2827 if (p_ptr->play_vis[Ind]) {
2828 /* Mark as not visible */
2829 p_ptr->play_vis[Ind] = FALSE;
2830
2831 /* Erase the player */
2832 lite_spot(i, py, px);
2833
2834 #ifdef HOSTILITY_ABORTS_RUNNING
2835 /* Disturb on disappearance */
2836 if (p_ptr->disturb_move && hostile) {
2837 /* Disturb */
2838 disturb(i, 1, 0);
2839 }
2840 #endif
2841 }
2842 }
2843
2844 /* The player is now easily visible */
2845 if (easy) {
2846 /* Change */
2847 if (!p_ptr->play_los[Ind]) {
2848 /* Mark as easily visible */
2849 p_ptr->play_los[Ind] = TRUE;
2850
2851 #ifdef HOSTILITY_ABORTS_RUNNING
2852 /* Disturb on appearance */
2853 if (p_ptr->disturb_near && hostile) {
2854 /* Disturb */
2855 disturb(i, 1, 0);
2856 }
2857 #endif
2858 }
2859 }
2860
2861 /* The player is not easily visible */
2862 else {
2863 /* Change */
2864 if (p_ptr->play_los[Ind]) {
2865 /* Mark as not easily visible */
2866 p_ptr->play_los[Ind] = FALSE;
2867
2868 #ifdef HOSTILITY_ABORTS_RUNNING
2869 /* Disturb on disappearance */
2870 if (p_ptr->disturb_near && hostile) {
2871 /* Disturb */
2872 disturb(i, 1, 0);
2873 }
2874 #endif
2875 }
2876 }
2877 }
2878 }
2879
2880 /* only takes care of updating player's invisibility flickering.
2881 Note: we assume (just for efficiency reasons) that we're only called
2882 if player is actually invisible. */
update_player_flicker(int Ind)2883 void update_player_flicker(int Ind) {
2884 player_type *p_ptr = Players[Ind];
2885
2886 /* Can we see invisible players ? */
2887
2888 #if 0
2889 /* make it level-difference dependant? */
2890 if (randint(p_ptr->lev) > (q_ptr->lev / 2))
2891 /* just make it a fixed 25% chance for visibility? (outdated code- it's no longer bool!) */
2892 if (rand_int(4))
2893 p_ptr->invis_phase = TRUE;
2894 else p_ptr->invis_phase = FALSE;
2895 #endif
2896
2897 /* Make it more distinct, to differ between PvP and normal situations.
2898 In normal situations it wouldn't really matter, but looks cooler! */
2899 p_ptr->invis_phase = rand_int(100);
2900 }
2901
2902 /*
2903 * This function simply updates all the players (see above).
2904 */
update_players(void)2905 void update_players(void) {
2906 int i;
2907
2908 /* Update each player */
2909 for (i = 1; i <= NumPlayers; i++) {
2910 player_type *p_ptr = Players[i];
2911
2912 /* Skip disconnected players */
2913 if (p_ptr->conn == NOT_CONNECTED) continue;
2914
2915 /* Update the player */
2916 update_player(i);
2917 }
2918 }
2919
2920
2921 /* Scan all players on the level and see if at least one can find the unique */
allow_unique_level(int r_idx,struct worldpos * wpos)2922 static bool allow_unique_level(int r_idx, struct worldpos *wpos) {
2923 int i;
2924
2925 for (i = 1; i <= NumPlayers; i++) {
2926 player_type *p_ptr = Players[i];
2927
2928 /* Is the player on the level and did he killed the unique already ? */
2929 if (p_ptr->r_killed[r_idx] != 1 && (inarea(wpos, &p_ptr->wpos))) {
2930 /* One is enough */
2931 return (TRUE);
2932 }
2933 }
2934
2935 /* Yeah but we need at least ONE */
2936 return (FALSE);
2937 }
2938
2939 /* Pick a random vermin-like monster to spawn in prison houses */
get_prison_monster(void)2940 static int get_prison_monster(void) {
2941 switch (rand_int(14)) {
2942 case 0: return 27; /* rats and mice */
2943 case 1: return 86;
2944 case 2: return 156;
2945 case 3: return 1005;
2946 case 4: return 31; /* worms (low) */
2947 case 5: return 58;
2948 case 6: return 78;
2949 case 7: return 89;
2950 case 8: return 105;
2951 case 9: return 20; /* mold (except for disenchanter/red) */
2952 case 10: return 76;
2953 case 11: return 113;
2954 case 12: return 146;
2955 case 13: return 190;
2956 }
2957 return 7; /* compiler paranoia dog */
2958 }
2959
2960 /*
2961 * Attempt to place a monster of the given race at the given location.
2962 *
2963 * To give the player a sporting chance, any monster that appears in
2964 * line-of-sight and is extremely dangerous can be marked as
2965 * "FORCE_SLEEP", which will cause them to be placed with low energy,
2966 * which often (but not always) lets the player move before they do.
2967 *
2968 * This routine refuses to place out-of-depth "FORCE_DEPTH" monsters.
2969 *
2970 * XXX XXX XXX Use special "here" and "dead" flags for unique monsters,
2971 * remove old "cur_num" and "max_num" fields.
2972 *
2973 * XXX XXX XXX Actually, do something similar for artifacts, to simplify
2974 * the "preserve" mode, and to make the "what artifacts" flag more useful.
2975 */
2976 /* lots of hard-coded stuff in here -C. Blue */
place_monster_one(struct worldpos * wpos,int y,int x,int r_idx,int ego,int randuni,bool slp,int clo,int clone_summoning)2977 int place_monster_one(struct worldpos *wpos, int y, int x, int r_idx, int ego, int randuni, bool slp, int clo, int clone_summoning) {
2978 int i, Ind, j, m_idx, dlev;
2979 bool already_on_level = FALSE;
2980 cave_type *c_ptr;
2981 dun_level *l_ptr = getfloor(wpos);
2982 monster_type *m_ptr;
2983 monster_race *r_ptr = &r_info[r_idx];
2984 player_type *p_ptr;
2985 char buf[MNAME_LEN];
2986 /* for final guardians, finally! - C. Blue */
2987 struct dungeon_type *d_ptr = getdungeon(wpos);
2988 dungeon_info_type *dinfo_ptr;
2989 bool netherrealm_level = in_netherrealm(wpos);
2990 bool nr_bottom;
2991 cave_type **zcave;
2992
2993 #ifdef IRONDEEPDIVE_MIXED_TYPES
2994 if (in_irondeepdive(wpos)) dinfo_ptr = d_ptr ? &d_info[iddc[ABS(wpos->wz)].type] : NULL;
2995 else
2996 #endif
2997 dinfo_ptr = d_ptr ? &d_info[d_ptr->theme ? d_ptr->theme : d_ptr->type] : NULL;
2998
2999 #ifdef PMO_DEBUG
3000 if (PMO_DEBUG == r_idx) s_printf("PMO_DEBUG 0\n");
3001 #endif
3002 if (!(zcave = getcave(wpos))) return 1;
3003 /* Verify location */
3004 if (!in_bounds(y, x)) return 2;
3005 /* Require empty space */
3006 if (!cave_empty_bold(zcave, y, x)) return 3;
3007 /* Paranoia */
3008 if (!r_idx) return 4;
3009 /* Paranoia */
3010 if (!r_ptr->name) return 5;
3011
3012 dlev = getlevel(wpos);
3013 nr_bottom = netherrealm_level && dlev == netherrealm_end;
3014
3015 #ifdef PMO_DEBUG
3016 if (PMO_DEBUG == r_idx) s_printf("PMO_DEBUG 1\n");
3017 #endif
3018 /* No live spawn inside IDDC -- except for breeder clones/summons */
3019 if (!(summon_override_checks & SO_IDDC) &&
3020 !level_generation_time &&
3021 in_irondeepdive(wpos)
3022 && !clo && !clone_summoning)
3023 return 6;
3024
3025 /* new: no Darkling/Candlebearer live spawns (not needed because of granted spawn on level generation;
3026 and no dungeon boss live spawn either (experimental)? */
3027 if (!level_generation_time && !(summon_override_checks & SO_BOSS_MONSTERS) &&
3028 (r_idx == RI_DARKLING || r_idx == RI_CANDLEBEARER
3029 || (r_ptr->flags0 & RF0_FINAL_GUARDIAN)
3030 )) return 50;
3031
3032 #ifdef PMO_DEBUG
3033 if (PMO_DEBUG == r_idx) s_printf("PMO_DEBUG 2\n");
3034 #endif
3035 if (!(summon_override_checks & SO_PROTECTED)) {
3036 /* require non-protected field. - C. Blue
3037 Note that there are two ways (technically) to protect a field:
3038 1) use feature 210 for predefined map setups (which is a "protected brown '.' floor tile")
3039 2) use CAVE_PROT which can be toggled on runtime as required
3040 */
3041 if (zcave[y][x].info & CAVE_PROT) return 7;
3042 if (f_info[zcave[y][x].feat].flags1 & FF1_PROTECTED) return 8;
3043
3044 #if 0 /* instead: no spawns in any dungeon town! */
3045 #ifdef IRONDEEPDIVE_FIXED_TOWNS
3046 /* hack: use for static deep dive dungeon towns too */
3047 if (is_fixed_irondeepdive_town(wpos, dlev)) return 9;
3048 #endif
3049 #else
3050 if (isdungeontown(wpos)) return 10;
3051 #endif
3052 /* Keep Ironman Deep Dive Challenge entrance sector clean too */
3053 if (wpos->wx == WPOS_IRONDEEPDIVE_X && wpos->wy == WPOS_IRONDEEPDIVE_Y && !wpos->wz)
3054 return 11;
3055 }
3056
3057 if (!(summon_override_checks & SO_GRID_EMPTY)) {
3058 #if 1
3059 if (!(r_ptr->flags2 & RF2_PASS_WALL) &&
3060 (!(cave_empty_bold(zcave, y, x) &&
3061 !(cave_empty_mountain(zcave, y, x) &&
3062 ((r_ptr->flags8 & RF8_WILD_MOUNTAIN) ||
3063 (r_ptr->flags8 & RF8_WILD_VOLCANO)))))) return 12;
3064 #endif
3065 }
3066
3067 if (!(summon_override_checks & SO_GRID_TERRAIN)) {
3068 /* This usually shouldn't happen */
3069 /* but can happen when monsters group */
3070 if (!monster_can_cross_terrain(zcave[y][x].feat, r_ptr, TRUE, zcave[y][x].info)) {
3071 #if DEBUG_LEVEL > 2
3072 s_printf("WARNING: Refused monster: cannot cross terrain\n");
3073 #endif // DEBUG_LEVEL
3074 /* Better debugging */
3075 /* s_printf("place_monster_one refused monster (terrain): r_idx = %d, feat = %d at (%d, %d, %d), y = %d, x = %d\n",
3076 r_idx, zcave[y][x].feat, wpos->wx, wpos->wy, wpos->wz, y, x); */
3077 return 13;
3078 }
3079 }
3080
3081 if (!(summon_override_checks & SO_GRID_GLYPH)) {
3082 /* Hack -- no creation on glyph of warding */
3083 if (zcave[y][x].feat == FEAT_GLYPH) return 14;
3084 if (zcave[y][x].feat == FEAT_RUNE) return 15;
3085 }
3086
3087 #ifdef PMO_DEBUG
3088 if (PMO_DEBUG == r_idx) s_printf("PMO_DEBUG 3\n");
3089 #endif
3090 /* override protection for monsters spawning inside houses, to generate
3091 monster 'invaders' and/or monster 'owners' in wild houses? */
3092 if (!(summon_override_checks & SO_HOUSE)) {
3093 if (istownarea(wpos, MAX_TOWNAREA) && (zcave[y][x].info & CAVE_ICKY)) {
3094 /* exception: spawn certain vermin in prisons :) */
3095 if (zcave[y][x].info & CAVE_STCK) r_idx = get_prison_monster();
3096 else return 16;
3097 }
3098 }
3099
3100 #ifdef PMO_DEBUG
3101 if (PMO_DEBUG == r_idx) s_printf("PMO_DEBUG 4\n");
3102 #endif
3103 #ifdef RPG_SERVER /* no spawns in Training Tower at all */
3104 if (!(summon_override_checks & SO_TT_RPG)) {
3105 if (in_trainingtower(wpos)) return 17;
3106 }
3107 #endif
3108
3109 if (!(summon_override_checks & SO_EVENTS)) {
3110 /* No live spawns allowed in training tower during global event */
3111 if (ge_special_sector &&
3112 wpos->wx == WPOS_ARENA_X && wpos->wy == WPOS_ARENA_Y &&
3113 wpos->wz == WPOS_ARENA_Z)
3114 return 18;
3115
3116 /* No spawns in 0,0 pvp arena tower */
3117 if (wpos->wx == WPOS_PVPARENA_X && wpos->wy == WPOS_PVPARENA_Y && wpos->wz == WPOS_PVPARENA_Z) return 19;
3118
3119 /* Note: Spawns in 0,0 surface during events are caught in wild_add_monster() */
3120 }
3121
3122 #ifdef PMO_DEBUG
3123 if (PMO_DEBUG == r_idx) s_printf("PMO_DEBUG 5\n");
3124 #endif
3125 if (!(summon_override_checks & SO_PRE_STAIRS)) {
3126 /* No monster pre-spawns on staircases, to avoid 'pushing off' a player when he goes up/down. */
3127 if (level_generation_time && (
3128 zcave[y][x].feat == FEAT_WAY_LESS ||
3129 zcave[y][x].feat == FEAT_WAY_MORE ||
3130 zcave[y][x].feat == FEAT_LESS ||
3131 zcave[y][x].feat == FEAT_MORE)) return 20;
3132 }
3133
3134 #ifdef PMO_DEBUG
3135 if (PMO_DEBUG == r_idx) s_printf("PMO_DEBUG 6\n");
3136 #endif
3137 if (!(summon_override_checks & SO_BOSS_LEVELS)) {
3138 /* Nether Realm bottom */
3139 if (nr_bottom) {
3140 /* No live spawns after initial spawn allowed */
3141 if (!level_generation_time) return 21;
3142
3143 #if 0 /* FINAL_GUARDIAN now */
3144 /* Special hack - level is empty except for Zu-Aon */
3145 r_idx = RI_ZU_AON;
3146 #else
3147 if (r_idx != RI_ZU_AON) return 22;
3148 #endif
3149 }
3150
3151 /* Valinor - No monster spawn, except for.. */
3152 if (in_valinor(wpos) &&
3153 (r_idx != RI_BRIGHTLANCE ) && (r_idx != RI_OROME)) /* Brightlance, Orome */
3154 return 23;
3155 }
3156 #ifdef PMO_DEBUG
3157 if (PMO_DEBUG == r_idx) s_printf("PMO_DEBUG 6a\n");
3158 #endif
3159
3160 if (!(summon_override_checks & SO_BOSS_MONSTERS)) {
3161 /* Dungeon boss? */
3162 if ((r_ptr->flags0 & RF0_FINAL_GUARDIAN)) {
3163 /* May only spawn when a floor is being generated */
3164 if (!d_ptr || !level_generation_time) {
3165 #if DEBUG_LEVEL > 2
3166 s_printf("rejected FINAL_GUARDIAN %d (LIVE)\n", r_idx);
3167 #endif
3168 return 24;
3169 }
3170
3171 /* wrong monster, or not at the bottom of the dungeon? */
3172 #ifdef IRONDEEPDIVE_MIXED_TYPES
3173 if (in_irondeepdive(wpos)) {
3174 if ((r_idx != dinfo_ptr->final_guardian ||
3175 d_info[iddc[ABS(wpos->wz)].type].maxdepth != ABS(wpos->wz))
3176 /* allow Sauron in any dungeon in IDDC, and at any depth starting at 99 */
3177 && r_idx != RI_SAURON) {
3178 #if DEBUG_LEVEL > 2
3179 s_printf("rejected FINAL_GUARDIAN %d in IDDC\n", r_idx);
3180 #endif
3181 return 25;
3182 }
3183 } else
3184 #endif
3185 if (r_idx != dinfo_ptr->final_guardian ||
3186 d_ptr->maxdepth != ABS(wpos->wz)) {
3187 #if DEBUG_LEVEL > 2
3188 s_printf("rejected FINAL_GUARDIAN %d\n", r_idx);
3189 #endif
3190 return 25;
3191 }
3192 /* generating the boss is ok. go on. */
3193 // s_printf("allowed FINAL_GUARDIAN %d\n", r_idx);
3194 }
3195
3196 /* Also use for DUN_xx dungeon-restricted monsters */
3197 if (r_ptr->restrict_dun) {
3198 if (!d_ptr) return 26;
3199 #ifdef IRONDEEPDIVE_MIXED_TYPES
3200 if (in_irondeepdive(wpos)) {
3201 if (r_ptr->restrict_dun != iddc[ABS(wpos->wz)].type) return 27;
3202 } else
3203 #endif
3204 if (d_ptr->theme) {
3205 if (r_ptr->restrict_dun != d_ptr->theme) return 28;
3206 } else {
3207 if (r_ptr->restrict_dun != d_ptr->type) return 27;
3208 }
3209 }
3210
3211 /* Couple of Nether Realm-only monsters hardcoded here */
3212 if ((r_ptr->flags8 & RF8_NETHER_REALM) && !netherrealm_level)
3213 return 29;
3214
3215 /* Hellraiser may not occur right on the 1st floor of the Nether Realm */
3216 if ((r_idx == RI_HELLRAISER) && dlev < (netherrealm_start + 1)) return 30;
3217
3218 /* Dor may not occur on 'easier' (lol) NR levels */
3219 if ((r_idx == RI_DOR) && dlev < (netherrealm_start + 9)) return 31;
3220
3221 #if 0 /* FINAL_GUARDIAN now */
3222 /* Zu-Aon guards the bottom of the Nether Realm now */
3223 if ((r_idx == RI_ZU_AON) && !nr_bottom) return 32;
3224 #endif
3225
3226 /* Nether Guard isn't a unique but there's only 1 guard per level */
3227 if (r_idx == RI_NETHER_GUARD) {
3228 #if DEBUG_LEVEL > 2
3229 s_printf("Checking for old Nether Guards\n");
3230 #endif
3231 for (i = m_top - 1; i >= 0; i--) {
3232 m_idx = m_fast[i];
3233 m_ptr = &m_list[m_idx];
3234 if (!m_ptr->r_idx) {
3235 m_fast[i] = m_fast[--m_top];
3236 continue;
3237 }
3238 if ((m_ptr->r_idx == RI_NETHER_GUARD) && inarea(wpos, &m_ptr->wpos)) return 33;
3239 }
3240 }
3241
3242 /* Morgoth may not spawn 'live' if the players on his level aren't prepared correctly */
3243 /* Morgoth may not spawn 'live' at all (!) if MORGOTH_NO_TELE_VAULTS is defined!
3244 (works in conjunction with cave_gen in generate.c) */
3245 if (r_idx == RI_MORGOTH) {
3246 #ifdef MORGOTH_NO_LIVE_SPAWN
3247 /* is Morgoth not generated within a dungeon level's
3248 initialization (cave_gen in generate.c) ? */
3249 if (!level_generation_time) {
3250 /* No, it's a live spawn! (!level_generation_time) */
3251 #if DEBUG_LEVEL > 2
3252 s_printf("Morgoth live spawn prevented (MORGOTH_NO_TELE_VAULTS)\n");
3253 #endif
3254 /* Prevent that. */
3255 return 34;
3256 } else {
3257 #endif
3258 for (i = 1; i <= NumPlayers; i++) {
3259 p_ptr = Players[i];
3260 if (is_admin(p_ptr)) continue;
3261 if (inarea(&p_ptr->wpos, wpos) &&
3262 (p_ptr->total_winner || (p_ptr->r_killed[RI_SAURON] != 1))) {
3263 /* log */
3264 #if DEBUG_LEVEL > 2
3265 if (level_generation_time) {
3266 if (p_ptr->total_winner) {
3267 s_printf("Morgoth generation prevented due to winner %s\n", p_ptr->name);
3268 } else {
3269 s_printf("Morgoth generation prevented due to Sauron-misser %s\n", p_ptr->name);
3270 }
3271 } else {
3272 if (p_ptr->total_winner) {
3273 s_printf("Morgoth live spawn prevented due to winner %s\n", p_ptr->name);
3274 } else {
3275 s_printf("Morgoth live spawn prevented due to Sauron-misser %s\n", p_ptr->name);
3276 }
3277 }
3278 #endif
3279 return 35;
3280 }
3281 }
3282 #ifdef MORGOTH_NO_LIVE_SPAWN
3283 }
3284 #endif
3285 }
3286 #ifdef PMO_DEBUG
3287 if (PMO_DEBUG == r_idx) s_printf("PMO_DEBUG 6b\n");
3288 #endif
3289
3290 /* Update r_ptr due to possible r_idx changes */
3291 r_ptr = &r_info[r_idx];
3292
3293 /* "unique" monsters.. */
3294 if (r_ptr->flags1 & RF1_UNIQUE) {
3295 /* Disallow unique spawns in dungeon towns? */
3296 if (l_ptr && (l_ptr->flags1 & LF1_DUNGEON_TOWN)) return 36;
3297
3298 /* If the monster is unique and all players on this level already killed
3299 the monster, don't spawn it. (For Morgoth, especially) -C. Blue */
3300 int on_level = 0, who_killed = 0;
3301 int admin_on_level = 0, admin_who_killed = 0;
3302 for (i = 1; i <= NumPlayers; i++) {
3303 /* Count how many players are here */
3304 if (inarea(&Players[i]->wpos, wpos)) {
3305 if (Players[i]->admin_dm) admin_on_level++;
3306 else on_level++;
3307 /* Count how many of them have killed this unique monster */
3308 if (Players[i]->r_killed[r_idx] == 1) {
3309 if (Players[i]->admin_dm) admin_who_killed++;
3310 else who_killed++;
3311 }
3312 }
3313 }
3314 /* If all of them already killed it it must not be spawned */
3315 /* If players are on the level, they exclusively determine the unique summonability. */
3316 if ((on_level > 0) && (on_level <= who_killed)) {
3317 return 37; /* should be '==', but for now lets be tolerant */
3318 }
3319 /* If only admins are on the level, allow unique creation
3320 if it fits the admins' unique masks */
3321 if ((on_level == 0) && (admin_on_level <= admin_who_killed)) {
3322 return 38;
3323 }
3324
3325 /* are allowed to appear at all? */
3326 if (!allow_unique_level(r_idx, wpos)) {
3327 return 39;
3328 }
3329 }
3330
3331 if (r_idx == RI_PUMPKIN1 || r_idx == RI_PUMPKIN2 || r_idx == RI_PUMPKIN3) {
3332 /* Don't spawn the pumpkin _solely_ for the person who killed him last time. */
3333 bool admins_only = TRUE;
3334 int Ind = 0;
3335 for (i = 1; i <= NumPlayers; i++) {
3336 if (!inarea(&Players[i]->wpos, wpos)) continue;
3337 if (Players[i]->admin_dm) continue;
3338 admins_only = FALSE;
3339 //if (Players[i]->id == great_pumpkin_killer) {
3340 if (streq(Players[i]->accountname, great_pumpkin_killer)) {
3341 Ind = i;
3342 continue;
3343 }
3344 break;
3345 }
3346 if (Ind && i == NumPlayers + 1 && !admins_only) {
3347 //mad spam- s_printf("Great Pumpkin Generation prevented just for last-killer '%s'\n", Players[Ind]->name);
3348 return 52;
3349 }
3350 }
3351 }
3352
3353 #ifdef PMO_DEBUG
3354 if (PMO_DEBUG == r_idx) s_printf("PMO_DEBUG 7\n");
3355 #endif
3356
3357 /* "unique" monsters combo check */
3358 if ((r_ptr->flags1 & RF1_UNIQUE) &&
3359 !(summon_override_checks & (SO_BOSS_MONSTERS | SO_SURFACE))) {
3360 /* may not appear on the world surface */
3361 if (wpos->wz == 0) return 40;
3362 }
3363 #ifdef PMO_DEBUG
3364 if (PMO_DEBUG == r_idx) s_printf("PMO_DEBUG 8\n");
3365 #endif
3366
3367 if (!(summon_override_checks & SO_FORCE_DEPTH)) {
3368 /* Depth monsters may NOT be created out of depth */
3369 if ((r_ptr->flags1 & RF1_FORCE_DEPTH) && (dlev < r_ptr->level)) {
3370 /* Cannot create */
3371 return 41;
3372 }
3373 if ((r_ptr->flags9 & RF9_ONLY_DEPTH) && (dlev != r_ptr->level)) {
3374 /* Cannot create */
3375 return 42;
3376 }
3377 if ((r_ptr->flags7 & RF7_OOD_10) && (dlev + 10 < r_ptr->level))
3378 return 43;
3379 if ((r_ptr->flags7 & RF7_OOD_15) && (dlev + 15 < r_ptr->level))
3380 return 44;
3381 if ((r_ptr->flags7 & RF7_OOD_20) && (dlev + 20 < r_ptr->level))
3382 return 45;
3383 }
3384 #ifdef PMO_DEBUG
3385 if (PMO_DEBUG == r_idx) s_printf("PMO_DEBUG 9\n");
3386 #endif
3387
3388
3389 /* Uniques monster consistency - stuff that is exempt from overriding really */
3390 if (r_ptr->flags1 & RF1_UNIQUE) {
3391 /* Ego Uniques are NOT to be created */
3392 if (ego || randuni) return 46;
3393
3394 /* prevent duplicate uniques on a floor */
3395 for(i = 0; i < m_max; i++) {
3396 m_ptr = &m_list[i];
3397 if (m_ptr->r_idx == r_idx) {
3398 if (inarea(wpos, &m_ptr->wpos)) {
3399 already_on_level = TRUE;
3400 break;
3401 }
3402 }
3403 }
3404 /* Exception for Ironman Deep Dive Challenge:
3405 Allow unique monsters to spawn although they already exist elsewhere right now. */
3406 if ((r_ptr->cur_num >= r_ptr->max_num && !in_irondeepdive(wpos))
3407 || already_on_level) {
3408 /* Cannot create */
3409 return 47;
3410 }
3411 }
3412
3413 #ifdef PMO_DEBUG
3414 if (PMO_DEBUG == r_idx) s_printf("PMO_DEBUG 10\n");
3415 #endif
3416
3417 /* does monster require open area to be spawned in? */
3418 if ((r_ptr->flags8 & RF8_AVOID_PERMAWALLS)
3419 && !(summon_override_checks & (SO_GRID_EMPTY | SO_GRID_TERRAIN))) {
3420 /* Radius of open area should be same as max radius of player ball/cloud/etc. spells - assume 5.
3421 For simplicity we just check for box shape instead of using distance() for pseudo-ball shape. */
3422 int x2, y2;
3423 u32b flags;
3424
3425 for (x2 = x - 5; x2 <= x + 5; x2++)
3426 for (y2 = y - 5; y2 <= y + 5; y2++) {
3427 if (!in_bounds(y2, x2)) continue;
3428 flags = f_info[zcave[y2][x2].feat].flags1;
3429
3430 /* only check for walls */
3431 if (!(flags & FF1_WALL)) continue;
3432
3433 /* open area means: No permawalls
3434 (anti vault-cheeze, but also for rough level border structures) */
3435 if ((flags & FF1_PERMANENT)) return 48;
3436 }
3437 }
3438
3439 /* Access the location */
3440 c_ptr = &zcave[y][x];
3441
3442 /* does monster *prefer* roaming freely and isn't found in vaults/pits/nests usually? */
3443 if ((r_ptr->flags0 & RF0_ROAMING)
3444 && !(summon_override_checks & (SO_GRID_EMPTY | SO_GRID_TERRAIN))) {
3445 if ((c_ptr->info & (CAVE_ICKY | CAVE_NEST_PIT))) return 51;
3446 }
3447
3448 #ifdef PMO_DEBUG
3449 if (PMO_DEBUG == r_idx) s_printf("PMO_DEBUG ok\n");
3450 #endif
3451
3452
3453 /* Now could we generate an Ego Monster */
3454 r_ptr = race_info_idx(r_idx, ego, randuni);
3455
3456 /* Make a new monster */
3457 c_ptr->m_idx = m_pop();
3458
3459 /* Mega-Hack -- catch "failure" */
3460 if (!c_ptr->m_idx) return 49;
3461
3462 /* Get a new monster record */
3463 m_ptr = &m_list[c_ptr->m_idx];
3464
3465 /* Save the race */
3466 m_ptr->r_idx = r_idx;
3467 #ifdef RANDUNIS
3468 m_ptr->ego = ego;
3469 // m_ptr->name3 = randuni;
3470 #endif // RANDUNIS
3471
3472 /* Place the monster at the location */
3473 m_ptr->fy = y;
3474 m_ptr->fx = x;
3475 wpcopy(&m_ptr->wpos, wpos);
3476
3477 m_ptr->special = m_ptr->questor = FALSE;
3478
3479 /* Hack -- Count the monsters on the level */
3480 r_ptr->cur_num++;
3481
3482
3483 /* Hack -- count the number of "reproducers" */
3484 if (r_ptr->flags7 & RF7_MULTIPLY) num_repro++;
3485
3486
3487 /* Assign maximal hitpoints */
3488 if (r_ptr->flags1 & RF1_FORCE_MAXHP)
3489 m_ptr->maxhp = maxroll(r_ptr->hdice, r_ptr->hside);
3490 else
3491 m_ptr->maxhp = damroll(r_ptr->hdice, r_ptr->hside);
3492
3493 /* And start out fully healthy */
3494 m_ptr->hp = m_ptr->maxhp;
3495
3496
3497 /* Extract base ac and other things */
3498 m_ptr->ac = r_ptr->ac;
3499
3500 for (j = 0; j < 4; j++) {
3501 m_ptr->blow[j].effect = r_ptr->blow[j].effect;
3502 m_ptr->blow[j].method = r_ptr->blow[j].method;
3503 m_ptr->blow[j].d_dice = r_ptr->blow[j].d_dice;
3504 m_ptr->blow[j].d_side = r_ptr->blow[j].d_side;
3505 }
3506 m_ptr->level = r_ptr->level;
3507 m_ptr->exp = MONSTER_EXP(m_ptr->level);
3508 m_ptr->owner = 0;
3509
3510 /* Extract the monster base speed */
3511 m_ptr->speed = r_ptr->speed;
3512 /* Hack -- small racial variety */
3513 if (!(r_ptr->flags1 & RF1_UNIQUE)) {
3514 /* Allow some small variation per monster */
3515 i = extract_energy[m_ptr->speed] / 100;
3516 if (i) {
3517 j = rand_spread(0, i);
3518 m_ptr->speed += j;
3519
3520 if (m_ptr->speed < j) m_ptr->speed = 255;//overflow paranoia
3521 }
3522
3523 // if (i) m_ptr->speed += rand_spread(0, i);
3524 }
3525 /* Set monster cur speed to normal base speed */
3526 m_ptr->mspeed = m_ptr->speed;
3527
3528 /* Starts 'flickered out'? */
3529 if ((r_ptr->flags2 & RF2_WEIRD_MIND) && rand_int(10)) m_ptr->no_esp_phase = TRUE;
3530
3531
3532 /* No "damage" yet */
3533 m_ptr->stunned = 0;
3534 m_ptr->confused = 0;
3535 m_ptr->monfear = 0;
3536
3537 /* No knowledge */
3538 m_ptr->cdis = 0;
3539
3540 /* clone value */
3541 m_ptr->clone = clo;
3542 /* does this monster summon clones yet? - C. Blue */
3543 m_ptr->clone_summoning = clone_summoning;
3544 if (cfg.clone_summoning == 999)
3545 m_ptr->clone_summoning = 0;
3546 else if (m_ptr->clone_summoning > cfg.clone_summoning)
3547 m_ptr->clone += 25 * (m_ptr->clone_summoning - cfg.clone_summoning);
3548 if (m_ptr->clone > 100) m_ptr->clone = 100;
3549 /* Don't let it overflow over time.. (well, not very realistic) */
3550 if (m_ptr->clone_summoning - cfg.clone_summoning > 4) m_ptr->clone_summoning = 4 + cfg.clone_summoning;
3551
3552 /* Hack - Unique monsters are never clones - C. Blue */
3553 if (r_ptr->flags1 & RF1_UNIQUE)
3554 /* hack for global event "Arena Monster Challenge" - C. Blue */
3555 if (clone_summoning != 1000) m_ptr->clone = 0;
3556
3557 for (Ind = 1; Ind < NumPlayers + 1; Ind++) {
3558 if (Players[Ind]->conn == NOT_CONNECTED)
3559 continue;
3560
3561 Players[Ind]->mon_los[c_ptr->m_idx] = FALSE;
3562 Players[Ind]->mon_vis[c_ptr->m_idx] = FALSE;
3563 }
3564
3565 if (dlev >= (m_ptr->level + 8)) {
3566 m_ptr->exp = MONSTER_EXP(m_ptr->level + ((dlev - m_ptr->level - 5) / 3));
3567 monster_check_experience(c_ptr->m_idx, TRUE);
3568 }
3569
3570
3571 #if 0
3572 /* Hack -- Reduce risk of "instant death by breath weapons" */
3573 if (r_ptr->flags1 & RF1_FORCE_SLEEP) {
3574 /* Start out with minimal energy */
3575 m_ptr->energy = rand_int(100);
3576 } else {
3577 /* Give a random starting energy */
3578 m_ptr->energy = rand_int(1000);
3579 }
3580 #else
3581 /* make (nether realm) summons less deadly (hounds) */
3582 if (!(summon_override_checks & SO_PLAYER_SUMMON)) {
3583 /* monsters gain per turn extract_energy[]: ee=1..80 (avg: spd+10) -> per second: 60..4800 (+0..+30spd: 600..2400)
3584 * monsters need to act: level_speed() = 5*level_speeds[] = 5*(75..200) = 375..1000, 1220..1380 for NR
3585 * on extremely rough average, monsters in high-level scenarios require ~1/2s to become able to act */
3586 //m_ptr->energy = -rand_int(level_speed(wpos) - 375);//delay by 0..1/3s on extremely rough average in high-level scenarios
3587 //m_ptr->energy = -rand_int((level_speed(wpos) - 375) * 2);//delay by 0..2/3s - " -, very lenient ^^
3588 m_ptr->energy = -rand_int(((level_speed(wpos) - 1750) * 3) / 2);//delay by 0..2/3s - " -, very lenient ^^
3589 }
3590 #endif
3591
3592
3593 strcpy(buf, (r_name + r_ptr->name));
3594
3595 /* Update the monster */
3596 update_mon(c_ptr->m_idx, TRUE);
3597
3598
3599 /* Assume no sleeping */
3600 m_ptr->csleep = 0;
3601
3602 /* Enforce sleeping if needed */
3603 if (slp && r_ptr->sleep) {
3604 int val = r_ptr->sleep;
3605 m_ptr->csleep = ((val * 2) + randint(val * 10));
3606 }
3607
3608 /* if(m_ptr->hold_o_idx){
3609 s_printf("AHA! monster created with an object in hand!\n");
3610 m_ptr->hold_o_idx = 0;
3611 }*/
3612
3613 /* Remember this monster's starting values in case they get temporarily decreased (by traps!) */
3614 /* STR */
3615 for (j = 0; j < 4; j++) {
3616 m_ptr->blow[j].org_d_dice = r_ptr->blow[j].d_dice;
3617 m_ptr->blow[j].org_d_side = r_ptr->blow[j].d_side;
3618 }
3619 /* DEX */
3620 m_ptr->org_ac = m_ptr->ac;
3621 /* CON */
3622 m_ptr->org_maxhp = m_ptr->maxhp;
3623
3624 #ifdef MONSTER_ASTAR
3625 if (r_ptr->flags0 & RF0_ASTAR) {
3626 /* search for an available A* table to use */
3627 for (j = 0; j < ASTAR_MAX_INSTANCES; j++) {
3628 /* found an available instance? */
3629 if (astar_info_open[j].m_idx == -1) {
3630 astar_info_open[j].m_idx = c_ptr->m_idx;
3631 astar_info_open[j].nodes = 0; /* init: start with empty set of nodes */
3632 astar_info_closed[j].nodes = 0; /* init: start with empty set of nodes */
3633 m_ptr->astar_idx = j;
3634 break;
3635 }
3636 }
3637 /* no instance available? Mark us (-1) to use normal movement instead */
3638 if (j == ASTAR_MAX_INSTANCES) m_ptr->astar_idx = -1;
3639 }
3640 #endif
3641
3642 if ((r_ptr->flags0 & RF0_FINAL_GUARDIAN)) {
3643 s_printf("FINAL_GUARDIAN %d spawned\n", r_idx);
3644 if (level_generation_time && l_ptr) l_ptr->flags2 |= LF2_DUN_BOSS; /* Floor feeling (IDDC) */
3645 }
3646
3647 /* Success */
3648 /* Report some very interesting monster creating: */
3649 if (r_idx == RI_SAURON) {
3650 /* Apply weakness if the One Ring was destroyed previously */
3651 if (in_irondeepdive(wpos)) {
3652 if (sauron_weakened_iddc) {
3653 m_ptr->speed -= 5;
3654 m_ptr->mspeed -= 5;
3655 m_ptr->hp = (m_ptr->hp * 1) / 2;
3656 m_ptr->maxhp = (m_ptr->maxhp * 1) / 2;
3657 s_printf("Sauron was created on %d (weakened)\n", dlev);
3658 } else s_printf("Sauron was created on %d\n", dlev);
3659 } else {
3660 if (sauron_weakened) {
3661 m_ptr->speed -= 5;
3662 m_ptr->mspeed -= 5;
3663 m_ptr->hp = (m_ptr->hp * 1) / 2;
3664 m_ptr->maxhp = (m_ptr->maxhp * 1) / 2;
3665 s_printf("Sauron was created on %d (weakened)\n", dlev);
3666 } else s_printf("Sauron was created on %d\n", dlev);
3667 }
3668 }
3669 #ifdef ENABLE_MAIA
3670 // if (r_idx == RI_CANDLEBEARER) s_printf("Candlebearer was created on %d\n", dlev);
3671 // if (r_idx == RI_DARKLING) s_printf("Darkling was created on %d\n", dlev);
3672 #endif
3673 if (r_idx == RI_MORGOTH) {
3674 s_printf("Morgoth was created on %d\n", dlev);
3675 #ifdef MORGOTH_GHOST_DEATH_LEVEL
3676 if (l_ptr) l_ptr->flags1 |= LF1_NO_GHOST;
3677 #endif
3678 #ifdef MORGOTH_DANGEROUS_LEVEL
3679 /* make it even harder? */
3680 if (l_ptr) l_ptr->flags1 |= (LF1_NO_GENO | LF1_NO_DESTROY);
3681 #endif
3682 /* Page all dungeon masters to notify them of a possible Morgoth-fight >:) - C. Blue */
3683 if (watch_morgoth)
3684 for (Ind = 1; Ind <= NumPlayers; Ind++) {
3685 if (Players[Ind]->conn == NOT_CONNECTED) continue;
3686 if (Players[Ind]->admin_dm && !(Players[Ind]->afk && !streq(Players[Ind]->afk_msg, "watch"))) Players[Ind]->paging = 4;
3687 }
3688 /* if it was a live spawn, adjust his power according to amount of players on his floor */
3689 if (!level_generation_time) check_Morgoth(0);
3690 }
3691 if (r_idx == RI_TIK_SRVZLLAT) s_printf("Tik'Svrzllat was created on %d\n", dlev);
3692 if (r_idx == RI_HELLRAISER) s_printf("The Hellraiser was created on %d\n", dlev);
3693 if (r_idx == RI_DOR) s_printf("Dor was created on %d\n", dlev);
3694 /* no easy escape from Zu-Aon besides resigning by recalling! */
3695 if (r_idx == RI_ZU_AON) {
3696 s_printf("Zu-Aon, The Cosmic Border Guard was created on %d\n", dlev);
3697 if (l_ptr) l_ptr->flags1 |= (LF1_NO_GENO | LF1_NO_DESTROY);
3698 }
3699 if (r_idx == RI_PUMPKIN1 || r_idx == RI_PUMPKIN2 || r_idx == RI_PUMPKIN3)
3700 s_printf("HALLOWEEN: The Great Pumpkin (%d) was created on %d,%d,%d\n", r_idx, wpos->wx, wpos->wy, wpos->wz);
3701
3702 /* Handle floor feelings */
3703 /* Special events don't necessarily influence floor feelings */
3704 if ((r_idx != RI_PUMPKIN1 && r_idx != RI_PUMPKIN2 && r_idx != RI_PUMPKIN3) &&
3705 /* for now ignore live-spawns. maybe change that?: */
3706 (level_generation_time)) {
3707 if ((r_ptr->flags1 & RF1_UNIQUE) && l_ptr) l_ptr->flags2 |= LF2_UNIQUE;
3708 /* note: actually it could be "un-free" ie in vault :/
3709 however, checking for that distinction wouldnt pay off really,
3710 because a feeling message about vaults takes precedence over
3711 one about a single 'freely roaming ood monster' anyway: */
3712 if ((r_ptr->level >= dlev + 10) && l_ptr) {
3713 l_ptr->flags2 |= LF2_OOD;
3714 if (!(zcave[y][x].info & CAVE_ICKY)) l_ptr->flags2 |= LF2_OOD_FREE;
3715 if (r_ptr->level >= dlev + 20) l_ptr->flags2 |= LF2_OOD_HI;
3716 }
3717 }
3718
3719 /* for obtaining statistical IDDC information: */
3720 if (l_ptr) {
3721 if (level_generation_time) l_ptr->monsters_generated++;
3722 else l_ptr->monsters_spawned++;
3723 }
3724
3725 /* monster creation attempt passed! */
3726 return 0;
3727 }
3728
3729 /*
3730 * Maximum size of a group of monsters
3731 */
3732 #define GROUP_MAX 32 /* 20 would be nice for hounds maybe - C. Blue */
3733
3734
3735 /*
3736 * Attempt to place a "group" of monsters around the given location
3737 */
place_monster_group(struct worldpos * wpos,int y,int x,int r_idx,bool slp,bool little,int s_clone,int clone_summoning)3738 static bool place_monster_group(struct worldpos *wpos, int y, int x, int r_idx, bool slp, bool little, int s_clone, int clone_summoning) {
3739 monster_race *r_ptr = &r_info[r_idx];
3740
3741 int n, i;
3742 int total = 0, extra = 0;
3743
3744 int hack_n = 0;
3745
3746 byte hack_y[GROUP_MAX];
3747 byte hack_x[GROUP_MAX];
3748 cave_type **zcave;
3749 if (!(zcave = getcave(wpos))) return(FALSE);
3750
3751 /* Pick a group size */
3752 total = randint(13);
3753
3754 /* Hard monsters, small groups */
3755 if (r_ptr->level > getlevel(wpos))
3756 {
3757 extra = r_ptr->level - getlevel(wpos);
3758 extra = 0 - randint(extra);
3759 }
3760
3761 /* Easy monsters, large groups */
3762 else if (r_ptr->level < getlevel(wpos))
3763 {
3764 extra = getlevel(wpos) - r_ptr->level;
3765 extra = randint(extra);
3766 }
3767
3768 /* Hack -- limit group reduction */
3769 if (extra > 12) extra = 12;
3770
3771 /* Modify the group size */
3772 total += extra;
3773
3774 /* fewer friends.. */
3775 if (little) total >>= 2;
3776
3777 /* Minimum size */
3778 if (total < 1) total = 1;
3779
3780 /* Maximum size */
3781 if (total > GROUP_MAX) total = GROUP_MAX;
3782
3783 /* Start on the monster */
3784 hack_n = 1;
3785 hack_x[0] = x;
3786 hack_y[0] = y;
3787
3788 /* Puddle monsters, breadth first, up to total */
3789 for (n = 0; (n < hack_n) && (hack_n < total); n++)
3790 {
3791 /* Grab the location */
3792 int hx = hack_x[n];
3793 int hy = hack_y[n];
3794
3795 /* Check each direction, up to total */
3796 for (i = 0; (i < 8) && (hack_n < total); i++)
3797 {
3798 int mx = hx + ddx_ddd[i];
3799 int my = hy + ddy_ddd[i];
3800
3801 /* Walls and Monsters block flow */
3802 /* Commented out for summoning on mountains */
3803 #if 1
3804 if (!cave_empty_bold(zcave, my, mx)) continue;
3805 #endif
3806 /* Attempt to place another monster */
3807 if (place_monster_one(wpos, my, mx, r_idx, pick_ego_monster(r_idx, getlevel(wpos)), 0, slp, s_clone, clone_summoning) == 0) {
3808 /* Add it to the "hack" set */
3809 hack_y[hack_n] = my;
3810 hack_x[hack_n] = mx;
3811 hack_n++;
3812 }
3813 }
3814 }
3815
3816 /* Success */
3817 return (TRUE);
3818 }
3819
3820
3821 /*
3822 * Hack -- help pick an escort type
3823 */
3824 static int place_monster_idx = 0;
3825
3826 /*
3827 * Hack -- help pick an escort type
3828 */
place_monster_okay_escort(int r_idx)3829 static bool place_monster_okay_escort(int r_idx) {
3830 monster_race *r_ptr = &r_info[place_monster_idx];
3831 monster_race *z_ptr = &r_info[r_idx];
3832
3833 /* Require similar "race" */
3834 if (z_ptr->d_char != r_ptr->d_char) return (FALSE);
3835
3836 /* Skip more advanced monsters */
3837 if (z_ptr->level > r_ptr->level) return (FALSE);
3838
3839 /* Skip Black Dogs */
3840 if (z_ptr->flags0 & RF0_NO_GROUP_MASK) return (FALSE);
3841
3842 /* Skip unique monsters */
3843 if (z_ptr->flags1 & RF1_UNIQUE) return (FALSE);
3844
3845 /* Paranoia -- Skip identical monsters */
3846 if (place_monster_idx == r_idx) return (FALSE);
3847
3848 /* Okay */
3849 return (TRUE);
3850 }
3851
3852
3853 /*
3854 * Attempt to place a monster of the given race at the given location
3855 *
3856 * Note that certain monsters are now marked as requiring "friends".
3857 * These monsters, if successfully placed, and if the "grp" parameter
3858 * is TRUE, will be surrounded by a "group" of identical monsters.
3859 *
3860 * Note that certain monsters are now marked as requiring an "escort",
3861 * which is a collection of monsters with similar "race" but lower level.
3862 *
3863 * Some monsters induce a fake "group" flag on their escorts.
3864 *
3865 * Note the "bizarre" use of non-recursion to prevent annoying output
3866 * when running a code profiler.
3867 *
3868 * Note the use of the new "monster allocation table" code to restrict
3869 * the "get_mon_num()" function to "legal" escort types.
3870 */
place_monster_aux(struct worldpos * wpos,int y,int x,int r_idx,bool slp,bool grp,int clo,int clone_summoning)3871 int place_monster_aux(struct worldpos *wpos, int y, int x, int r_idx, bool slp, bool grp, int clo, int clone_summoning) {
3872 int i;
3873 monster_race *r_ptr = &r_info[r_idx];
3874 cave_type **zcave;
3875 int level = getlevel(wpos), res;
3876 if (!(zcave = getcave(wpos))) return -1;
3877
3878 #ifdef ARCADE_SERVER
3879 if (in_trainingtower(wpos)) return -2;
3880 #endif
3881
3882 if (!(summon_override_checks & SO_SURFACE)) {
3883 /* Do not allow breeders to spawn in the wilderness - the_sandman */
3884 if ((r_ptr->flags7 & RF7_MULTIPLY) && !(wpos->wz)) return -3;
3885 }
3886
3887 /* Place one monster, or fail */
3888 if ((res = place_monster_one(wpos, y, x, r_idx, pick_ego_monster(r_idx, level), 0, slp, clo, clone_summoning)) != 0) {
3889 // DEBUG
3890 /* s_printf("place_monster_one failed at (%d, %d, %d), y = %d, x = %d, r_idx = %d, feat = %d\n",
3891 wpos->wx, wpos->wy, wpos->wz, y, x, r_idx, zcave[y][x].feat); */
3892 return res;
3893 }
3894
3895 /* Require the "group" flag */
3896 if (!grp) return 0;
3897 #ifdef BLOODLETTER_SUMMON_NERF
3898 if (r_idx == RI_BLOODLETTER) return 0;
3899 #endif
3900
3901 /* Friend for certain monsters */
3902 if (r_ptr->flags1 & RF1_FRIEND) {
3903 /* Attempt to place a group */
3904 (void)place_monster_group(wpos, y, x, r_idx, slp, TRUE, clo, clone_summoning);
3905 }
3906
3907 /* Friends for certain monsters */
3908 if (r_ptr->flags1 & RF1_FRIENDS) {
3909 /* Attempt to place a group */
3910 (void)place_monster_group(wpos, y, x, r_idx, slp, FALSE, clo, clone_summoning);
3911 }
3912
3913
3914 /* Escorts for certain monsters */
3915 if (r_ptr->flags1 & RF1_ESCORT) {
3916 dungeon_type *dt_ptr = getdungeon(wpos);
3917 int dun_type = 0;
3918 #ifdef IRONDEEPDIVE_MIXED_TYPES
3919 if (in_irondeepdive(wpos)) dun_type = iddc[ABS(wpos->wz)].type;
3920 else
3921 #endif
3922 if (dt_ptr) {
3923 if (dt_ptr->theme) dun_type = dt_ptr->theme;
3924 else dun_type = dt_ptr->type;
3925 }
3926
3927 /* Try to place several "escorts" */
3928 for (i = 0; i < 50; i++) {
3929 int nx, ny, z, d = 3;
3930
3931 /* Pick a location */
3932 scatter(wpos, &ny, &nx, y, x, d, 0);
3933 /* Require empty grids */
3934 if (!cave_empty_bold(zcave, ny, nx)) continue;
3935
3936 /* Set the escort index */
3937 place_monster_idx = r_idx;
3938
3939 /* Set the escort hook */
3940 get_mon_num_hook = place_monster_okay_escort;
3941
3942 /* Prepare allocation table */
3943 get_mon_num_prep(dun_type, NULL);
3944
3945 /* Pick a random race */
3946 z = get_mon_num(r_ptr->level, r_ptr->level - 20); //not too high level escort for lower level boss
3947
3948
3949 /* Remove restriction */
3950 get_mon_num_hook = dungeon_aux;
3951
3952 /* Handle failure */
3953 if (!z) break;
3954
3955 /* Place a single escort */
3956 (void)place_monster_one(wpos, ny, nx, z, pick_ego_monster(z, level), 0, slp, clo, clone_summoning);
3957
3958 #ifdef TEST_SERVER
3959 if (r_ptr->flags1 & RF1_ESCORTS)
3960 (void)place_monster_group(wpos, ny, nx, z, slp, TRUE, clo, clone_summoning);
3961 #else
3962 /* Place a "group" of escorts if needed */
3963 if ((r_info[z].flags1 & RF1_FRIENDS) ||
3964 (r_ptr->flags1 & RF1_ESCORTS))
3965 {
3966 /* Place a group of monsters */
3967 #if 0
3968 (void)place_monster_group(wpos, ny, nx, z, slp, FALSE, clo, clone_summoning);
3969 #else
3970 (void)place_monster_group(wpos, ny, nx, z, slp, (r_info[z].flags1 & RF1_FRIENDS) ? TRUE : FALSE, clo, clone_summoning);
3971 #endif
3972 }
3973 #endif
3974 }
3975 }
3976
3977
3978 /* Success */
3979 return 0;
3980 }
3981
3982
3983 /*
3984 * Hack -- attempt to place a monster at the given location
3985 *
3986 * Attempt to find a monster appropriate to the "monster_level"
3987 */
place_monster(struct worldpos * wpos,int y,int x,bool slp,bool grp)3988 bool place_monster(struct worldpos *wpos, int y, int x, bool slp, bool grp) {
3989 int r_idx = 0, i;
3990 player_type *p_ptr;
3991 int lev = getlevel(wpos); /* HALLOWEEN; and
3992 new: anti-double-OOD */
3993 #ifdef RPG_SERVER
3994 struct dungeon_type *d_ptr = getdungeon(wpos);
3995 #endif
3996 struct dun_level *l_ptr = getfloor(wpos);
3997
3998
3999 if (season_halloween && great_pumpkin_timer == 0 && wpos->wz != 0 &&
4000 level_generation_time && /* spawn it only on level generation time? yes, because of high-lev camping TT while lowbies frequent it, spawning it for him */
4001 /* Don't waste Great Pumpkins on low-level IDDC floors */
4002 (!in_irondeepdive(wpos) || wpos->wz >= 20)) {
4003 bool no_high_level_players = TRUE;
4004
4005 /* Verify that no high-level player is on this level! */
4006 for (i = 1; i <= NumPlayers; i++) {
4007 p_ptr = Players[i];
4008 //if (is_admin(p_ptr)) continue;
4009 if (p_ptr->admin_dm) continue;
4010 if (!inarea(&p_ptr->wpos, wpos)) continue;
4011 #ifndef RPG_SERVER
4012 if (p_ptr->max_lev <= 35) continue;
4013 //spam s_printf("Great Pumpkin spawn prevented by player>35 %s\n", p_ptr->name);
4014 #else
4015 if (p_ptr->max_lev <= 40) continue;
4016 //spam s_printf("Great Pumpkin spawn prevented by player>40 %s\n", p_ptr->name);
4017 #endif
4018 no_high_level_players = FALSE;
4019 break;
4020 }
4021
4022 /* Place a Great Pumpkin sometimes -- WARNING: HARDCODED r_idx */
4023 #ifndef RPG_SERVER
4024 if (no_high_level_players && (lev < 40)) {
4025 if (lev > 20) r_idx = RI_PUMPKIN3;//10k HP
4026 else {
4027 if (lev > 10) r_idx = RI_PUMPKIN2;//6k HP
4028 else r_idx = RI_PUMPKIN1;//3k HP, smallest version
4029
4030 if (magik(15)) r_idx = RI_PUMPKIN2; /* sometimes tougher */
4031 else if (magik(15)) r_idx = RI_PUMPKIN3; /* sometimes tougher */
4032 }
4033 #else
4034 if (no_high_level_players && (lev < 50) && !(d_ptr->flags2 & DF2_NO_DEATH)) { /* not in Training Tower */
4035 if (lev > 30) r_idx = RI_PUMPKIN3;//6.6k HP
4036 else {
4037 if (lev > 15) r_idx = RI_PUMPKIN2;//4k HP
4038 else r_idx = RI_PUMPKIN1;//2k HP, smallest version
4039
4040 if (magik(15)) r_idx = RI_PUMPKIN2; /* sometimes tougher */
4041 else if (magik(15)) r_idx = RI_PUMPKIN3; /* sometimes tougher */
4042 }
4043 #endif
4044
4045 if (place_monster_aux(wpos, y, x, r_idx, FALSE, FALSE, 0, 0) == 0) {
4046 //spam s_printf("%s HALLOWEEN: Generated Great Pumpkin (%d) on %d,%d,%d (lev %d)\n", showtime(), r_idx, wpos->wx, wpos->wy, wpos->wz, lev);
4047 great_pumpkin_timer = -1; /* put generation on hold */
4048 great_pumpkin_duration = 60;
4049
4050 /* This seems to be crashing the server - mikaelh */
4051 // check_Pumpkin(); /* recall high-level players off this floor! */
4052
4053 return(TRUE);
4054 }
4055 /* oupsee */
4056 #if 0 /* not necessary/wrong even (if place_monster_aux() fails -> problem) */
4057 great_pumpkin_timer = 1; /* <- just paranoia: no mass-emptiness in case above always fails for unknown reasons */
4058 return(FALSE);
4059 #else
4060 /* fall through and generate a usual monster instead */
4061 r_idx = 0;
4062 #endif
4063 }
4064 }
4065
4066
4067 #if 0 /* unused - mikaelh */
4068 /* Specific filter - should be made more useful */
4069 /* Ok, I'll see to that later - Jir - */
4070
4071 struct dungeon_type *d_ptr = getdungeon(wpos);
4072
4073 if(d_ptr && (d_ptr->r_char[0] || d_ptr->nr_char[0])){
4074 int i, j = 0;
4075 monster_race *r_ptr;
4076 while((r_idx = get_mon_num(monster_level, lev))){
4077 if(j++ > 250) break;
4078 r_ptr = &r_info[r_idx];
4079 if(d_ptr->r_char[0]){
4080 for (i = 0; i < 10; i++)
4081 {
4082 if (r_ptr->d_char == d_ptr->r_char[i]) break;
4083 }
4084 if(i < 10) break;
4085 continue;
4086 }
4087 if(d_ptr->nr_char[0]){
4088 for (i = 0; i < 10; i++)
4089 {
4090 if (r_ptr->d_char == d_ptr->r_char[i]) continue;
4091 }
4092 break;
4093 }
4094 }
4095 }
4096 else
4097 #endif
4098 {
4099 cave_type **zcave;
4100 dungeon_type *dt_ptr = getdungeon(wpos);
4101 int dun_type = 0;
4102 #ifdef IRONDEEPDIVE_MIXED_TYPES
4103 if (in_irondeepdive(wpos)) dun_type = iddc[ABS(wpos->wz)].type;
4104 else
4105 #endif
4106 if (dt_ptr) {
4107 if (dt_ptr->theme) dun_type = dt_ptr->theme;
4108 else dun_type = dt_ptr->type;
4109 }
4110
4111 if (in_bounds(y, x) && (zcave = getcave(wpos))) {
4112 /* Set monster restriction */
4113 set_mon_num2_hook(zcave[y][x].feat);
4114 }
4115
4116 /* Prepare allocation table */
4117 get_mon_num_prep(dun_type, l_ptr ? l_ptr->uniques_killed : NULL);
4118
4119 /* Pick a monster */
4120 r_idx = get_mon_num(monster_level, lev);
4121
4122 /* Reset restriction */
4123 get_mon_num2_hook = NULL;
4124 }
4125
4126 /* Handle failure */
4127 if (!r_idx) return (FALSE);
4128
4129 /* Attempt to place the monster */
4130 if (place_monster_aux(wpos, y, x, r_idx, slp, grp, FALSE, 0) == 0) return (TRUE);
4131
4132 /* Oops */
4133 return (FALSE);
4134 }
4135
4136 /*
4137 * XXX XXX XXX Player Ghosts are such a hack, they have been completely
4138 * removed until Angband 2.8.0, in which there will actually be a small
4139 * number of "unique" monsters which will serve as the "player ghosts".
4140 * Each will have a place holder for the "name" of a deceased player,
4141 * which will be extracted from a "bone" file, or replaced with a
4142 * "default" name if a real name is not available. Each ghost will
4143 * appear exactly once and will not induce a special feeling.
4144 *
4145 * Possible methods:
4146 * (s) 1 Skeleton
4147 * (z) 1 Zombie
4148 * (M) 1 Mummy
4149 * (G) 1 Polterguiest, 1 Spirit, 1 Ghost, 1 Shadow, 1 Phantom
4150 * (W) 1 Wraith
4151 * (V) 1 Vampire, 1 Vampire Lord
4152 * (L) 1 Lich
4153 *
4154 * Possible change: Lose 1 ghost, Add "Master Lich"
4155 *
4156 * Possible change: Lose 2 ghosts, Add "Wraith", Add "Master Lich"
4157 *
4158 * Possible change: Lose 4 ghosts, lose 1 vampire lord
4159 *
4160 * Note that ghosts should never sleep, should be very attentive, should
4161 * have maximal hitpoints, drop only good (or great) items, should be
4162 * cold blooded, evil, undead, immune to poison, sleep, confusion, fear.
4163 *
4164 * Base monsters:
4165 * Skeleton
4166 * Zombie
4167 * Mummy
4168 * Poltergeist
4169 * Spirit
4170 * Ghost
4171 * Vampire
4172 * Wraith
4173 * Vampire Lord
4174 * Shadow
4175 * Phantom
4176 * Lich
4177 *
4178 * This routine will simply extract ghost names from files, and
4179 * attempt to allocate a player ghost somewhere in the dungeon,
4180 * note that normal allocation may also attempt to place ghosts,
4181 * so we must work with some form of default names.
4182 *
4183 * XXX XXX XXX XXX
4184 */
4185
4186
4187
4188
4189
4190 /*
4191 * Attempt to allocate a random monster in the dungeon.
4192 *
4193 * Place the monster at least "dis" distance from the player.
4194 *
4195 * Use "slp" to choose the initial "sleep" status
4196 *
4197 * Use "monster_level" for the monster level
4198 */
4199 bool alloc_monster(struct worldpos *wpos, int dis, int slp) {
4200 int y, x, i, d, min_dis = 999;
4201 int tries = 0;
4202 player_type *p_ptr;
4203 cave_type **zcave;
4204 if (!(zcave = getcave(wpos))) return(FALSE);
4205
4206 /* Find a legal, distant, unoccupied, space */
4207 while (tries < 50) {
4208 /* Increase the counter */
4209 tries++;
4210
4211 /* Pick a location */
4212 y = rand_int(getlevel(wpos) ? MAX_HGT : MAX_HGT);
4213 x = rand_int(getlevel(wpos) ? MAX_WID : MAX_WID);
4214
4215 /* Require "naked" floor grid */
4216 if (!cave_naked_bold(zcave, y, x)) continue;
4217
4218 /* Accept far away grids */
4219 for (i = 1; i < NumPlayers + 1; i++)
4220 {
4221 p_ptr = Players[i];
4222
4223 /* Skip him if he's not playing */
4224 if (p_ptr->conn == NOT_CONNECTED)
4225 continue;
4226
4227 /* Skip him if he's not on this depth */
4228 if(!inarea(wpos, &p_ptr->wpos))
4229 continue;
4230
4231 if ((d = distance(y, x, p_ptr->py, p_ptr->px)) < min_dis)
4232 min_dis = d;
4233 }
4234
4235 if (min_dis >= dis)
4236 break;
4237 }
4238
4239 /* Abort */
4240 if (tries >= 50)
4241 return (FALSE);
4242
4243 /*printf("Trying to place a monster at %d, %d.\n", y, x);*/
4244
4245 /* Attempt to place the monster, allow groups */
4246 if (place_monster(wpos, y, x, slp, TRUE)) return (TRUE);
4247
4248 /* Nope */
4249 return (FALSE);
4250 }
4251
4252 /* Used for dungeon bosses, aka FINAL_GUARDIAN - C. Blue */
4253 int alloc_monster_specific(struct worldpos *wpos, int r_idx, int dis, int slp) {
4254 int y, x, i, d, min_dis = 999, org_dis = dis, res;
4255 int tries = 2000;
4256 player_type *p_ptr;
4257 cave_type **zcave;
4258 if (!(zcave = getcave(wpos))) return -1;
4259 dun_level *l_ptr = getfloor(wpos);
4260
4261 /* Find a legal, distant, unoccupied, space */
4262 while (--tries) { /* try especially hard to succeed */
4263 /* Pick a location */
4264 y = rand_int(l_ptr->hgt);
4265 x = rand_int(l_ptr->wid);
4266
4267 /* Require "naked" floor grid */
4268 if (!cave_naked_bold(zcave, y, x)) continue;
4269
4270
4271 /* ---------- specific location restrictions for this monster? ---------- */
4272 /* does monster require open area to be spawned in? */
4273 if ((r_info[r_idx].flags8 & RF8_AVOID_PERMAWALLS)
4274 && !(summon_override_checks & (SO_GRID_EMPTY | SO_GRID_TERRAIN))) {
4275 /* Radius of open area should be same as max radius of player ball/cloud/etc. spells - assume 5.
4276 For simplicity we just check for box shape instead of using distance() for pseudo-ball shape. */
4277 int x2, y2;
4278 u32b flags;
4279 bool broke = FALSE;
4280
4281 for (x2 = x - 5; x2 <= x + 5; x2++) {
4282 for (y2 = y - 5; y2 <= y + 5; y2++) {
4283 if (!in_bounds(y2, x2)) continue;
4284 flags = f_info[zcave[y2][x2].feat].flags1;
4285
4286 /* only check for walls */
4287 if (!(flags & FF1_WALL)) continue;
4288
4289 /* open area means: No permawalls
4290 (anti vault-cheeze, but also for rough level border structures) */
4291 if ((flags & FF1_PERMANENT)) {
4292 broke = TRUE;
4293 break;
4294 }
4295 }
4296 if (broke) break;
4297 }
4298 if (broke) continue;
4299 }
4300 /* does monster *prefer* roaming freely and isn't found in vaults/pits/nests usually? */
4301 if ((r_info[r_idx].flags0 & RF0_ROAMING)
4302 && !(summon_override_checks & (SO_GRID_EMPTY | SO_GRID_TERRAIN))) {
4303 if ((zcave[y][x].info & (CAVE_ICKY | CAVE_NEST_PIT))) continue;
4304 }
4305
4306
4307 /* Accept far away grids */
4308 for (i = 1; i < NumPlayers + 1; i++) {
4309 p_ptr = Players[i];
4310
4311 /* Skip him if he's not playing */
4312 if (p_ptr->conn == NOT_CONNECTED)
4313 continue;
4314
4315 /* Skip him if he's not on this depth */
4316 if(!inarea(wpos, &p_ptr->wpos))
4317 continue;
4318
4319 if ((d = distance(y, x, p_ptr->py, p_ptr->px)) < min_dis)
4320 min_dis = d;
4321 }
4322
4323 if (min_dis >= dis) break;
4324
4325 /* try especially hard to succeed */
4326 if (!(tries % 100)) dis -= org_dis / 10;
4327 }
4328
4329 /* Abort */
4330 if (!tries) {
4331 /* fun stuff. it STILL fails here "relatively" often.. -_- */
4332 s_printf("allocate_monster_specific() out of tries for r_idx %d on %s.\n", r_idx, wpos_format(0, wpos));
4333 return -2;
4334 }
4335
4336 /* Attempt to place the monster, allow groups */
4337 if ((res = place_monster_aux(wpos, y, x, r_idx, slp, TRUE, FALSE, 0)) == 0) return 0;
4338
4339 /* Nope */
4340 if (res != 37) /* no spam for players who have killed the boss already */
4341 s_printf("allocate_monster_specific()->place_monster_aux() failed for r_idx %d on %s (%d).\n", r_idx, wpos_format(0, wpos), res);
4342
4343 return res;
4344 }
4345
4346 /*
4347 * Hack -- the "type" of the current "summon specific"
4348 */
4349 static int summon_specific_type = 0; /* SUMMON_ALL */
4350
4351
4352 /*
4353 * Hack -- help decide if a monster race is "okay" to summon
4354 */
4355 /* Disallow summoning unique monsters except for
4356 explicite SUMMON_UNIQUE/SUMMON_HI_UNIQUE calls? */
4357 #define EXPLICITE_UNIQUE_SUMMONING
4358 static bool summon_specific_okay(int r_idx) {
4359 monster_race *r_ptr = &r_info[r_idx];
4360 bool okay = FALSE;
4361
4362 /* Dungeon bosses are never okay; they can only be generated on level creation time */
4363 if ((r_ptr->flags0 & RF0_FINAL_GUARDIAN)) return FALSE;
4364
4365 /* Hack -- no specific type specified */
4366 if (!summon_specific_type) return TRUE; /* 'SUMMON_ALL' */
4367
4368 /* Check our requirements */
4369 switch (summon_specific_type) {
4370 case SUMMON_ALL_U98:
4371 okay = (r_ptr->level <= 98 ||
4372 !(r_ptr->flags1 & RF1_UNIQUE));
4373 break;
4374 case SUMMON_MONSTER:
4375 okay = (!(r_ptr->flags1 & RF1_UNIQUE));
4376 break;
4377 case SUMMON_ANT:
4378 okay = ((r_ptr->d_char == 'a') &&
4379 !(r_ptr->flags1 & RF1_UNIQUE));
4380 break;
4381 case SUMMON_SPIDER:
4382 okay = ((r_ptr->d_char == 'S') &&
4383 !(r_ptr->flags1 & RF1_UNIQUE));
4384 break;
4385 case SUMMON_HOUND:
4386 okay = (((r_ptr->d_char == 'C') || (r_ptr->d_char == 'Z')) &&
4387 !(r_ptr->flags1 & RF1_UNIQUE));
4388 break;
4389 case SUMMON_HYDRA:
4390 okay = ((r_ptr->d_char == 'M') &&
4391 !(r_ptr->flags1 & RF1_UNIQUE));
4392 break;
4393 case SUMMON_ANGEL:
4394 okay = ((r_ptr->d_char == 'A') &&
4395 !(r_ptr->flags1 & RF1_UNIQUE));
4396 break;
4397 case SUMMON_DEMON:
4398 okay = ((r_ptr->flags3 & RF3_DEMON) &&
4399 !(r_ptr->flags1 & RF1_UNIQUE));
4400 break;
4401 case SUMMON_UNDEAD:
4402 okay = ((r_ptr->flags3 & RF3_UNDEAD) &&
4403 !(r_ptr->flags1 & RF1_UNIQUE));
4404 break;
4405 case SUMMON_DRAGON:
4406 okay = ((r_ptr->flags3 & RF3_DRAGON) &&
4407 !(r_ptr->flags1 & RF1_UNIQUE));
4408 break;
4409 case SUMMON_HI_UNDEAD:
4410 okay = (((r_ptr->d_char == 'L') ||
4411 (r_ptr->d_char == 'V') ||
4412 (r_ptr->d_char == 'W')) &&
4413 (r_ptr->level >= 45)
4414 #ifdef EXPLICITE_UNIQUE_SUMMONING
4415 && (!(r_ptr->flags1 & RF1_UNIQUE)
4416 || (r_ptr->flags7 & RF7_NAZGUL)) /* exception: allow Nazgul! */
4417 #endif
4418 );
4419 break;
4420 case SUMMON_HI_DRAGON:
4421 okay = (r_ptr->d_char == 'D'
4422 #ifdef EXPLICITE_UNIQUE_SUMMONING
4423 && !(r_ptr->flags1 & RF1_UNIQUE)
4424 #endif
4425 );
4426 break;
4427 case SUMMON_NAZGUL:
4428 okay = ((r_ptr->flags7 & RF7_NAZGUL));
4429 break;
4430 case SUMMON_UNIQUE:
4431 okay = ((r_ptr->flags1 & RF1_UNIQUE));
4432 break;
4433
4434 /* PernA-addition
4435 * many of them are unused for now. - Jir -
4436 * */
4437 case SUMMON_BIZARRE1:
4438 okay = ((r_ptr->d_char == 'm') &&
4439 !(r_ptr->flags1 & (RF1_UNIQUE)));
4440 break;
4441 case SUMMON_BIZARRE2:
4442 okay = ((r_ptr->d_char == 'b') &&
4443 !(r_ptr->flags1 & (RF1_UNIQUE)));
4444 break;
4445 case SUMMON_BIZARRE3:
4446 okay = ((r_ptr->d_char == 'Q') &&
4447 !(r_ptr->flags1 & (RF1_UNIQUE)));
4448 break;
4449 case SUMMON_BIZARRE4:
4450 okay = ((r_ptr->d_char == 'v') &&
4451 !(r_ptr->flags1 & (RF1_UNIQUE)));
4452 break;
4453 case SUMMON_BIZARRE5:
4454 okay = ((r_ptr->d_char == '$') &&
4455 !(r_ptr->flags1 & (RF1_UNIQUE)));
4456 break;
4457 case SUMMON_BIZARRE6:
4458 okay = (((r_ptr->d_char == '!') ||
4459 (r_ptr->d_char == '?') ||
4460 (r_ptr->d_char == '=') ||
4461 (r_ptr->d_char == '$') ||
4462 (r_ptr->d_char == '|') ||
4463 (r_ptr->flags9 & (RF9_MIMIC)) ) &&
4464 !(r_ptr->flags1 & (RF1_UNIQUE)));
4465 break;
4466 case SUMMON_HI_DEMON:
4467 okay = ((r_ptr->flags3 & (RF3_DEMON)) &&
4468 (r_ptr->d_char == 'U') &&
4469 (r_ptr->level >= 49) &&
4470 !(r_ptr->flags1 & RF1_UNIQUE));
4471 break;
4472 #if 1 // welcome, Julian Lighton Hack ;)
4473 case SUMMON_KIN:
4474 okay = ((r_ptr->d_char == summon_kin_type) &&
4475 !(r_ptr->flags1 & (RF1_UNIQUE)));
4476 break;
4477 #endif // 0
4478 case SUMMON_DAWN:
4479 okay = ((strstr((r_name + r_ptr->name),"the Dawn")) &&
4480 !(r_ptr->flags1 & (RF1_UNIQUE)));
4481 break;
4482 case SUMMON_ANIMAL:
4483 okay = ((r_ptr->flags3 & (RF3_ANIMAL)) &&
4484 !(r_ptr->flags1 & (RF1_UNIQUE)));
4485 break;
4486 case SUMMON_ANIMAL_RANGER:
4487 okay = ((r_ptr->flags3 & (RF3_ANIMAL)) &&
4488 (strchr("abcflqrwBCIJKMRS", r_ptr->d_char)) &&
4489 !(r_ptr->flags3 & (RF3_DRAGON))&&
4490 !(r_ptr->flags3 & (RF3_EVIL)) &&
4491 !(r_ptr->flags3 & (RF3_UNDEAD))&&
4492 !(r_ptr->flags3 & (RF3_DEMON)) &&
4493 !(r_ptr->flags4 || r_ptr->flags5 || r_ptr->flags6) &&
4494 !(r_ptr->flags1 & (RF1_UNIQUE)));
4495 break;
4496 case SUMMON_HI_UNDEAD_NO_UNIQUES:
4497 okay = (((r_ptr->d_char == 'L') ||
4498 (r_ptr->d_char == 'V') ||
4499 (r_ptr->d_char == 'W')) &&
4500 (r_ptr->level >= 45) &&
4501 !(r_ptr->flags1 & (RF1_UNIQUE)));
4502 break;
4503 case SUMMON_HI_DRAGON_NO_UNIQUES:
4504 okay = ((r_ptr->d_char == 'D') &&
4505 !(r_ptr->flags1 &(RF1_UNIQUE)));
4506 break;
4507 case SUMMON_NO_UNIQUES:
4508 okay = (!(r_ptr->flags1 & (RF1_UNIQUE)));
4509 break;
4510 case SUMMON_PHANTOM:
4511 okay = ((strstr((r_name + r_ptr->name),"Phantom")) &&
4512 !(r_ptr->flags1 & (RF1_UNIQUE)));
4513 break;
4514 case SUMMON_ELEMENTAL:
4515 okay = ((strstr((r_name + r_ptr->name),"lemental")) &&
4516 !(r_ptr->flags1 & (RF1_UNIQUE)));
4517 break;
4518 case SUMMON_DRAGONRIDER:
4519 okay = ((r_ptr->flags3 & RF3_DRAGONRIDER)
4520 #ifdef EXPLICITE_UNIQUE_SUMMONING
4521 && !(r_ptr->flags1 & RF1_UNIQUE)
4522 #endif
4523 );
4524 break;
4525 case SUMMON_BLUE_HORROR:
4526 okay = ((strstr((r_name + r_ptr->name),"lue horror")) &&
4527 !(r_ptr->flags1 & (RF1_UNIQUE)));
4528 break;
4529 case SUMMON_BUG:
4530 okay = ((strstr((r_name + r_ptr->name),"Software bug")) &&
4531 !(r_ptr->flags1 & (RF1_UNIQUE)));
4532 break;
4533 case SUMMON_RNG:
4534 okay = ((strstr((r_name + r_ptr->name),"Random Number Generator")) &&
4535 !(r_ptr->flags1 & (RF1_UNIQUE)));
4536 break;
4537 case SUMMON_IMMOBILE:
4538 okay = ((r_ptr->flags1 & RF1_NEVER_MOVE)
4539 #ifdef EXPLICITE_UNIQUE_SUMMONING
4540 && !(r_ptr->flags1 & RF1_UNIQUE)
4541 #endif
4542 );
4543 break;
4544 case SUMMON_HUMAN:
4545 okay = ((r_ptr->d_char == 'p') &&
4546 !(r_ptr->flags1 & (RF1_UNIQUE)));
4547 break;
4548 case SUMMON_SHADOW:
4549 okay = ((r_ptr->d_char == 'G') &&
4550 !(r_ptr->flags1 & (RF1_UNIQUE)));
4551 break;
4552 case SUMMON_QUYLTHULG:
4553 okay = ((r_ptr->d_char == 'Q') &&
4554 !(r_ptr->flags1 & (RF1_UNIQUE)));
4555 break;
4556 case SUMMON_VERMIN:
4557 okay = ((r_ptr->flags7 & RF7_MULTIPLY)
4558 #ifdef EXPLICITE_UNIQUE_SUMMONING /* paranoia - there cannot be unique multiplying vermin, but whatever */
4559 && !(r_ptr->flags1 & RF1_UNIQUE)
4560 #endif
4561 );
4562 break;
4563 case SUMMON_PATIENT:
4564 okay = ((r_ptr->flags1 & RF1_NEVER_MOVE) &&
4565 !(r_ptr->flags4 || r_ptr->flags5 || r_ptr->flags6 || (r_ptr->flags0 & RF0_ACTIVE_MASK))
4566 #ifdef EXPLICITE_UNIQUE_SUMMONING
4567 && !(r_ptr->flags1 & RF1_UNIQUE)
4568 #endif
4569 );
4570 break;
4571 #ifdef USE_LUA
4572 #if 0 // let's leave it to DG :)
4573 case SUMMON_LUA:
4574 okay = summon_lua_okay(r_idx);
4575 break;
4576 #endif
4577 #endif
4578 case SUMMON_HI_MONSTER:
4579 okay = (r_ptr->level >= 60
4580 #ifdef EXPLICITE_UNIQUE_SUMMONING
4581 && !(r_ptr->flags1 & RF1_UNIQUE)
4582 #endif
4583 );
4584 break;
4585 case SUMMON_HI_UNIQUE:
4586 okay = ((r_ptr->flags1 & RF1_UNIQUE)
4587 && (r_ptr->level >= 60));
4588 break;
4589 case SUMMON_SPOOK:
4590 okay = ((r_ptr->d_char == 'G')
4591 && (r_ptr->flags2 & RF2_INVISIBLE) /* hm, no phantom warriors (also excludes spectres) */
4592 #ifdef EXPLICITE_UNIQUE_SUMMONING
4593 && !(r_ptr->flags1 & RF1_UNIQUE)
4594 #endif
4595 && (r_ptr->level <= 31)); /* 31 for Ghost, 33 also allows Shade (somewhat nasty) */
4596 break;
4597 }
4598
4599 /* Result */
4600 return (okay);
4601 }
4602
4603
4604 /*
4605 * Place a monster (of the specified "type") near the given
4606 * location. Return TRUE iff a monster was actually summoned.
4607 *
4608 * We will attempt to place the monster up to 10 times before giving up.
4609 *
4610 * Note: SUMMON_UNIQUE, SUMMON_HI_UNIQUE and SUMMON_NAZGUL will summon Uniques
4611 * Note: SUMMON_HI_UNDEAD, SUMMON_HI_DRAGON and SUMMON_HI_MONSTER(S) may summon
4612 * Unique's (depends on EXPLICITE_UNIQUE_SUMMONING - an exception is that
4613 * SUMMON_HI_UNDEAD may still summon Nazgul!)
4614 * Note: None of the other summon codes will ever summon Unique's.
4615 *
4616 * This function has been changed. We now take the "monster level"
4617 * of the summoning monster as a parameter, and use that, along with
4618 * the current dungeon level, to help determine the level of the
4619 * desired monster. Note that this is an upper bound, and also
4620 * tends to "prefer" monsters of that level. Currently, we use
4621 * the average of the dungeon and monster levels, and then add
4622 * five to allow slight increases in monster power.
4623 *
4624 * Note that we use the new "monster allocation table" creation code
4625 * to restrict the "get_mon_num()" function to the set of "legal"
4626 * monsters, making this function much faster and more reliable.
4627 *
4628 * Note that this function may not succeed, though this is very rare.
4629 */
4630 bool summon_specific(struct worldpos *wpos, int y1, int x1, int lev, int s_clone, int type, int allow_sidekicks, int clone_summoning) {
4631 int i, x, y, r_idx;
4632 dun_level *l_ptr = getfloor(wpos);
4633 cave_type **zcave;
4634 if(!(zcave = getcave(wpos))) return(FALSE);
4635
4636 /* Look for a location */
4637 for (i = 0; i < 20; ++i) {
4638 /* Pick a distance */
4639 int d = (i / 15) + 1;
4640
4641 /* Pick a location */
4642 scatter(wpos, &y, &x, y1, x1, d, 0);
4643
4644 /* Require "empty" floor grid */
4645 /* Changed for summoning on mountains */
4646 if (!cave_empty_bold(zcave, y, x)) continue;
4647 /* Hack -- no summon on glyph of warding */
4648 if (zcave[y][x].feat == FEAT_GLYPH) continue;
4649 if (zcave[y][x].feat == FEAT_RUNE) continue;
4650
4651 /* Okay */
4652 break;
4653 }
4654
4655 /* Failure */
4656 if (i == 20) return (FALSE);
4657
4658
4659 /* Save the "summon" type */
4660 summon_specific_type = type;
4661
4662
4663 /* Require "okay" monsters */
4664 get_mon_num_hook = summon_specific_okay;
4665
4666 /* Prepare allocation table */
4667 get_mon_num_prep(0, l_ptr ? l_ptr->uniques_killed : NULL);
4668
4669
4670 /* Pick a monster, using the level calculation */
4671 /* XXX: Exception for Morgoth (so that he won't summon townies)
4672 * This fix presumes Morgie and Morgie only has level 100 */
4673
4674 for (i = 0; i < 10; i++) { /* try a couple of times */
4675 #if 0 /* incorporated it directly into summon_specific_type, as it should be */
4676 /* Hack for RF0_S_HI_ flags */
4677 if (type == SUMMON_HI_MONSTER || type == SUMMON_HI_UNIQUE) {
4678 /* Ok, now let them summon what they can */
4679 r_idx = get_mon_num(100 + 5, 100);
4680 if (r_info[r_idx].level < 60) {
4681 r_idx = 0; /* failure - see below */
4682 continue;
4683 }
4684 } else {
4685 /* Ok, now let them summon what they can */
4686 r_idx = get_mon_num((getlevel(wpos) + lev) / 2 + 5, (getlevel(wpos) + lev) / 2);
4687 }
4688 #else
4689 /* Ok, now let them summon what they can */
4690 r_idx = get_mon_num((getlevel(wpos) + lev) / 2 + 5, (getlevel(wpos) + lev) / 2);
4691 #endif
4692 break;
4693 }
4694
4695 /* Don't allow uniques if escorts/friends (sidekicks) weren't allowed */
4696 if (!allow_sidekicks && (r_info[r_idx].flags1 & RF1_UNIQUE)) return (FALSE);
4697
4698 /* Remove restriction */
4699 get_mon_num_hook = dungeon_aux;
4700
4701 /* Handle failure */
4702 if (!r_idx) return (FALSE);
4703
4704 /* Attempt to place the monster (awake, allow groups) */
4705 if (place_monster_aux(wpos, y, x, r_idx, FALSE, allow_sidekicks ? TRUE : FALSE, s_clone, clone_summoning) != 0) return (FALSE);
4706
4707 /* Success */
4708 return (TRUE);
4709 }
4710
4711 /* summon a specific race near this location */
4712 /* summon until we can't find a location or we have summoned size */
4713 bool summon_specific_race(struct worldpos *wpos, int y1, int x1, int r_idx, int s_clone, unsigned char size) {
4714 int c, i, x, y;
4715 cave_type **zcave;
4716 if (!(zcave = getcave(wpos))) return(FALSE);
4717
4718 /* Handle failure */
4719 if (!r_idx) return (FALSE);
4720
4721 /* for each monster we are summoning */
4722 for (c = 0; c < size; c++) {
4723 /* Look for a location */
4724 for (i = 0; i < 200; ++i) {
4725 /* Pick a distance */
4726 int d = (i / 15) + 1;
4727
4728 /* Pick a location */
4729 scatter(wpos, &y, &x, y1, x1, d, 0);
4730
4731 /* Require "empty" floor grid */
4732 if (!cave_empty_bold(zcave, y, x)) continue;
4733
4734 /* Hack -- no summon on glyph of warding */
4735 if (zcave[y][x].feat == FEAT_GLYPH) continue;
4736 if (zcave[y][x].feat == FEAT_RUNE) continue;
4737
4738 /* Okay */
4739 break;
4740 }
4741
4742 /* Failure */
4743 if (i == 20) return (FALSE);
4744
4745 /* Attempt to place the monster (awake, don't allow groups) */
4746 if (place_monster_aux(wpos, y, x, r_idx, FALSE, FALSE,
4747 s_clone == 101 ? 100 : s_clone, s_clone == 101 ? 1000 : 0) != 0)
4748 return (FALSE);
4749
4750 }
4751
4752 /* Success */
4753 return (TRUE);
4754 }
4755
4756
4757 /* summon a specific race at a random location */
4758 bool summon_specific_race_somewhere(struct worldpos *wpos, int r_idx, int s_clone, unsigned char size) {
4759 int y, x;
4760 int tries = 0;
4761
4762 cave_type **zcave;
4763 if (!(zcave = getcave(wpos))) return(FALSE);
4764
4765 /* Find a legal, distant, unoccupied, space */
4766 while (tries < 50)
4767 {
4768 /* Increase the counter */
4769 tries++;
4770
4771 /* Pick a location */
4772 y = rand_int(getlevel(wpos) ? MAX_HGT : MAX_HGT);
4773 x = rand_int(getlevel(wpos) ? MAX_WID : MAX_WID);
4774
4775 /* Require "naked" floor grid */
4776 if (!cave_naked_bold(zcave, y, x)) continue;
4777
4778
4779 /* Abort */
4780 if (tries >= 50)
4781 return (FALSE);
4782
4783 /* We have a valid location */
4784 break;
4785 }
4786
4787 /* Attempt to place the monster */
4788 if (summon_specific_race(wpos, y, x, r_idx, s_clone, size)) return TRUE;
4789 return (FALSE);
4790 }
4791
4792 /* summon a single monster in every detail in a random location */
4793 int summon_detailed_one_somewhere(struct worldpos *wpos, int r_idx, int ego, bool slp, int s_clone) {
4794 int y, x;
4795 int tries = 0;
4796
4797 cave_type **zcave;
4798 if (!(zcave = getcave(wpos))) return(FALSE);
4799
4800 /* Find a legal, distant, unoccupied, space */
4801 while (tries < 50) {
4802 /* Increase the counter */
4803 tries++;
4804
4805 /* Pick a location */
4806 y = rand_int(getlevel(wpos) ? MAX_HGT : MAX_HGT);
4807 x = rand_int(getlevel(wpos) ? MAX_WID : MAX_WID);
4808
4809 /* Require "naked" floor grid */
4810 if (!cave_naked_bold(zcave, y, x)) continue;
4811
4812
4813 /* these two possibly superfluous? */
4814 /* Require "empty" floor grid */
4815 if (!cave_empty_bold(zcave, y, x)) continue;
4816 /* Hack -- no summon on glyph of warding */
4817 if (zcave[y][x].feat == FEAT_GLYPH) continue;
4818 if (zcave[y][x].feat == FEAT_RUNE) continue;
4819
4820
4821 /* Abort */
4822 if (tries >= 50)
4823 return (FALSE);
4824
4825 /* We have a valid location */
4826 break;
4827 }
4828
4829 if (place_monster_one(wpos, y, x, r_idx, ego, FALSE, slp, s_clone == 101 ? 100 : s_clone, s_clone == 101 ? 1000 : 0) != 0)
4830 return (FALSE);
4831
4832 /* Success */
4833 return (zcave[y][x].m_idx);
4834 }
4835
4836
4837
4838
4839
4840 /*
4841 * Let the given monster attempt to reproduce.
4842 *
4843 * Note that "reproduction" REQUIRES empty space.
4844 */
4845 bool multiply_monster(int m_idx) {
4846 monster_type *m_ptr = &m_list[m_idx];
4847 monster_race *r_ptr = race_inf(m_ptr);
4848 int i, y, x;
4849
4850 bool result = FALSE;
4851 struct worldpos *wpos = &m_ptr->wpos;
4852 cave_type **zcave;
4853 if (!(zcave = getcave(wpos))) return(FALSE);
4854
4855 if (m_ptr->clone > 90) return(FALSE);
4856
4857 /* NO UNIQUES */
4858 if (r_ptr->flags1 & RF1_UNIQUE) return FALSE;
4859 /* Not in town -_- */
4860 if (istown(wpos)) return FALSE;
4861
4862 /* Try up to 18 times */
4863 for (i = 0; i < 18; i++) {
4864 int d = 1;
4865
4866 /* Pick a location */
4867 scatter(&m_ptr->wpos, &y, &x, m_ptr->fy, m_ptr->fx, d, 0);
4868 /* Require an "empty" floor grid */
4869 if (!cave_empty_bold(zcave, y, x)) continue;
4870 result = place_monster_one(&m_ptr->wpos, y, x, m_ptr->r_idx,
4871 (m_ptr->ego && magik(CLONE_EGO_CHANCE)) ? m_ptr->ego :
4872 pick_ego_monster(m_ptr->r_idx, getlevel(&m_ptr->wpos)),
4873 0, FALSE, m_ptr->clone + 10, m_ptr->clone_summoning + 1) == 0;
4874 /* Done */
4875 break;
4876 }
4877
4878 /* Result */
4879 return (result);
4880 }
4881
4882
4883
4884 /*
4885 * Dump a message describing a monster's reaction to damage
4886 *
4887 * Technically should attempt to treat "Beholder"'s as jelly's
4888 */
4889 void message_pain(int Ind, int m_idx, int dam) {
4890 long oldhp, newhp, tmp;
4891 int percentage;
4892
4893 monster_type *m_ptr = &m_list[m_idx];
4894 monster_race *r_ptr = race_inf(m_ptr);
4895
4896 char m_name[MNAME_LEN];
4897
4898 char uniq = 'w';
4899 if ((r_ptr->flags1 & RF1_UNIQUE) &&
4900 Players[Ind]->r_killed[m_ptr->r_idx] == 1) {
4901 uniq = 'D';
4902 if (Players[Ind]->warn_unique_credit) Send_beep(Ind);
4903 }
4904
4905 /* hack: no message at all for invincible questors because it looks ugly */
4906 if (m_ptr->questor && (m_ptr->questor_invincible || (r_ptr->flags7 & RF7_NO_DEATH) || !m_ptr->questor_hostile)) return;
4907
4908 /* Get the monster name */
4909 monster_desc(Ind, m_name, m_idx, 0);
4910
4911
4912 /* Target Dummy */
4913 if (m_ptr->r_idx == RI_TARGET_DUMMY1 || m_ptr->r_idx == RI_TARGET_DUMMY2 ||
4914 m_ptr->r_idx == RI_TARGET_DUMMYA1 || m_ptr->r_idx == RI_TARGET_DUMMYA2) {
4915 msg_format(Ind, "%^s reels from \377g%d \377wdamage.", m_name, dam);
4916 //// msg_format_near(Ind, "%^s reels from \377g%d \377wdamage.", m_name, dam);
4917 //spammy msg_format_near_site(m_ptr->fy, m_ptr->fx, &m_ptr->wpos, Ind, TRUE, "%^s reels from \377g%d \377wdamage.", m_name, dam);
4918
4919 /* Hack: Reduce snow on it during winter season :) */
4920 m_ptr->extra -= 7;
4921 if (m_ptr->extra < 0) m_ptr->extra = 0;
4922 if ((m_ptr->r_idx == RI_TARGET_DUMMY2) && (m_ptr->extra < 30)) {
4923 m_ptr->r_idx = RI_TARGET_DUMMY1;
4924 everyone_lite_spot(&m_ptr->wpos, m_ptr->fy, m_ptr->fx);
4925 }
4926 if ((m_ptr->r_idx == RI_TARGET_DUMMYA2) && (m_ptr->extra < 30)) {
4927 m_ptr->r_idx = RI_TARGET_DUMMYA1;
4928 everyone_lite_spot(&m_ptr->wpos, m_ptr->fy, m_ptr->fx);
4929 }
4930 return;
4931 /* some monsters don't react at all */
4932 } else if (r_ptr->flags7 & RF7_NEVER_ACT) {
4933 if (r_ptr->flags1 & RF1_UNIQUE)
4934 msg_format(Ind, "\377%c%^s remains unmoving and takes \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
4935 else
4936 msg_format(Ind, "%^s remains unmoving and takes \377g%d \377wdamage.", m_name, dam);
4937 return;
4938 }
4939
4940
4941 /* Notice non-damage */
4942 if (dam == 0) {
4943 msg_format(Ind, "%^s is unharmed.", m_name);
4944 return;
4945 }
4946
4947 /* Note -- subtle fix -CFT */
4948 newhp = (long)(m_ptr->hp);
4949 oldhp = newhp + (long)(dam);
4950 tmp = (newhp * 100L) / oldhp;
4951 percentage = (int)(tmp);
4952
4953 /* DEG Modified to give damage information */
4954 /* Jelly's, Mold's, Vortex's, Quthl's */
4955 if (strchr("jmvQ", r_ptr->d_char)) {
4956 if (r_ptr->flags1 & RF1_UNIQUE) {
4957 if (percentage > 95)
4958 msg_format(Ind, "\377%c%^s barely notices the \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
4959 else if (percentage > 75)
4960 msg_format(Ind, "\377%c%^s flinches from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
4961 else if (percentage > 50)
4962 msg_format(Ind, "\377%c%^s squelches from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
4963 else if (percentage > 35)
4964 msg_format(Ind, "\377%c%^s quivers in pain from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
4965 else if (percentage > 20)
4966 msg_format(Ind, "\377%c%^s writhes about from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
4967 else if (percentage > 10)
4968 msg_format(Ind, "\377%c%^s writhes in agony from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
4969 else
4970 msg_format(Ind, "\377%c%^s jerks limply from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
4971 } else {
4972 if (percentage > 95)
4973 msg_format(Ind, "%^s barely notices the \377g%d \377wdamage.", m_name, dam);
4974 else if (percentage > 75)
4975 msg_format(Ind, "%^s flinches from \377g%d \377wdamage.", m_name, dam);
4976 else if (percentage > 50)
4977 msg_format(Ind, "%^s squelches from \377g%d \377wdamage.", m_name, dam);
4978 else if (percentage > 35)
4979 msg_format(Ind, "%^s quivers in pain from \377g%d \377wdamage.", m_name, dam);
4980 else if (percentage > 20)
4981 msg_format(Ind, "%^s writhes about from \377g%d \377wdamage.", m_name, dam);
4982 else if (percentage > 10)
4983 msg_format(Ind, "%^s writhes in agony from \377g%d \377wdamage.", m_name, dam);
4984 else
4985 msg_format(Ind, "%^s jerks limply from \377g%d \377wdamage.", m_name, dam);
4986 }
4987 }
4988
4989 /* Dogs and Hounds */
4990 else if (strchr("CZ", r_ptr->d_char)) {
4991 if (r_ptr->flags1 & RF1_UNIQUE) {
4992 if (percentage > 95)
4993 msg_format(Ind, "\377%c%^s shrugs off the attack of \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
4994 else if (percentage > 75)
4995 msg_format(Ind, "\377%c%^s snarls with pain from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
4996 else if (percentage > 50)
4997 msg_format(Ind, "\377%c%^s yelps in pain from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
4998 else if (percentage > 35)
4999 msg_format(Ind, "\377%c%^s howls in pain from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
5000 else if (percentage > 20)
5001 msg_format(Ind, "\377%c%^s howls in agony from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
5002 else if (percentage > 10)
5003 msg_format(Ind, "\377%c%^s writhes in agony from \377e%d \377%cdamage.", uniq, m_name,dam, uniq);
5004 else
5005 msg_format(Ind, "\377%c%^s yelps feebly from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
5006 } else {
5007 if (percentage > 95)
5008 msg_format(Ind, "%^s shrugs off the attack of \377g%d \377wdamage.", m_name, dam);
5009 else if (percentage > 75)
5010 msg_format(Ind, "%^s snarls with pain from \377g%d \377wdamage.", m_name, dam);
5011 else if (percentage > 50)
5012 msg_format(Ind, "%^s yelps in pain from \377g%d \377wdamage.", m_name, dam);
5013 else if (percentage > 35)
5014 msg_format(Ind, "%^s howls in pain from \377g%d \377wdamage.", m_name, dam);
5015 else if (percentage > 20)
5016 msg_format(Ind, "%^s howls in agony from \377g%d \377wdamage.", m_name, dam);
5017 else if (percentage > 10)
5018 msg_format(Ind, "%^s writhes in agony from \377g%d \377wdamage.", m_name,dam);
5019 else
5020 msg_format(Ind, "%^s yelps feebly from \377g%d \377wdamage.", m_name, dam);
5021 }
5022 }
5023
5024 /* One type of monsters (ignore,squeal,shriek) */
5025 else if (strchr("FIKMRSXabclqrst", r_ptr->d_char)) {
5026 if (r_ptr->flags1 & RF1_UNIQUE) {
5027 if (percentage > 95)
5028 msg_format(Ind, "\377%c%^s ignores the attack of \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
5029 else if (percentage > 75)
5030 msg_format(Ind, "\377%c%^s grunts with pain from \377e%d \377%cdamage.", uniq, m_name ,dam, uniq);
5031 else if (percentage > 50)
5032 msg_format(Ind, "\377%c%^s squeals in pain from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
5033 else if (percentage > 35)
5034 msg_format(Ind, "\377%c%^s shrieks in pain from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
5035 else if (percentage > 20)
5036 msg_format(Ind, "\377%c%^s shrieks in agony from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
5037 else if (percentage > 10)
5038 msg_format(Ind, "\377%c%^s writhes in agony from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
5039 else
5040 msg_format(Ind, "\377%c%^s cries out feebly from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
5041 } else {
5042 if (percentage > 95)
5043 msg_format(Ind, "%^s ignores the attack of \377g%d \377wdamage.", m_name, dam);
5044 else if (percentage > 75)
5045 msg_format(Ind, "%^s grunts with pain from \377g%d \377wdamage.", m_name ,dam);
5046 else if (percentage > 50)
5047 msg_format(Ind, "%^s squeals in pain from \377g%d \377wdamage.", m_name, dam);
5048 else if (percentage > 35)
5049 msg_format(Ind, "%^s shrieks in pain from \377g%d \377wdamage.", m_name, dam);
5050 else if (percentage > 20)
5051 msg_format(Ind, "%^s shrieks in agony from \377g%d \377wdamage.", m_name, dam);
5052 else if (percentage > 10)
5053 msg_format(Ind, "%^s writhes in agony from \377g%d \377wdamage.", m_name, dam);
5054 else
5055 msg_format(Ind, "%^s cries out feebly from \377g%d \377wdamage.", m_name, dam);
5056 }
5057 }
5058
5059 /* Another type of monsters (shrug,cry,scream) */
5060 else if (r_ptr->flags1 & RF1_UNIQUE) {
5061 if (percentage > 95)
5062 msg_format(Ind, "\377%c%^s shrugs off the attack of \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
5063 else if (percentage > 75)
5064 msg_format(Ind, "\377%c%^s grunts with pain from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
5065 else if (percentage > 50)
5066 msg_format(Ind, "\377%c%^s cries out in pain from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
5067 else if (percentage > 35)
5068 msg_format(Ind, "\377%c%^s screams in pain from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
5069 else if (percentage > 20)
5070 msg_format(Ind, "\377%c%^s screams in agony from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
5071 else if (percentage > 10)
5072 msg_format(Ind, "\377%c%^s writhes in agony from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
5073 else
5074 msg_format(Ind, "\377%c%^s cries out feebly from \377e%d \377%cdamage.", uniq, m_name, dam, uniq);
5075 } else {
5076 if (percentage > 95)
5077 msg_format(Ind, "%^s shrugs off the attack of \377g%d \377wdamage.", m_name, dam);
5078 else if (percentage > 75)
5079 msg_format(Ind, "%^s grunts with pain from \377g%d \377wdamage.", m_name, dam);
5080 else if (percentage > 50)
5081 msg_format(Ind, "%^s cries out in pain from \377g%d \377wdamage.", m_name, dam);
5082 else if (percentage > 35)
5083 msg_format(Ind, "%^s screams in pain from \377g%d \377wdamage.", m_name, dam);
5084 else if (percentage > 20)
5085 msg_format(Ind, "%^s screams in agony from \377g%d \377wdamage.", m_name, dam);
5086 else if (percentage > 10)
5087 msg_format(Ind, "%^s writhes in agony from \377g%d \377wdamage.", m_name, dam);
5088 else
5089 msg_format(Ind, "%^s cries out feebly from \377g%d \377wdamage.", m_name, dam);
5090 }
5091 }
5092
5093
5094
5095 /*
5096 * Learn about an "observed" resistance.
5097 */
5098 void update_smart_learn(int m_idx, int what)
5099 {
5100
5101 #ifdef DRS_SMART_OPTIONS
5102
5103 monster_type *m_ptr = &m_list[m_idx];
5104
5105 monster_race *r_ptr = race_inf(m_ptr);
5106
5107
5108 /* Not allowed to learn */
5109 if (!smart_learn) return;
5110
5111 /* Too stupid to learn anything */
5112 if (r_ptr->flags2 & RF2_STUPID) return;
5113
5114 /* Not intelligent, only learn sometimes */
5115 if (!(r_ptr->flags2 & RF2_SMART) && (rand_int(100) < 50)) return;
5116
5117
5118 /* XXX XXX XXX */
5119
5120 /* Analyze the knowledge */
5121 switch (what)
5122 {
5123 case DRS_ACID:
5124 if (p_ptr->resist_acid) m_ptr->smart |= SM_RES_ACID;
5125 if (p_ptr->oppose_acid) m_ptr->smart |= SM_OPP_ACID;
5126 if (p_ptr->immune_acid) m_ptr->smart |= SM_IMM_ACID;
5127 break;
5128
5129 case DRS_ELEC:
5130 if (p_ptr->resist_elec) m_ptr->smart |= SM_RES_ELEC;
5131 if (p_ptr->oppose_elec) m_ptr->smart |= SM_OPP_ELEC;
5132 if (p_ptr->immune_elec) m_ptr->smart |= SM_IMM_ELEC;
5133 break;
5134
5135 case DRS_FIRE:
5136 if (p_ptr->resist_fire) m_ptr->smart |= SM_RES_FIRE;
5137 if (p_ptr->oppose_fire) m_ptr->smart |= SM_OPP_FIRE;
5138 if (p_ptr->immune_fire) m_ptr->smart |= SM_IMM_FIRE;
5139 break;
5140
5141 case DRS_COLD:
5142 if (p_ptr->resist_cold) m_ptr->smart |= SM_RES_COLD;
5143 if (p_ptr->oppose_cold) m_ptr->smart |= SM_OPP_COLD;
5144 if (p_ptr->immune_cold) m_ptr->smart |= SM_IMM_COLD;
5145 break;
5146
5147 case DRS_POIS:
5148 if (p_ptr->resist_pois) m_ptr->smart |= SM_RES_POIS;
5149 if (p_ptr->oppose_pois) m_ptr->smart |= SM_OPP_POIS;
5150 break;
5151
5152
5153 case DRS_NETH:
5154 if (p_ptr->resist_neth) m_ptr->smart |= SM_RES_NETH;
5155 if (p_ptr->immune_neth) m_ptr->smart |= SM_RES_NETH;
5156 break;
5157
5158 case DRS_LITE:
5159 if (p_ptr->resist_lite) m_ptr->smart |= SM_RES_LITE;
5160 break;
5161
5162 case DRS_DARK:
5163 if (p_ptr->resist_dark) m_ptr->smart |= SM_RES_DARK;
5164 break;
5165
5166 case DRS_FEAR:
5167 if (p_ptr->resist_fear) m_ptr->smart |= SM_RES_FEAR;
5168 break;
5169
5170 case DRS_CONF:
5171 if (p_ptr->resist_conf) m_ptr->smart |= SM_RES_CONF;
5172 break;
5173
5174 case DRS_CHAOS:
5175 if (p_ptr->resist_chaos) m_ptr->smart |= SM_RES_CHAOS;
5176 break;
5177
5178 case DRS_DISEN:
5179 if (p_ptr->resist_disen) m_ptr->smart |= SM_RES_DISEN;
5180 break;
5181
5182 case DRS_BLIND:
5183 if (p_ptr->resist_blind) m_ptr->smart |= SM_RES_BLIND;
5184 break;
5185
5186 case DRS_NEXUS:
5187 if (p_ptr->resist_nexus) m_ptr->smart |= SM_RES_NEXUS;
5188 break;
5189
5190 case DRS_SOUND:
5191 if (p_ptr->resist_sound) m_ptr->smart |= SM_RES_SOUND;
5192 break;
5193
5194 case DRS_SHARD:
5195 if (p_ptr->resist_shard) m_ptr->smart |= SM_RES_SHARD;
5196 break;
5197
5198
5199 case DRS_FREE:
5200 if (p_ptr->free_act) m_ptr->smart |= SM_IMM_FREE;
5201 break;
5202
5203 case DRS_MANA:
5204 if (!p_ptr->msp) m_ptr->smart |= SM_IMM_MANA;
5205 break;
5206 }
5207
5208 #endif /* DRS_SMART_OPTIONS */
5209
5210 }
5211
5212 /*
5213 * Set the "m_idx" fields in the cave array to correspond
5214 * to the objects in the "m_list".
5215 */
5216 void setup_monsters(void) {
5217 int i;
5218 monster_type *r_ptr;
5219 cave_type **zcave;
5220
5221 for (i = 0; i < m_max; i++) {
5222 r_ptr = &m_list[i];
5223 /* setup the cave m_idx if the level has been
5224 * allocated.
5225 */
5226 if ((zcave = getcave(&r_ptr->wpos)))
5227 zcave[r_ptr->fy][r_ptr->fx].m_idx = i;
5228 }
5229 }
5230
5231 /* Takes a monster name and returns an index, or 0 if no such monster
5232 * was found.
5233 */
5234 int race_index(char * name) {
5235 int i;
5236
5237 /* for each monster race */
5238 for (i = 1; i < MAX_R_IDX - 1; i++) {
5239 if (r_info[i].name) {
5240 if (!strcmp(&r_name[r_info[i].name],name)) return i;
5241 }
5242 }
5243 return 0;
5244 }
5245
5246 monster_race* r_info_get(monster_type *m_ptr) {
5247 /* golem or new questor? */
5248 if (m_ptr->special || m_ptr->questor) return (m_ptr->r_ptr);
5249 #ifdef RANDUNIS
5250 else if (m_ptr->ego) return (race_info_idx((m_ptr)->r_idx, (m_ptr)->ego, (m_ptr)->name3));
5251 else return (&r_info[m_ptr->r_idx]);
5252 #else
5253 else return (&r_info[m_ptr->r_idx]);
5254 #endif // RANDUNIS
5255 }
5256
5257 cptr r_name_get(monster_type *m_ptr) {
5258 static char buf[100];
5259
5260 if (m_ptr->questor) {
5261 if (q_info[m_ptr->quest].defined && q_info[m_ptr->quest].questors > m_ptr->questor_idx) {
5262 if (strlen(q_info[m_ptr->quest].questor[m_ptr->questor_idx].name)) {
5263 snprintf(buf, sizeof(buf), "%s", q_info[m_ptr->quest].questor[m_ptr->questor_idx].name);
5264 return buf;
5265 } else return (r_name + m_ptr->r_ptr->name);
5266 } else {
5267 s_printf("QUESTOR DEPRECATED (r_name_get)\n");
5268 return (r_name + m_ptr->r_ptr->name);
5269 }
5270 } else if (m_ptr->special) {
5271 cptr p = (m_ptr->owner) ? lookup_player_name(m_ptr->owner) : "**INTERNAL BUG**";
5272 if (p == NULL) p = "**INTERNAL BUG**";
5273 switch (m_ptr->r_idx - 1) {
5274 case SV_GOLEM_WOOD:
5275 snprintf(buf, sizeof(buf), "%s's Wood Golem", p);
5276 break;
5277 case SV_GOLEM_COPPER:
5278 snprintf(buf, sizeof(buf), "%s's Copper Golem", p);
5279 break;
5280 case SV_GOLEM_IRON:
5281 snprintf(buf, sizeof(buf), "%s's Iron Golem", p);
5282 break;
5283 case SV_GOLEM_ALUM:
5284 snprintf(buf, sizeof(buf), "%s's Aluminium Golem", p);
5285 break;
5286 case SV_GOLEM_SILVER:
5287 snprintf(buf, sizeof(buf), "%s's Silver Golem", p);
5288 break;
5289 case SV_GOLEM_GOLD:
5290 snprintf(buf, sizeof(buf), "%s's Gold Golem", p);
5291 break;
5292 case SV_GOLEM_MITHRIL:
5293 snprintf(buf, sizeof(buf), "%s's Mithril Golem", p);
5294 break;
5295 case SV_GOLEM_ADAM:
5296 snprintf(buf, sizeof(buf), "%s's Adamantite Golem", p);
5297 break;
5298 }
5299 return (buf);
5300 }
5301 #ifdef RANDUNIS
5302 else if (m_ptr->ego) {
5303 if (re_info[m_ptr->ego].before) {
5304 snprintf(buf, sizeof(buf), "%s %s", re_name + re_info[m_ptr->ego].name,
5305 r_name + r_info[m_ptr->r_idx].name);
5306 } else {
5307 snprintf(buf, sizeof(buf), "%s %s", r_name + r_info[m_ptr->r_idx].name,
5308 re_name + re_info[m_ptr->ego].name);
5309 }
5310 return (buf);
5311 }
5312 #endif
5313 else return (r_name + r_info[m_ptr->r_idx].name);
5314 }
5315
5316 #ifdef RANDUNIS
5317 /* Will add, sub, .. */
5318 static s32b modify_aux(s32b a, s32b b, char mod)
5319 {
5320 switch (mod)
5321 {
5322 case MEGO_ADD:
5323 return (a + b);
5324 break;
5325 case MEGO_SUB:
5326 return (a - b);
5327 break;
5328 case MEGO_FIX:
5329 return (b);
5330 break;
5331 case MEGO_PRC:
5332 return (a * b / 100);
5333 break;
5334 default:
5335 s_printf("WARNING, unmatching MEGO(%d).\n", mod);
5336 return (0);
5337 }
5338 }
5339
5340 #define MODIFY_AUX(o, n) ((o) = modify_aux((o), (n) >> 2, (n) & 3))
5341 #define MODIFY(o, n, min) MODIFY_AUX(o, n); (o) = ((o) < (min))?(min):(o)
5342
5343 /* Is this ego ok for this monster ? */
5344 bool mego_ok(int r_idx, int ego)
5345 {
5346 monster_ego *re_ptr = &re_info[ego];
5347 monster_race *r_ptr = &r_info[r_idx];
5348 bool ok = FALSE;
5349 int i;
5350
5351 /* missing number */
5352 if (!re_ptr->name) return FALSE;
5353
5354 /* needed flags */
5355 if (re_ptr->flags1 && ((re_ptr->flags1 & r_ptr->flags1) != re_ptr->flags1)) return FALSE;
5356 if (re_ptr->flags2 && ((re_ptr->flags2 & r_ptr->flags2) != re_ptr->flags2)) return FALSE;
5357 if (re_ptr->flags3 && ((re_ptr->flags3 & r_ptr->flags3) != re_ptr->flags3)) return FALSE;
5358 #if 1
5359 if (re_ptr->flags7 && ((re_ptr->flags7 & r_ptr->flags7) != re_ptr->flags7)) return FALSE;
5360 if (re_ptr->flags8 && ((re_ptr->flags8 & r_ptr->flags8) != re_ptr->flags8)) return FALSE;
5361 if (re_ptr->flags9 && ((re_ptr->flags9 & r_ptr->flags9) != re_ptr->flags9)) return FALSE;
5362 #endif
5363
5364 /* unwanted flags */
5365 if (re_ptr->hflags1 && (re_ptr->hflags1 & r_ptr->flags1)) return FALSE;
5366 if (re_ptr->hflags2 && (re_ptr->hflags2 & r_ptr->flags2)) return FALSE;
5367 if (re_ptr->hflags3 && (re_ptr->hflags3 & r_ptr->flags3)) return FALSE;
5368 #if 1
5369 if (re_ptr->hflags7 && (re_ptr->hflags7 & r_ptr->flags7)) return FALSE;
5370 if (re_ptr->hflags8 && (re_ptr->hflags8 & r_ptr->flags8)) return FALSE;
5371 if (re_ptr->hflags9 && (re_ptr->hflags9 & r_ptr->flags9)) return FALSE;
5372 #endif
5373
5374 /* Need good race -- IF races are specified */
5375 if (re_ptr->r_char[0])
5376 {
5377 for (i = 0; i < 10; i++)
5378 {
5379 if (r_ptr->d_char == re_ptr->r_char[i]) ok = TRUE;
5380 }
5381 if (!ok) return FALSE;
5382 }
5383 if (re_ptr->nr_char[0])
5384 {
5385 for (i = 0; i < 10; i++)
5386 {
5387 if (r_ptr->d_char == re_ptr->nr_char[i]) return (FALSE);
5388 }
5389 }
5390
5391 /* Passed all tests ? */
5392 return TRUE;
5393 }
5394
5395 /* Choose an ego type */
5396 /* 'Level' is a transitional index for dun_depth. - Jir -
5397 */
5398 int pick_ego_monster(int r_idx, int Level)
5399 {
5400 /* Assume no ego */
5401 int ego = 0, lvl;
5402 int tries = MAX_RE_IDX + 10;
5403 monster_ego *re_ptr;
5404
5405 /* No townspeople ego */
5406 if (!r_info[r_idx].level) return 0;
5407
5408 /* No Great Pumpkin ego (HALLOWEEN) */
5409 if (r_idx == RI_PUMPKIN1 || r_idx == RI_PUMPKIN2 || r_idx == RI_PUMPKIN3) return 0;
5410
5411 /* First are we allowed to find an ego */
5412 if (!magik(MEGO_CHANCE)) return 0;
5413
5414 /* Ego Uniques are NOT to be created */
5415 if ((r_info[r_idx].flags1 & RF1_UNIQUE)) return 0;
5416
5417 /* Lets look for one */
5418 while(tries--)
5419 {
5420 /* Pick one */
5421 ego = rand_range(1, MAX_RE_IDX - 1);
5422 re_ptr = &re_info[ego];
5423
5424 /* No hope so far */
5425 if (!mego_ok(r_idx, ego)) continue;
5426
5427 /* Not too much OoD */
5428 lvl = r_info[r_idx].level;
5429 MODIFY(lvl, re_ptr->level, 0);
5430 lvl -= ((Level / 2) + (rand_int(Level / 2)));
5431 if (lvl < 1) lvl = 1;
5432 if (rand_int(lvl)) continue;
5433 // if (rand_int(lvl * 2 - 1)) continue; /* less OoD */
5434
5435 /* Hack -- Depth monsters may NOT be created out of depth */
5436 if ((re_ptr->mflags1 & RF1_FORCE_DEPTH) && (lvl > 1)) {
5437 /* Cannot create */
5438 continue;
5439 }
5440
5441 /* Each ego types have a rarity */
5442 if (rand_int(re_ptr->rarity)) continue;
5443
5444 /* (Remove me) */
5445 #if DEBUG_LEVEL > 2
5446 s_printf("ego %d(%s)(%s) is generated.\n", ego, re_name + re_ptr->name, r_name + r_info[r_idx].name);
5447 #endif
5448
5449 /* We finanly got one ? GREAT */
5450 return ego;
5451 }
5452
5453 /* Found none ? so sad, well no ego for the time being */
5454 return 0;
5455 }
5456
5457 #if 0
5458 /* Pick a randuni (not implemented yet) */
5459 int pick_randuni(int r_idx, int Level)
5460 {
5461 /* Assume no ego */
5462 int ego = 0, lvl;
5463 int tries = max_re_idx + 10;
5464 monster_ego *re_ptr;
5465
5466 /* No townspeople ego */
5467 if (!r_info[r_idx].level) return 0;
5468
5469 /* First are we allowed to find an ego */
5470 if (!magik(MEGO_CHANCE)) return 0;
5471
5472
5473 /* Lets look for one */
5474 while(tries--)
5475 {
5476 /* Pick one */
5477 ego = rand_range(1, max_re_idx - 1);
5478 re_ptr = &re_info[ego];
5479
5480 /* No hope so far */
5481 if (!mego_ok(r_idx, ego)) continue;
5482
5483 /* Not too much OoD */
5484 lvl = r_info[r_idx].level;
5485 MODIFY(lvl, re_ptr->level, 0);
5486 lvl -= ((dlev / 2) + (rand_int(dlev / 2)));
5487 if (lvl < 1) lvl = 1;
5488 if (rand_int(lvl)) continue;
5489
5490 /* Each ego types have a rarity */
5491 if (rand_int(re_ptr->rarity)) continue;
5492
5493 /* We finanly got one ? GREAT */
5494 return ego;
5495 }
5496
5497 /* Found none ? so sad, well no ego for the time being */
5498 return 0;
5499 }
5500 #endif
5501
5502 /*
5503 * Return a (monster_race*) with the combinaison of the monster
5504 * proprieties, the ego type and randuni id.
5505 * (randuni parts are not done yet.. - Jir -)
5506 */
5507 static monster_race* race_info_idx(int r_idx, int ego, int randuni)
5508 {
5509 static monster_race race;
5510 monster_ego *re_ptr = &re_info[ego];
5511 monster_race *r_ptr = &r_info[r_idx], *nr_ptr = ∽̱
5512 int i;
5513
5514 /* No work needed */
5515 if (!ego) return r_ptr;
5516
5517 /* Copy the base monster */
5518 COPY(nr_ptr, r_ptr, monster_race);
5519
5520 /* Adjust the values */
5521 for (i = 0; i < 4; i++) {
5522 s32b j, k;
5523
5524 j = modify_aux(nr_ptr->blow[i].d_dice, re_ptr->blow[i].d_dice, re_ptr->blowm[i][0]);
5525 if (j < 0) j = 0;
5526 if (j > 255) j = 255;
5527 k = modify_aux(nr_ptr->blow[i].d_side, re_ptr->blow[i].d_side, re_ptr->blowm[i][1]);
5528 if (k < 0) k = 0;
5529 if (k > 255) k = 255;
5530
5531 nr_ptr->blow[i].d_dice = j;
5532 nr_ptr->blow[i].d_side = k;
5533
5534 if (re_ptr->blow[i].method) nr_ptr->blow[i].method = re_ptr->blow[i].method;
5535 if (re_ptr->blow[i].effect) nr_ptr->blow[i].effect = re_ptr->blow[i].effect;
5536 }
5537
5538 MODIFY(nr_ptr->hdice, re_ptr->hdice, 1);
5539 MODIFY(nr_ptr->hside, re_ptr->hside, 1);
5540
5541 MODIFY(nr_ptr->ac, re_ptr->ac, 0);
5542
5543 MODIFY(nr_ptr->sleep, re_ptr->sleep, 0);
5544
5545 MODIFY(nr_ptr->aaf, re_ptr->aaf, 1);
5546
5547 /* Hack - avoid to be back to 0 (consider using s16b) */
5548 i = nr_ptr->speed;
5549 MODIFY(i, re_ptr->speed, 50);
5550 MODIFY(nr_ptr->speed, re_ptr->speed, 50);
5551
5552 if (nr_ptr->speed < i) nr_ptr->speed = 255;
5553
5554 MODIFY(nr_ptr->mexp, re_ptr->mexp, 0);
5555
5556 // MODIFY(nr_ptr->weight, re_ptr->weight, 10);
5557
5558 nr_ptr->freq_innate = re_ptr->freq_innate;
5559 nr_ptr->freq_spell = re_ptr->freq_spell;
5560
5561 MODIFY(nr_ptr->level, re_ptr->level, 1);
5562
5563 /* Take off some flags */
5564 nr_ptr->flags1 &= ~(re_ptr->nflags1);
5565 nr_ptr->flags2 &= ~(re_ptr->nflags2);
5566 nr_ptr->flags3 &= ~(re_ptr->nflags3);
5567 nr_ptr->flags4 &= ~(re_ptr->nflags4);
5568 nr_ptr->flags5 &= ~(re_ptr->nflags5);
5569 nr_ptr->flags6 &= ~(re_ptr->nflags6);
5570 nr_ptr->flags7 &= ~(re_ptr->nflags7);
5571 nr_ptr->flags8 &= ~(re_ptr->nflags8);
5572 nr_ptr->flags9 &= ~(re_ptr->nflags9);
5573
5574 /* Add some flags */
5575 nr_ptr->flags1 |= re_ptr->mflags1;
5576 nr_ptr->flags2 |= re_ptr->mflags2;
5577 nr_ptr->flags3 |= re_ptr->mflags3;
5578 nr_ptr->flags4 |= re_ptr->mflags4;
5579 nr_ptr->flags5 |= re_ptr->mflags5;
5580 nr_ptr->flags6 |= re_ptr->mflags6;
5581 nr_ptr->flags7 |= re_ptr->mflags7;
5582 nr_ptr->flags8 |= re_ptr->mflags8;
5583 nr_ptr->flags9 |= re_ptr->mflags9;
5584
5585 /* Change the char/attr is needed */
5586 if (re_ptr->d_char != MEGO_CHAR_ANY)
5587 {
5588 nr_ptr->d_char = re_ptr->d_char;
5589 nr_ptr->x_char = re_ptr->d_char;
5590 }
5591 #ifndef M_EGO_NEW_FLICKER
5592 if (re_ptr->d_attr != MEGO_CHAR_ANY)
5593 {
5594 nr_ptr->d_attr = re_ptr->d_attr;
5595 nr_ptr->x_attr = re_ptr->d_attr;
5596 }
5597 #endif
5598
5599 /* And finanly return a pointer to a fully working monster race */
5600 return nr_ptr;
5601 }
5602
5603 #endif // RANDUNIS
5604
5605 #ifdef MONSTER_INVENTORY
5606 /*
5607 * Drop all items carried by a monster
5608 */
5609 void monster_drop_carried_objects(monster_type *m_ptr)
5610 {
5611 s16b this_o_idx, next_o_idx = 0;
5612 object_type forge;
5613 object_type *o_ptr;
5614 object_type *q_ptr;
5615
5616
5617 /* Drop objects being carried */
5618 for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
5619 {
5620 /* Acquire object */
5621 o_ptr = &o_list[this_o_idx];
5622
5623 /* Acquire next object */
5624 next_o_idx = o_ptr->next_o_idx;
5625
5626 /* Paranoia */
5627 o_ptr->held_m_idx = 0;
5628
5629 /* Get local object */
5630 q_ptr = &forge;
5631
5632 /* Copy the object */
5633 object_copy(q_ptr, o_ptr);
5634 q_ptr->next_o_idx = 0;
5635
5636 /* Delete the object */
5637 delete_object_idx(this_o_idx, FALSE);
5638
5639 /* the_sandman - Perhaps we can filter out the nothings here?
5640 */
5641 // char* tempbuf = (char*) malloc(sizeof(char)*80);
5642 // object_desc(Ind, tempbuf, o_ptr, 0, 0);
5643 // if (!strcmp(tempbuf, "(nothing)")) {
5644 /* Drop it */
5645 drop_near(q_ptr, -1, &m_ptr->wpos, m_ptr->fy, m_ptr->fx);
5646 // }
5647 // free(tempbuf);
5648 }
5649
5650 /* Forget objects */
5651 m_ptr->hold_o_idx = 0;
5652 }
5653
5654 void monster_carry(monster_type *m_ptr, int m_idx, object_type *q_ptr) {
5655 object_type *o_ptr;
5656
5657 /* Get new object */
5658 int o_idx = o_pop();
5659
5660 if (o_idx) {
5661 /* Get the item */
5662 o_ptr = &o_list[o_idx];
5663
5664 /* Structure copy */
5665 object_copy(o_ptr, q_ptr);
5666
5667 /* Build a stack */
5668 o_ptr->next_o_idx = m_ptr->hold_o_idx;
5669
5670 o_ptr->held_m_idx = m_idx;
5671 o_ptr->ix = 0;
5672 o_ptr->iy = 0;
5673
5674 m_ptr->hold_o_idx = o_idx;
5675 }
5676
5677 else {
5678 /* Hack -- Preserve artifacts */
5679 if (q_ptr->name1) handle_art_d(q_ptr->name1);
5680 questitem_d(q_ptr, q_ptr->number);
5681 }
5682 }
5683
5684 #endif // MONSTER_INVENTORY
5685
5686
5687 /* Already in wild.c */
5688 #define monster_dungeon(r_idx) dungeon_aux(r_idx)
5689
5690
5691 static bool monster_deep_water(int r_idx)
5692 {
5693 monster_race *r_ptr = &r_info[r_idx];
5694
5695 if (r_ptr->flags7 & RF7_AQUATIC)
5696 return TRUE;
5697 else
5698 return FALSE;
5699 }
5700
5701
5702 static bool monster_shallow_water(int r_idx)
5703 {
5704 monster_race *r_ptr = &r_info[r_idx];
5705
5706 if (r_ptr->flags2 & RF2_AURA_FIRE)
5707 return FALSE;
5708 else
5709 return TRUE;
5710 }
5711
5712
5713 static bool monster_lava(int r_idx)
5714 {
5715 monster_race *r_ptr = &r_info[r_idx];
5716
5717 if (((r_ptr->flags3 & RF3_IM_FIRE) ||
5718 (r_ptr->flags9 & RF9_RES_FIRE) ||
5719 (r_ptr->flags3 & RF3_RES_PLAS) ||
5720 (r_ptr->flags7 & RF7_CAN_FLY)) &&
5721 !(r_ptr->flags3 & RF3_AURA_COLD))
5722 return TRUE;
5723 else
5724 return FALSE;
5725 }
5726
5727
5728 static bool monster_ground(int r_idx)
5729 {
5730 monster_race *r_ptr = &r_info[r_idx];
5731
5732 if ((r_ptr->flags7 & RF7_AQUATIC) &&
5733 !(r_ptr->flags7 & RF7_CAN_FLY))
5734 return FALSE;
5735 else
5736 return TRUE;
5737 }
5738
5739
5740 /*
5741 * Check if monster can cross terrain
5742 * 'spawn' flag determines if monster also reasonably should be
5743 * generated on this kind of terrain. Added for is_door/is_stair
5744 * checks regarding aquatic monsters, otherwise we have them spawn
5745 * on doors/stairs, which is silly. - C. Blue
5746 * Added 'info' too, since aquatic monsters would seek out doors/stairs
5747 * and then get stuck on them if the surrounding floor wasnt watery.
5748 * Also note that fountains mustn't count as safe haven for aquatic monsters,
5749 * or fountain guards without ranged attacks might be pretty helpless.
5750 */
5751 bool monster_can_cross_terrain(byte feat, monster_race *r_ptr, bool spawn, u32b info) {
5752 /* Deep water */
5753 if (feat == FEAT_DEEP_WATER) {
5754 if ((r_ptr->flags7 & RF7_AQUATIC) ||
5755 (r_ptr->flags7 & RF7_CAN_FLY) ||
5756 (r_ptr->flags9 & RF9_IM_WATER) ||
5757 (r_ptr->flags7 & RF7_CAN_SWIM))
5758 return TRUE;
5759 else
5760 return FALSE;
5761 }
5762 /* Shallow water */
5763 else if (feat == FEAT_SHAL_WATER) {
5764 if ((r_ptr->flags2 & RF2_AURA_FIRE)
5765 && r_ptr->level < 25 /* no more Solar Blades stuck in shallow water o_o */
5766 /*(this level is actually only undercut by a) Jumping Fireball, b) Fire Spirit and c) Fire Vortex)*/
5767 )
5768 return FALSE;
5769 else
5770 return TRUE;
5771 }
5772 /* Aquatic monster */
5773 else if ((r_ptr->flags7 & RF7_AQUATIC) &&
5774 !(r_ptr->flags7 & RF7_CAN_FLY)) {
5775 /* MAY pass all sorts of doors, so they don't get stuck
5776 in water-filled rooms all the time, waiting to get shot - C. Blue */
5777 if (!spawn && is_always_passable(feat) && (info & CAVE_WATERY)) return TRUE;
5778 else return FALSE;
5779 }
5780 /* Lava */
5781 else if ((feat == FEAT_SHAL_LAVA) ||
5782 (feat == FEAT_DEEP_LAVA)) {
5783 if ((r_ptr->flags3 & RF3_IM_FIRE) ||
5784 (r_ptr->flags9 & RF9_RES_FIRE) ||
5785 (r_ptr->flags3 & RF3_RES_PLAS) ||
5786 (r_ptr->flags7 & RF7_CAN_FLY))
5787 return TRUE;
5788 else
5789 return FALSE;
5790 }
5791
5792 return TRUE;
5793 }
5794
5795
5796 void set_mon_num2_hook(int feat)
5797 {
5798 /* Set the monster list */
5799 switch (feat)
5800 {
5801 case FEAT_SHAL_WATER:
5802 get_mon_num2_hook = monster_shallow_water;
5803 break;
5804 case FEAT_DEEP_WATER:
5805 get_mon_num2_hook = monster_deep_water;
5806 break;
5807 case FEAT_DEEP_LAVA:
5808 case FEAT_SHAL_LAVA:
5809 get_mon_num2_hook = monster_lava;
5810 break;
5811 default:
5812 get_mon_num2_hook = monster_ground;
5813 break;
5814 }
5815 }
5816