Branch data Line data Source code
1 : : /* omega copyright (c) 1987,1988,1989 by Laurence Raphael Brothers */
2 : : /* mspec.c */
3 : : /* monster special functions */
4 : :
5 : : #include "glob.h"
6 : :
7 : :
8 : 0 : void m_sp_mp(pmt m)
9 : : {
10 [ # # ][ # # ]: 0 : if (m->attacked && (random_range(3) == 1)) {
11 : 0 : mprint("You feel cursed!");
12 : 0 : p_damage(10,UNSTOPPABLE,"a mendicant priest's curse");
13 : 0 : m_vanish(m);
14 : : }
15 [ # # ]: 0 : else if (! m_statusp(m,NEEDY)) {
16 : 0 : mprint("The mendicant priest makes a mystical gesture....");
17 : 0 : mprint("You feel impressed...");
18 : 0 : Player.alignment += 5;
19 [ # # ]: 0 : if (Player.alignment > 20)
20 : 0 : Player.hp = max(Player.hp,Player.maxhp);
21 : 0 : m_vanish(m);
22 : : }
23 : 0 : }
24 : :
25 : :
26 : 0 : void m_sp_ng(pmt m)
27 : : {
28 [ # # ]: 0 : if (distance(m->x,m->y,Player.x,Player.y) < 2)
29 [ # # ][ # # ]: 0 : if ((random_range(5) == 1) || (Player.status[VULNERABLE]>0)) {
30 : 0 : mprint("The night gaunt grabs you and carries you off!");
31 : 0 : mprint("Its leathery wings flap and flap, and it giggles insanely.");
32 : 0 : mprint("It tickles you cunningly to render you incapable of escape.");
33 : 0 : mprint("Finally, it deposits you in a strange place.");
34 : 0 : p_teleport(0);
35 : : }
36 : 0 : }
37 : :
38 : :
39 : :
40 : 0 : void m_sp_poison_cloud(pmt m)
41 : : {
42 [ # # ]: 0 : if (distance(m->x,m->y,Player.x,Player.y) < 3) {
43 : 0 : mprint("A cloud of poison gas surrounds you!");
44 [ # # ]: 0 : if (Player.status[BREATHING] > 0)
45 : 0 : mprint("You can breathe freely, however.");
46 : 0 : else p_poison(7);
47 : : }
48 : 0 : }
49 : :
50 : :
51 : 0 : void m_sp_explode(pmt m)
52 : : {
53 [ # # ][ # # ]: 0 : if ((distance(Player.x,Player.y,m->x,m->y)<2) &&
54 [ # # ]: 0 : (m-> hp > 0) &&
55 : 0 : (m->hp < Monsters[m->id].hp))
56 : 0 : fball(m->x,m->y,m->x,m->y,m->hp);
57 : 0 : }
58 : :
59 : :
60 : 0 : void m_sp_demon (pmt m)
61 : : {
62 : : int mid;
63 : :
64 [ # # ]: 0 : if (random_range(2))
65 : : {
66 [ # # ]: 0 : if ((m->id != INCUBUS) /* succubi don't give fear */
67 [ # # ]: 0 : && los_p(m->x, m->y, Player.x, Player.y)
68 [ # # ]: 0 : && (random_range(30) > (Player.level + 10))
69 [ # # ]: 0 : && (0 == Player.status[AFRAID]))
70 : : {
71 : 0 : mprint("You are stricken with fear!");
72 [ # # ]: 0 : if (!p_immune(FEAR))
73 : 0 : Player.status[AFRAID] += m->level;
74 : : else
75 : 0 : mprint("You master your reptile brain and stand fast.");
76 : : }
77 : : else
78 : : {
79 : 0 : m_sp_spell(m);
80 : : }
81 : : }
82 : :
83 [ # # ][ # # ]: 0 : if ((m->hp < (m->level * 5)) && (m->hp > 1))
84 : : {
85 : 0 : mprint("The demon uses its waning lifeforce to summon help!");
86 : 0 : m->hp = 1;
87 [ # # # # : 0 : switch(m->level)
# # # ]
88 : : {
89 : 0 : case 3: mid = NIGHT_GAUNT; break;
90 : : case 4:
91 : 0 : case 5: mid = L_FDEMON; break; /* lesser frost demon */
92 : 0 : case 6: mid = FROST_DEMON; break;
93 : 0 : case 7: mid = OUTER_DEMON; break; /* outer circle demon */
94 : 0 : case 8: mid = DEMON_SERP; break; /* demon serpent */
95 : 0 : case 9: mid = INNER_DEMON; break; /* inner circle demon */
96 : 0 : default: mid = 0; assert(FALSE); /* bomb on error */
97 : : }
98 : :
99 : 0 : summon(-1, mid);
100 : 0 : summon(-1, mid);
101 : : }
102 : 0 : }
103 : :
104 : :
105 : 0 : void m_sp_acid_cloud(pmt m)
106 : : {
107 [ # # # # ]: 0 : if (m_statusp(m,HOSTILE) &&
108 : 0 : (distance(m->x,m->y,Player.x,Player.y) < 3))
109 : 0 : acid_cloud();
110 : 0 : }
111 : :
112 : :
113 : 0 : void m_sp_escape(pmt m)
114 : : {
115 [ # # ]: 0 : if (m_statusp(m,HOSTILE))
116 : 0 : m_vanish(m);
117 : 0 : }
118 : :
119 : :
120 : 0 : void m_sp_ghost(pmt m)
121 : : {
122 [ # # ]: 0 : if (m_statusp(m,HOSTILE)) {
123 : 0 : mprint("The ghost moans horribly....");
124 : 0 : p_damage(1,FEAR,"a ghost-inspired heart attack");
125 : 0 : mprint("You've been terrorized!");
126 [ # # ]: 0 : if (! p_immune(FEAR)) Player.status[AFRAID] += m->level;
127 : 0 : else mprint("You master your reptile brain and stand fast.");
128 : : }
129 : 0 : }
130 : :
131 : :
132 : : /* random spell cast by monster */
133 : 0 : void m_sp_spell(pmt m)
134 : : {
135 : : char action[80];
136 [ # # ][ # # ]: 0 : if (m_statusp(m,HOSTILE) && los_p(Player.x,Player.y,m->x,m->y)) {
137 [ # # ]: 0 : if (m->uniqueness == COMMON) strcpy(action,"The ");
138 : 0 : else strcpy(action,"");
139 : 0 : strcat(action,m->monstring);
140 : 0 : strcat(action," casts a spell...");
141 : 0 : mprint(action);
142 [ # # ][ # # : 0 : if (! magic_resist(m->level)) switch (random_range(m->level+7)) {
# # # # #
# # # # #
# # # #
# ]
143 : : case 0:
144 : 0 : nbolt(m->x,m->y,Player.x,Player.y,m->hit,10);
145 : 0 : break;
146 : : case 1:
147 : 0 : mprint("It seems stronger...");
148 : 0 : m->hp += random_range(m->level*m->level);
149 : 0 : break;
150 : : case 2:
151 : 0 : haste(-1);
152 : 0 : break;
153 : : case 3:
154 : 0 : cure(-1);
155 : 0 : break;
156 : : case 4:
157 : : /* WDT: I'd like to make this (and "case 5" below) dependant on
158 : : * the monster's IQ in some way -- dumb but powerful monsters
159 : : * deserve what they get :). No rush. */
160 [ # # # # ]: 0 : if (m_immunityp(m, ELECTRICITY) ||
161 : 0 : distance(m->x,m->y,Player.x,Player.y) > 2)
162 : 0 : lball(m->x,m->y,Player.x,Player.y,20);
163 : : else
164 : 0 : lbolt(m->x,m->y,Player.x,Player.y,m->hit,20);
165 : 0 : break;
166 : : case 5:
167 [ # # # # ]: 0 : if (m_immunityp(m, COLD) ||
168 : 0 : distance(m->x,m->y,Player.x,Player.y) > 2)
169 : 0 : snowball(m->x,m->y,Player.x,Player.y,30);
170 : : else
171 : 0 : icebolt(m->x,m->y,Player.x,Player.y,m->hit,30);
172 : 0 : break;
173 : : case 6:
174 : 0 : enchant(-1);
175 : 0 : break;
176 : : case 7:
177 : 0 : bless(0-m->level);
178 : 0 : break;
179 : : case 8:
180 : 0 : p_poison(m->level);
181 : 0 : break;
182 : : case 9:
183 : 0 : sleep_player(m->level/2);
184 : 0 : break;
185 : : case 10:
186 : 0 : fbolt(m->x,m->y,Player.x,Player.y,m->hit*3,50);
187 : 0 : break;
188 : : case 11:
189 : 0 : acquire(0-m->level);
190 : 0 : break;
191 : : case 12:
192 : 0 : dispel(-1);
193 : 0 : break;
194 : : case 13:
195 : 0 : disrupt(Player.x,Player.y,50);
196 : 0 : break;
197 : : case 14:
198 [ # # ]: 0 : if (m->uniqueness == COMMON) {
199 : 0 : strcpy(Str2,"a ");
200 : 0 : strcat(Str2,m->monstring);
201 : : }
202 : 0 : else strcpy(Str2,m->monstring);
203 : 0 : level_drain(m->level,Str2);
204 : 0 : break;
205 : : case 15:
206 : : case 16:
207 : 0 : disintegrate(Player.x,Player.y);
208 : 0 : break;
209 : : }
210 : : }
211 : 0 : }
212 : :
213 : :
214 : :
215 : : /* monsters with this have some way to hide, camouflage, etc until they
216 : : attack */
217 : 0 : void m_sp_surprise(pmt m)
218 : : {
219 [ # # ]: 0 : if (m->attacked) {
220 [ # # ][ # # ]: 0 : if (m_statusp(m,HOSTILE) &&
221 [ # # ]: 0 : (! Player.status[TRUESIGHT]) &&
222 : 0 : m_statusp(m,M_INVISIBLE)) {
223 : 0 : m->monchar = Monsters[m->id].monchar;
224 [ # # ]: 0 : if (! Player.status[ALERT]) {
225 [ # # # # : 0 : switch(random_range(4)) {
# ]
226 : : case 0:
227 : 0 : mprint("You are surprised by a sudden treacherous attack!");
228 : 0 : break;
229 : : case 1:
230 : 0 : mprint("You are shocked out of your reverie by the scream of battle!");
231 : 0 : break;
232 : : case 2:
233 : 0 : mprint("Suddenly, from out of the shadows, a surprise attack!");
234 : 0 : break;
235 : : case 3:
236 : 0 : mprint("A shriek of hatred causes you to momentarily freeze up!");
237 : 0 : break;
238 : : }
239 : 0 : morewait();
240 : 0 : setgamestatus(SKIP_PLAYER);
241 : 0 : m_status_reset(m,M_INVISIBLE);
242 : : }
243 : : else {
244 : 0 : mprint("You alertly sense the presence of an attacker!");
245 : 0 : m_status_reset(m,M_INVISIBLE);
246 : : }
247 : : }
248 : : }
249 : 0 : }
250 : :
251 : 0 : void m_sp_whistleblower(pmt m)
252 : : {
253 [ # # ]: 0 : if (m_statusp(m,HOSTILE)) {
254 : 0 : alert_guards();
255 : 0 : m->specialf = M_MELEE_NORMAL;
256 : : }
257 : 0 : }
258 : :
259 : :
260 : 0 : void m_sp_seductor(pmt m)
261 : : {
262 [ # # ]: 0 : if (m_statusp(m,HOSTILE)) {
263 [ # # ]: 0 : if (m->uniqueness == COMMON) {
264 : 0 : strcpy(Str2,"The ");
265 : 0 : strcat(Str2,m->monstring);
266 : : }
267 : 0 : else strcpy(Str2,m->monstring);
268 : 0 : strcat(Str2," runs away screaming for help....");
269 : 0 : mprint(Str2);
270 : 0 : m_vanish(m);
271 : 0 : summon(-1,-1);
272 : 0 : summon(-1,-1);
273 : 0 : summon(-1,-1);
274 : : }
275 [ # # ]: 0 : else if (distance(Player.x,Player.y,m->x,m->y) < 2)
276 : 0 : m_talk_seductor(m);
277 : :
278 : 0 : }
279 : :
280 : :
281 : 0 : void m_sp_demonlover(pmt m)
282 : : {
283 [ # # ]: 0 : if (distance(Player.x,Player.y,m->x,m->y) < 2)
284 : 0 : m_talk_demonlover(m);
285 : 0 : }
286 : :
287 : 0 : void m_sp_eater(pmt m)
288 : : {
289 [ # # ]: 0 : if (Player.rank[COLLEGE]) m_status_set(m,HOSTILE);
290 [ # # ]: 0 : if (m_statusp(m,HOSTILE))
291 [ # # ]: 0 : if (los_p(m->x,m->y,Player.x,Player.y)) {
292 : 0 : mprint("A strange numbing sensation comes over you...");
293 : 0 : morewait();
294 : 0 : Player.mana = Player.mana / 2;
295 [ # # ]: 0 : if (random_range(4)) enchant(-1);
296 : 0 : else dispel(-1);
297 : 0 : Player.pow--;
298 [ # # ]: 0 : if (--Player.pow < 1) p_death("the Eater of Magic");
299 : : }
300 [ # # ]: 0 : if (m->hp < 10) {
301 : 0 : mprint("The Eater explodes in a burst of mana!");
302 : 0 : manastorm(m->x,m->y,1000);
303 : : }
304 : 0 : }
305 : :
306 : :
307 : 0 : void m_sp_dragonlord(pmt m)
308 : : {
309 [ # # ]: 0 : if (m_statusp(m,HOSTILE)) {
310 [ # # ]: 0 : if (distance(m->x,m->y,Player.x,Player.y)<2) {
311 [ # # ]: 0 : if (! Player.status[IMMOBILE]) {
312 : 0 : mprint("A gust of wind from the Dragonlord's wings knocks you down!");
313 : 0 : p_damage(25,NORMAL_DAMAGE,"a gust of wind");
314 : 0 : setgamestatus(SKIP_PLAYER);
315 : 0 : Player.status[IMMOBILE]+=2;
316 : : }
317 [ # # ]: 0 : else if (! Constriction) {
318 : 0 : mprint("The Dragonlord grabs you with his tail!");
319 : 0 : Constriction = 25;
320 : 0 : Player.status[IMMOBILE]+=1;
321 : : }
322 [ # # ]: 0 : else if (random_range(2)) {
323 : 0 : mprint("The coils squeeze tighter and tighter...");
324 : 0 : p_damage(Constriction,NORMAL_DAMAGE,"the Dragonlord");
325 : 0 : Player.status[IMMOBILE]+=1;
326 : 0 : Constriction *=2;
327 : : }
328 : : else {
329 : 0 : mprint("The Dragonlord hurls you to the ground!");
330 : 0 : p_damage(2*Constriction,NORMAL_DAMAGE,"the Dragonlord");
331 : 0 : Constriction = 0;
332 : : }
333 : 0 : m_sp_spell(m);
334 : : }
335 : : else {
336 : 0 : Constriction = 0;
337 [ # # ]: 0 : if (view_los_p(m->x,m->y,Player.x,Player.y)) {
338 [ # # ][ # # ]: 0 : if ((! Player.immunity[FEAR]) && (! Player.status[AFRAID])) {
339 : 0 : mprint("You are awestruck at the sight of the Dragonlord.");
340 : 0 : Player.status[AFRAID]+=5;
341 : : }
342 [ # # ]: 0 : if (random_range(3)) {
343 : 0 : m_sp_spell(m);
344 : 0 : m_sp_spell(m);
345 : : }
346 : : }
347 : : }
348 : : }
349 [ # # ]: 0 : else if (distance(m->x,m->y,Player.x,Player.y)<2)
350 : 0 : mprint("You are extremely impressed at the sight of the Dragonlord.");
351 : 0 : }
352 : :
353 : :
354 : 0 : void m_sp_blackout(pmt m)
355 : : {
356 [ # # ][ # # ]: 0 : if ((distance(m->x,m->y,Player.x,Player.y) < 4) &&
357 : 0 : (Player.status[BLINDED] == 0)) {
358 : 0 : mprint("The fungus emits a burst of black spores. You've been blinded!");
359 [ # # ]: 0 : if (Player.status[TRUESIGHT] > 0) mprint("The blindness quickly passes.");
360 : 0 : else Player.status[BLINDED]+=4;
361 : : }
362 [ # # ]: 0 : if (loc_statusp(m->x,m->y,LIT)) {
363 : 0 : mprint("The fungus chirps.... ");
364 : 0 : mprint("The area is plunged into darkness.");
365 : 0 : torch_check();torch_check();torch_check();
366 : 0 : torch_check();torch_check();torch_check();
367 : 0 : spreadroomdark(m->x,m->y,Level->site[m->x][m->y].roomnumber);
368 : 0 : levelrefresh();
369 : : }
370 : 0 : }
371 : :
372 : :
373 : 0 : void m_sp_bogthing(pmt m)
374 : : {
375 [ # # # # ]: 0 : if (Player.status[IMMOBILE] &&
376 : 0 : (distance(Player.x,Player.y,m->x,m->y) < 2)) {
377 [ # # ]: 0 : if (! Player.status[AFRAID]) {
378 : 0 : mprint("As the bogthing touches you, you feel a frisson of terror....");
379 [ # # ]: 0 : if (Player.immunity[FEAR]) mprint("which you shake off.");
380 : 0 : else Player.status[AFRAID]+=2;
381 : : }
382 : : else {
383 : 0 : mprint("The bogthing's touch causes you scream in agony!");
384 : 0 : p_damage(50,UNSTOPPABLE,"fright");
385 : 0 : mprint("Your struggles grow steadily weaker....");
386 : 0 : Player.con--;
387 : 0 : Player.str--;
388 [ # # ][ # # ]: 0 : if ((Player.con < 3) || (Player.str < 3))
389 : 0 : p_death("congestive heart failure");
390 : : }
391 : : }
392 : 0 : }
393 : :
394 : :
395 : 0 : void m_sp_were(pmt m)
396 : : {
397 : : int mid;
398 [ # # ][ # # ]: 0 : if (m_statusp(m,HOSTILE) || (Phase == 6)) {
399 : 0 : do mid = random_range(ML9-NML_0)+ML1;
400 : : /* log npc, 0th level npc, high score npc or were-creature */
401 [ # # ][ # # ]: 0 : while (mid == NPC || mid == ZERO_NPC ||
402 [ # # ][ # # ]: 0 : mid == HISCORE_NPC || mid == WEREHUMAN ||
403 [ # # ]: 0 : (Monsters[mid].uniqueness != COMMON) ||
404 [ # # ]: 0 : (! m_statusp(&(Monsters[mid]),MOBILE)) ||
405 : 0 : (! m_statusp(&(Monsters[mid]),HOSTILE))
406 [ # # ]: 0 : );
407 : 0 : m->id = Monsters[mid].id;
408 : 0 : m->hp += Monsters[mid].hp;
409 : 0 : m->status |= Monsters[mid].status;
410 : 0 : m->ac = Monsters[mid].ac;
411 : 0 : m->dmg = Monsters[mid].dmg;
412 : 0 : m->speed = Monsters[mid].speed;
413 : 0 : m->immunity |= Monsters[mid].immunity;
414 : 0 : m->xpv += Monsters[mid].xpv;
415 : 0 : m->corpseweight = Monsters[mid].corpseweight;
416 : 0 : m->monchar = Monsters[mid].monchar;
417 : 0 : m->talkf = Monsters[mid].talkf;
418 : 0 : m->meleef = Monsters[mid].meleef;
419 : 0 : m->strikef = Monsters[mid].strikef;
420 : 0 : m->specialf = Monsters[mid].specialf;
421 : 0 : strcpy(Str1,"were-");
422 : 0 : strcat(Str1,Monsters[mid].monstring);
423 : 0 : strcpy(Str2,"dead were-");
424 : 0 : strcat(Str2,Monsters[mid].monstring);
425 : 0 : m->monstring = salloc(Str1);
426 : 0 : m->corpsestr = salloc(Str2);
427 : 0 : m_status_set( m, ALLOC );
428 : 0 : m->immunity |= pow2(NORMAL_DAMAGE); /* WDT: not +=, rather |=. */
429 [ # # ]: 0 : if (los_p(m->x,m->y,Player.x,Player.y))
430 : 0 : mprint("You witness a hideous transformation!");
431 : 0 : else mprint("You hear a distant howl.");
432 : : }
433 : 0 : }
434 : :
435 : :
436 : 0 : void m_sp_servant(pmt m)
437 : : {
438 [ # # ][ # # ]: 0 : if ((m->id == SERV_LAW) && (Player.alignment < 0))
439 : 0 : m_status_set(m,HOSTILE);
440 [ # # ][ # # ]: 0 : else if ((m->id == SERV_CHAOS) && (Player.alignment > 0))
441 : 0 : m_status_set(m,HOSTILE);
442 : 0 : }
443 : :
444 : :
445 : 0 : void m_sp_av(pmt m)
446 : : {
447 [ # # ]: 0 : if (Player.mana > 0) {
448 : 0 : mprint("You feel a sudden loss of mana!");
449 [ # # ]: 0 : Player.mana -= (max(0,10-distance(m->x,m->y,Player.x,Player.y)));
450 : 0 : dataprint();
451 : : }
452 : 0 : }
453 : :
454 : 0 : void m_sp_lw(pmt m)
455 : : {
456 [ # # ]: 0 : if (random_range(2)) {
457 [ # # ]: 0 : if (Level->site[m->x][m->y].locchar == FLOOR) {
458 : 0 : Level->site[m->x][m->y].locchar = LAVA;
459 : 0 : Level->site[m->x][m->y].p_locf = L_LAVA;
460 : 0 : lset(m->x, m->y, CHANGED);
461 : : }
462 [ # # ]: 0 : else if (Level->site[m->x][m->y].locchar == WATER) {
463 : 0 : Level->site[m->x][m->y].locchar = FLOOR;
464 : 0 : Level->site[m->x][m->y].p_locf = L_NO_OP;
465 : 0 : lset(m->x, m->y, CHANGED);
466 : : }
467 : : }
468 : 0 : }
469 : :
470 : :
471 : 0 : void m_sp_angel(pmt m)
472 : : {
473 : 0 : int mid,hostile = FALSE;
474 [ # # # # ]: 0 : switch(m->aux1) {
475 : : case ATHENA:
476 : : case ODIN:
477 [ # # ][ # # ]: 0 : hostile = ((Player.patron == HECATE) || (Player.patron == SET));
478 : 0 : break;
479 : : case SET:
480 : : case HECATE:
481 [ # # ][ # # ]: 0 : hostile = ((Player.patron == ODIN) || (Player.patron == ATHENA));
482 : 0 : break;
483 : : case DESTINY:
484 : 0 : hostile = (Player.patron != DESTINY);
485 : 0 : break;
486 : : }
487 [ # # ]: 0 : if (hostile)
488 : 0 : m_status_set(m,HOSTILE);
489 [ # # ]: 0 : if (m_statusp(m,HOSTILE)) {
490 : 0 : mprint("The angel summons a heavenly host!");
491 [ # # # ]: 0 : switch(m->level) {
492 : 0 : case 9: mid = HIGH_ANGEL; break;
493 : 0 : case 8: mid = ANGEL; break;
494 : : default:
495 : 0 : case 6: mid = PHANTOM; break;
496 : : }
497 : 0 : summon(-1,mid);
498 : 0 : summon(-1,mid);
499 : 0 : summon(-1,mid);
500 : : /* prevent angel from summoning infinitely */
501 : 0 : m->specialf = M_NO_OP;
502 : : }
503 : 0 : }
504 : :
505 : :
506 : : /* Could completely fill up level */
507 : 0 : void m_sp_swarm(pmt m)
508 : : {
509 [ # # ]: 0 : if (random_range(5)==1) {
510 [ # # ]: 0 : if (view_los_p(m->x,m->y,Player.x,Player.y))
511 : 0 : mprint("The swarm expands!");
512 : 0 : else mprint("You hear an aggravating humming noise.");
513 : 0 : summon(-1,SWARM);
514 : : }
515 : 0 : }
516 : :
517 : :
518 : : /* raise nearby corpses from the dead.... */
519 : 0 : void m_sp_raise(pmt m)
520 : : {
521 : : int x,y;
522 : : pol t;
523 [ # # ]: 0 : for(x=m->x-2;x<=m->x+2;x++)
524 [ # # ]: 0 : for(y=m->y-2;y<=m->y+2;y++)
525 [ # # ]: 0 : if (inbounds(x,y))
526 [ # # ]: 0 : if (Level->site[x][y].things != NULL)
527 [ # # ]: 0 : if (Level->site[x][y].things->thing->id == CORPSEID) {
528 : 0 : mprint("The Zombie Overlord makes a mystical gesture...");
529 : 0 : summon(-1,Level->site[x][y].things->thing->charge);
530 : 0 : t = Level->site[x][y].things;
531 : 0 : Level->site[x][y].things = Level->site[x][y].things->next;
532 : 0 : free_obj( t->thing, TRUE );
533 : 0 : free((char *) t);
534 : : }
535 : 0 : }
536 : :
537 : :
538 : :
539 : 0 : void m_sp_mb(pmt m)
540 : : {
541 [ # # ]: 0 : if (distance(m->x,m->y,Player.x,Player.y)==1) {
542 : 0 : mprint("The manaburst explodes!");
543 [ # # ]: 0 : if (m_statusp(m,HOSTILE)) {
544 : 0 : mprint("You get blasted!");
545 : 0 : p_damage(random_range(100),UNSTOPPABLE,"a manaburst");
546 : 0 : mprint("You feel cold all over!");
547 : 0 : Player.pow-=3;
548 : 0 : Player.iq--;
549 : 0 : Player.con--;
550 : 0 : Player.str-=2;
551 : 0 : Player.dex--;
552 : 0 : Player.agi--;
553 : 0 : dispel(-1);
554 : : /* DAG -- need calc_melee/calcmana here, because of new stats */
555 : 0 : calc_melee();
556 : 0 : Player.maxmana = calcmana();
557 : 0 : Player.mana = min( Player.mana, Player.maxmana );
558 : : }
559 : : else {
560 : 0 : mprint("You feel toasty warm inside!");
561 : 0 : Player.pow++;
562 [ # # ]: 0 : Player.mana = max(Player.mana,calcmana());
563 [ # # ]: 0 : Player.hp = max(Player.hp,++Player.maxhp);
564 : : }
565 : : /* DAG -- to fix the explode but not die manaburst bug */
566 : 0 : m_remove( m );
567 : : }
568 : 0 : }
569 : :
570 : :
571 : 0 : void m_sp_mirror(pmt m)
572 : : {
573 : : int i,x,y;
574 [ # # ]: 0 : if (view_los_p(m->x,m->y,Player.x,Player.y)) {
575 [ # # ]: 0 : if (random_range(20)+6 < m->level) {
576 : 0 : summon(-1,m->id);
577 : 0 : mprint("You hear the sound of a mirror shattering!");
578 : : }
579 [ # # ]: 0 : else for(i=0;i<5;i++) {
580 : 0 : x = m->x + random_range(13)-6;
581 : 0 : y = m->y + random_range(13)-6;
582 [ # # ]: 0 : if (inbounds(x,y)) {
583 : 0 : Level->site[x][y].showchar = m->monchar;
584 : 0 : putspot(x,y,m->monchar);
585 : : }
586 : : }
587 : : }
588 : 0 : }
589 : :
590 : :
591 : :
592 : 6 : void m_illusion(pmt m)
593 : : {
594 : 6 : int i = random_range(NUMMONSTERS);
595 [ + - ][ + - ]: 6 : if (i==NPC || i==HISCORE_NPC || i==ZERO_NPC) i = m->id; /* can't imitate NPC */
[ - + ]
596 [ - + ]: 6 : if (Player.status[TRUESIGHT]) {
597 : 0 : m->monchar = Monsters[m->id].monchar;
598 : 0 : m->monstring = Monsters[m->id].monstring;
599 : : }
600 [ + + ]: 6 : else if (random_range(5) == 1) {
601 : 2 : m->monchar = Monsters[i].monchar;
602 : 2 : m->monstring = Monsters[i].monstring;
603 : : }
604 : 6 : }
605 : :
606 : :
607 : :
608 : 0 : void m_huge_sounds(pmt m)
609 : : {
610 [ # # # # ]: 0 : if (m_statusp(m,AWAKE) &&
611 [ # # ]: 0 : (! los_p(m->x,m->y,Player.x,Player.y)) &&
612 : 0 : (random_range(10) == 1))
613 : 0 : mprint("The dungeon shakes!");
614 : 0 : }
615 : :
616 : :
617 : :
618 : 0 : void m_thief_f(pmt m)
619 : : {
620 : 0 : int i = stolen_item();
621 [ # # ]: 0 : if (random_range(3) == 1) {
622 [ # # ]: 0 : if (distance(Player.x,Player.y,m->x,m->y) < 2) {
623 [ # # ][ # # ]: 0 : if (p_immune(THEFT) || (Player.level > (m->level*2)+random_range(20)))
624 : 0 : mprint("You feel secure.");
625 : : else {
626 [ # # ]: 0 : if (i == ABORT)
627 : 0 : mprint("You feel fortunate.");
628 [ # # # # ]: 0 : else if ((Player.possessions[i]->used) ||
629 : 0 : (Player.dex < m->level*random_range(10))) {
630 : 0 : mprint("You feel a sharp tug.... You hold on!");
631 : : }
632 : : else {
633 : 0 : mprint("You feel uneasy for a moment.");
634 [ # # ]: 0 : if (m->uniqueness == COMMON) {
635 : 0 : strcpy(Str2,"The ");
636 : 0 : strcat(Str2,m->monstring);
637 : : }
638 : 0 : else strcpy(Str2,m->monstring);
639 : 0 : strcat(Str2," suddenly runs away for some reason.");
640 : 0 : mprint(Str2);
641 : 0 : m_teleport(m);
642 : 0 : m->movef = M_MOVE_SCAREDY;
643 : 0 : m->specialf = M_MOVE_SCAREDY;
644 : 0 : m_pickup(m,Player.possessions[i]);
645 : 0 : conform_unused_object(Player.possessions[i]);
646 : 0 : Player.possessions[i] = NULL;
647 : : }
648 : : }
649 : : }
650 : : }
651 : 0 : }
652 : :
653 : :
654 : 0 : void m_summon(pmt m)
655 : : {
656 [ # # # # ]: 0 : if ((distance(Player.x,Player.y,m->x,m->y) < 2) &&
657 : 0 : (random_range(3) == 1)) {
658 : 0 : summon(0,-1);
659 : 0 : summon(0,-1);
660 : : }
661 : 0 : }
662 : :
663 : :
664 : 0 : void m_aggravate(pmt m)
665 : : {
666 : :
667 [ # # ]: 0 : if (m_statusp(m,HOSTILE)) {
668 [ # # ]: 0 : if (m->uniqueness == COMMON) {
669 : 0 : strcpy(Str2,"The ");
670 : 0 : strcat(Str2,m->monstring);
671 : : }
672 : 0 : else strcpy(Str2,m->monstring);
673 : 0 : strcat(Str2," emits an irritating humming sound.");
674 : 0 : mprint(Str2);
675 : 0 : aggravate();
676 : 0 : m_status_reset(m,HOSTILE);
677 : : }
678 : 0 : }
679 : :
680 : :
681 : :
682 : 0 : void m_sp_merchant(pmt m)
683 : : {
684 : : pml ml;
685 [ # # ]: 0 : if (m_statusp(m,HOSTILE))
686 [ # # ]: 0 : if (Current_Environment == E_VILLAGE) {
687 : 0 : mprint("The merchant screams: 'Help! Murder! Guards! Help!'");
688 : 0 : mprint("You hear the sound of police whistles and running feet.");
689 [ # # ]: 0 : for (ml=Level->mlist;ml!=NULL;ml=ml->next) {
690 : 0 : m_status_set(ml->m,AWAKE);
691 : 0 : m_status_set(ml->m,HOSTILE);
692 : : }
693 : 0 : m->specialf = M_NO_OP;
694 : : }
695 : 0 : }
696 : :
697 : : /* The special function of the various people in the court of the archmage */
698 : : /* and the sorcerors' circle */
699 : 0 : void m_sp_court(pmt m)
700 : : {
701 : : pml ml;
702 [ # # ]: 0 : if (m_statusp(m,HOSTILE)) {
703 : 0 : mprint("A storm of spells hits you!");
704 [ # # ]: 0 : for(ml=Level->mlist;ml!=NULL;ml=ml->next) {
705 : 0 : m_status_set(ml->m,HOSTILE);
706 : 0 : m_sp_spell(ml->m);
707 [ # # ]: 0 : if (ml->m->specialf == M_SP_COURT)
708 : 0 : ml->m->specialf = M_SP_SPELL;
709 : : }
710 : : }
711 : 0 : }
712 : :
713 : :
714 : : /* The special function of the dragons in the dragons' lair */
715 : 0 : void m_sp_lair(pmt m)
716 : : {
717 : : pml ml;
718 [ # # ]: 0 : if (m_statusp(m,HOSTILE)) {
719 : 0 : mprint("You notice a number of dragons waking up....");
720 : 0 : mprint("You are struck by a quantity of firebolts.");
721 : 0 : morewait();
722 [ # # ]: 0 : for(ml=Level->mlist;ml!=NULL;ml=ml->next)
723 [ # # ][ # # ]: 0 : if (ml->m->hp > 0 && ml->m->specialf == M_SP_LAIR) {
724 : 0 : m_status_set(ml->m,HOSTILE);
725 : 0 : fbolt(ml->m->x,ml->m->y,Player.x,Player.y,100,100);
726 [ # # ]: 0 : if (ml->m->id == DRAGON_LORD)
727 : 0 : ml->m->specialf = M_SP_DRAGONLORD;
728 : : else
729 : 0 : ml->m->specialf = M_STRIKE_FBOLT;
730 : : }
731 : : }
732 : 0 : }
733 : :
734 : :
735 : 0 : void m_sp_prime(pmt m)
736 : : {
737 [ # # ]: 0 : if (m_statusp(m,HOSTILE)) {
738 : 0 : mprint("The prime sorceror gestures and a pentacular gate opens!");
739 : 0 : mprint("You are surrounded by demons!");
740 : 0 : summon(-1,DEMON_PRINCE);
741 : 0 : summon(-1,DEMON_PRINCE);
742 : 0 : summon(-1,DEMON_PRINCE);
743 : 0 : summon(-1,DEMON_PRINCE);
744 : : }
745 : 0 : m->specialf = M_SP_SPELL;
746 : 0 : }
|