Branch data Line data Source code
1 : : /* omega copyright (c) 1987,1988,1989 by Laurence Raphael Brothers */
2 : : /* mon.c */
3 : : /* various functions to do with monsters */
4 : :
5 : : #include "glob.h"
6 : :
7 : :
8 : :
9 : : /* Revised function */
10 : : /* WDT: code contributed by David J. Robertson */
11 : : /* consider one monster's action */
12 : 322 : void m_pulse(pmt m)
13 : : {
14 : 322 : int range = distance(m->x, m->y, Player.x,Player.y);
15 : 322 : int STRIKE=FALSE;
16 : : pol prev;
17 : :
18 [ - + ]: 322 : if (Time % 10 == 0)
19 [ # # ]: 0 : if (m->hp < Monsters[m->id].hp)
20 : 0 : m->hp++;
21 : :
22 [ + + ][ + + ]: 322 : if ((! m_statusp(m,AWAKE)) && (range <= m->wakeup)) {
23 : 1 : m_status_set(m,AWAKE);
24 : 1 : resetgamestatus(FAST_MOVE);
25 : : }
26 : :
27 [ + + ]: 322 : if (m_statusp(m,AWAKE)) {
28 [ - + ]: 286 : if (m_statusp(m,WANDERING)) {
29 [ # # ]: 0 : if (m_statusp(m,MOBILE)) m_random_move(m);
30 [ # # ][ # # ]: 0 : if (range <= m->sense && (m_statusp(m, HOSTILE) ||
[ # # ]
31 : 0 : m_statusp(m, NEEDY)))
32 : 0 : m_status_reset(m,WANDERING);
33 : : }
34 : : else /* not wandering */ {
35 [ + + ]: 286 : if (m_statusp(m,HOSTILE))
36 [ + + ][ + + ]: 156 : if ((range > 2) && (range < m->sense) && (random_range(2) == 1))
[ + + ]
37 [ + + ][ + - ]: 4 : if (los_p(m->x,m->y,Player.x,Player.y) &&
38 : 2 : (Player.status[INVISIBLE] == 0)) {
39 : 2 : STRIKE=TRUE;
40 : 2 : monster_strike(m);
41 : : }
42 : :
43 [ + + ][ - + ]: 286 : if ((m_statusp(m,HOSTILE) || m_statusp(m,NEEDY))
44 [ + + ][ + - ]: 156 : && (range > 1) && m_statusp(m,MOBILE) &&
[ + + ]
45 [ + + ]: 2 : (!STRIKE || (random_range(2) == 1)))
46 : 136 : monster_move(m);
47 : : else
48 [ + + ][ + + ]: 150 : if (m_statusp(m,HOSTILE) && (range ==1)) {
49 : 19 : resetgamestatus(FAST_MOVE);
50 : 19 : tacmonster(m);
51 : : }
52 : : }
53 : : /* if monster is greedy, picks up treasure it finds */
54 [ + + ][ + - ]: 285 : if (m_statusp(m,GREEDY) && (m->hp >0) )
55 [ + + ]: 149 : while (Level->site[m->x][m->y].things != NULL) {
56 : 4 : m_pickup(m,Level->site[m->x][m->y].things->thing);
57 : 4 : prev = Level->site[m->x][m->y].things;
58 : 8 : Level->site[m->x][m->y].things =
59 : 4 : Level->site[m->x][m->y].things->next;
60 : 4 : free((char *) prev);
61 : : }
62 : : /* prevents monsters from casting spells from other side of dungeon */
63 [ + + ]: 314 : if ((range < max(5,m->level)) && (m->hp > 0) &&
[ + - + + ]
64 : 29 : (random_range(2) == 1))
65 : 15 : monster_special(m);
66 : : }
67 : 321 : }
68 : :
69 : : /* actually make a move */
70 : 100 : void movemonster(pmt m, int newx, int newy)
71 : : {
72 [ - + ]: 100 : if (Level->site[newx][newy].creature != NULL)
73 : 0 : return;
74 [ + - ]: 100 : if (Level->site[m->x][m->y].creature == m)
75 : 100 : Level->site[m->x][m->y].creature = NULL;
76 : 100 : m->x = newx;
77 : 100 : m->y = newy;
78 : 100 : Level->site[m->x][m->y].creature = m;
79 : 100 : m_movefunction(m,Level->site[m->x][m->y].p_locf);
80 : : }
81 : :
82 : :
83 : : /* give object o to monster m */
84 : 18 : void m_pickup(pmt m, pob o)
85 : : {
86 : 18 : pol tmp = ((pol) checkmalloc(sizeof(oltype)));
87 : 18 : tmp->thing = o;
88 : 18 : tmp->next = m->possessions;
89 : 18 : m->possessions = tmp;
90 : 18 : }
91 : :
92 : 2 : void m_dropstuff(pmt m)
93 : : {
94 : 2 : pol tmp = m->possessions;
95 [ + - ]: 2 : if (tmp != NULL) {
96 [ + + ]: 4 : while (tmp->next != NULL)
97 : 2 : tmp = tmp->next;
98 : :
99 : 2 : tmp->next = Level->site[m->x][m->y].things;
100 : 2 : Level->site[m->x][m->y].things = m->possessions;
101 : 2 : m->possessions = NULL;
102 : : }
103 : 2 : }
104 : :
105 : :
106 : 3 : void m_damage(pmt m, int dmg, int dtype)
107 : : {
108 : 3 : m_status_set(m,AWAKE);
109 : 3 : m_status_set(m,HOSTILE);
110 [ - + ]: 3 : if (m_immunityp(m,dtype)) {
111 [ # # ]: 0 : if (los_p(Player.x,Player.y,m->x,m->y)) {
112 [ # # ]: 0 : if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
113 : : else {
114 : 0 : strcpy(Str1,"The ");
115 : 0 : strcat(Str1,m->monstring);
116 : : }
117 : 0 : strcat(Str1," ignores the attack!");
118 : 0 : mprint(Str1);
119 : : }
120 : : }
121 [ + + ]: 3 : else if ((m->hp -= dmg) < 1) m_death(m);
122 : 3 : }
123 : :
124 : :
125 : : /* remove a monster -- death without crediting player */
126 : 0 : void m_remove(pmt m)
127 : : {
128 : 0 : Level->site[m->x][m->y].creature = NULL;
129 : 0 : erase_monster(m);
130 : 0 : m->hp = -1; /* signals "death" -- no credit to player, though */
131 : : /* DAG -- monster structure will be "cleaned up" in time_clock() which */
132 : : /* walks through all the monsters each "tick". (Or on level free.) */
133 : 0 : }
134 : :
135 : 2 : void m_death(pmt m)
136 : : {
137 : : pob corpse;
138 : : pml ml;
139 : 2 : int x,y,found=FALSE;
140 : 2 : pol curr, prev = NULL;
141 : :
142 : 2 : m->hp = -1;
143 [ + - ]: 2 : if (los_p(Player.x,Player.y,m->x,m->y)) {
144 : 2 : gain_experience(m->xpv);
145 : 2 : calc_melee();
146 [ - + ]: 2 : if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
147 : : else {
148 : 2 : strcpy(Str1,"The ");
149 : 2 : strcat(Str1,m->monstring);
150 : : }
151 : 2 : strcat(Str1," is dead! ");
152 : 2 : mprint(Str1);
153 : : }
154 : 2 : m_dropstuff(m);
155 [ - + ]: 2 : if (m->id == DEATH) { /* Death */
156 : 0 : mprint("Death lies sprawled out on the ground......");
157 : 0 : mprint("Death laughs ironically and gets back to its feet.");
158 : 0 : mprint("It gestures and another scythe appears in its hands.");
159 [ # # # # : 0 : switch(random_range(10)) {
# # # # #
# # ]
160 : : case 0:
161 : 0 : mprint("Death performs a little bow and goes back on guard.");
162 : 0 : break;
163 : : case 1:
164 : 0 : mprint("'A hit! A palpable hit!' Death goes back on the attack.");
165 : 0 : break;
166 : : case 2:
167 : 0 : mprint("'Ah, if only it could be so simple!' snickers Death.");
168 : 0 : break;
169 : : case 3:
170 : 0 : mprint("'You think Death can be slain? What a jest!' says Death.");
171 : 0 : break;
172 : : case 4:
173 : 0 : mprint("'Your point is well taken.' says Death, attacking again.");
174 : 0 : break;
175 : : case 5:
176 : 0 : mprint("'Oh, come now, stop delaying the inevitable.' says Death.");
177 : 0 : break;
178 : : case 6:
179 : 0 : mprint("'Your destiny ends here with me.' says Death, scythe raised.");
180 : 0 : break;
181 : : case 7:
182 : 0 : mprint("'I almost felt that.' says Death, smiling.");
183 : 0 : break;
184 : : case 8:
185 : 0 : mprint("'Timeo Mortis?' asks Death quizzically, 'Not me!'");
186 : 0 : break;
187 : : case 9:
188 : 0 : mprint("Death sighs theatrically. 'They never learn.'");
189 : 0 : break;
190 : : }
191 : 0 : strengthen_death(m);
192 : : }
193 : : else {
194 : 2 : Level->site[m->x][m->y].creature = NULL;
195 [ - + ]: 2 : if (m == Arena_Monster)
196 : 0 : Arena_Victory = TRUE; /* won this round of arena combat */
197 [ + + ][ - + ]: 2 : if (random_range(2) || (m->uniqueness != COMMON)) {
198 : 1 : corpse=((pob) checkmalloc(sizeof(objtype)));
199 : 1 : make_corpse(corpse,m);
200 : 1 : drop_at(m->x,m->y,corpse);
201 : : }
202 : 2 : plotspot(m->x,m->y,FALSE);
203 [ - - - - : 2 : switch(m->id) {
- - - - -
+ ]
204 : : case HISCORE_NPC:
205 [ # # # # : 0 : switch(m->aux2) {
# # # # #
# # # # ]
206 : : case 0:
207 : 0 : mprint("You hear a faroff dirge. You feel a sense of triumph.");
208 : 0 : break;
209 : : case 1:case 2: case 3:case 4:case 5:case 6:
210 : 0 : mprint("You hear a faroff sound like angels crying....");
211 : 0 : strcpy(Priest[m->aux2],nameprint());
212 : 0 : Priestbehavior[m->aux2] = 2933;
213 : 0 : break;
214 : : case 7:
215 : 0 : mprint("A furtive figure dashes out of the shadows, takes a look at");
216 : 0 : mprint("the corpse, and runs away!");
217 : 0 : strcpy(Shadowlord,nameprint());
218 : 0 : Shadowlordbehavior = 2912;
219 : 0 : break;
220 : : case 8:
221 : 0 : mprint("An aide-de-camp approaches, removes the corpse's insignia,");
222 : 0 : mprint("and departs.");
223 : 0 : strcpy(Commandant,nameprint());
224 : 0 : Commandantbehavior = 2912;
225 : 0 : break;
226 : : case 9:
227 : 0 : mprint("An odd glow surrounds the corpse, and slowly fades.");
228 : 0 : strcpy(Archmage,nameprint());
229 : 0 : Archmagebehavior = 2933;
230 : 0 : break;
231 : : case 10:
232 : 0 : mprint("A demon materializes, takes a quick look at the corpse,");
233 : 0 : mprint("and teleports away with a faint popping noise.");
234 : 0 : strcpy(Prime,nameprint());
235 : 0 : Primebehavior = 2932;
236 : 0 : break;
237 : : case 11:
238 : 0 : mprint("A sports columnist rushes forward and takes a quick photo");
239 : 0 : mprint("of the corpse and rushes off muttering about a deadline.");
240 : 0 : strcpy(Champion,nameprint());
241 : 0 : Championbehavior = 2913;
242 : 0 : break;
243 : : case 12:
244 : 0 : mprint("You hear a fanfare in the distance, and feel dismayed.");
245 : 0 : strcpy(Duke,nameprint());
246 : 0 : Dukebehavior = 2911;
247 : 0 : break;
248 : : case 13:
249 [ # # ]: 0 : if (Player.alignment > 10) mprint("You feel smug.");
250 [ # # ]: 0 : else if (Player.alignment < 10) mprint("You feel ashamed.");
251 : 0 : strcpy(Chaoslord,nameprint());
252 : 0 : Chaoslordbehavior = 2912;
253 : 0 : break;
254 : : case 14:
255 [ # # ]: 0 : if (Player.alignment < 10) mprint("You feel smug.");
256 [ # # ]: 0 : else if (Player.alignment > 10) mprint("You feel ashamed.");
257 : 0 : strcpy(Lawlord,nameprint());
258 : 0 : Lawlordbehavior = 2911;
259 : 0 : break;
260 : : case 15:
261 : : /* just a tad complicated. Promote a new justiciar if any
262 : : guards are left in the city, otherwise Destroy the Order! */
263 : 0 : Player.alignment -= 100;
264 [ # # ]: 0 : if (! gamestatusp(DESTROYED_ORDER)) {
265 : 0 : curr = Level->site[m->x][m->y].things;
266 [ # # ][ # # ]: 0 : while (curr && curr->thing->id != OB_JUSTICIAR_BADGE) {
267 : 0 : prev = curr;
268 : 0 : curr = curr->next;
269 : : }
270 : 0 : strcpy(Justiciar,nameprint());
271 : 0 : Justiciarbehavior = 2911;
272 : 0 : mprint("In the distance you hear a trumpet. A Servant of Law");
273 : : /* promote one of the city guards to be justiciar */
274 : 0 : ml = City->mlist;
275 [ # # ][ # # ]: 0 : while ((! found) && (ml != NULL)) {
276 [ # # ][ # # ]: 0 : found = ((ml->m->id == GUARD) && (ml->m->hp > 0));
277 [ # # ]: 0 : if (! found) ml=ml->next;
278 : : }
279 [ # # ]: 0 : if (ml != NULL) {
280 [ # # ]: 0 : if (curr) {
281 : 0 : mprint("materializes, sheds a tear, picks up the badge, and leaves.");
282 : 0 : m_pickup(ml->m, curr->thing);
283 [ # # ]: 0 : if (prev)
284 : 0 : prev->next = curr->next;
285 : : else
286 : 0 : Level->site[m->x][m->y].things = curr->next;
287 : 0 : free(curr);
288 : : }
289 : : else
290 : 0 : mprint("materializes, sheds a tear, and leaves.");
291 : 0 : mprint("A new justiciar has been promoted!");
292 : 0 : x = ml->m->x; y = ml->m->y;
293 : 0 : make_hiscore_npc(ml->m,15);
294 : 0 : ml->m->x = x;
295 : 0 : ml->m->y = y;
296 : 0 : ml->m->click = (Tick + 1) % 60;
297 : 0 : m_status_reset(ml->m,AWAKE);
298 : 0 : m_status_reset(ml->m,HOSTILE);
299 : : }
300 : : else {
301 : 0 : mprint("materializes, sheds a tear, and leaves.");
302 : 0 : morewait();
303 : : }
304 : 0 : alert_guards();
305 : : /* will cause order to be destroyed if no guards or justiciar*/
306 : : }
307 : : else {
308 : 0 : mprint("A Servant of Chaos materializes, grabs the corpse,");
309 : 0 : mprint("snickers a bit, and vanishes.");
310 : : }
311 : 0 : break;
312 : : case 16:
313 : : #ifdef TRADEMARK_VIOLATION /* paraphrase of harlan ellison... ? PGM */
314 : 0 : mprint("It doesn't rain this day, anywhere in the known universe.");
315 : : #else
316 : : mprint("The universal equilibrium slides down a notch.");
317 : : #endif
318 : 0 : strcpy(Grandmaster,nameprint());
319 : 0 : Grandmasterbehavior = 2933;
320 : 0 : break;
321 : : }
322 : 0 : save_hiscore_npc(m->aux2);
323 : 0 : break;
324 : : case GUARD: /* guard */
325 : 0 : Player.alignment -= 10;
326 [ # # ][ # # ]: 0 : if ((Current_Environment == E_CITY) ||
327 : 0 : (Current_Environment == E_VILLAGE))
328 : 0 : alert_guards();
329 : 0 : break;
330 : : case GOBLIN_KING:
331 [ # # ]: 0 : if (! gamestatusp(ATTACKED_ORACLE)) {
332 : 0 : mprint("You seem to hear a woman's voice from far off:");
333 : 0 : mprint("'Well done! Come to me now....'");
334 : : }
335 : 0 : setgamestatus(COMPLETED_CAVES);
336 : 0 : break; /* gob king */
337 : : case GREAT_WYRM:
338 [ # # ]: 0 : if (! gamestatusp(ATTACKED_ORACLE)) {
339 : 0 : mprint("A female voice sounds from just behind your ear:");
340 : 0 : mprint("'Well fought! I have some new advice for you....'");
341 : : }
342 : 0 : setgamestatus(COMPLETED_SEWERS);
343 : 0 : break; /*grt worm */
344 : : case EATER:
345 : 0 : setgamestatus(KILLED_EATER);
346 : 0 : break;
347 : : case LAWBRINGER:
348 : 0 : setgamestatus(KILLED_LAWBRINGER);
349 : 0 : break;
350 : : case DRAGON_LORD:
351 : 0 : setgamestatus(KILLED_DRAGONLORD);
352 : 0 : break;
353 : : case DEMON_EMP:
354 : 0 : setgamestatus(COMPLETED_VOLCANO);
355 [ # # ]: 0 : if (! gamestatusp(ATTACKED_ORACLE)) {
356 : 0 : mprint("You feel a soft touch on your shoulder...");
357 : 0 : mprint("You turn around but there is no one there!");
358 : 0 : mprint("You turn back and see a note: 'See me soon.'");
359 : 0 : mprint("The note vanishes in a burst of blue fire!");
360 : : }
361 : 0 : break;
362 : : case ELEM_MASTER:
363 [ # # ]: 0 : if (! gamestatusp(ATTACKED_ORACLE)) {
364 : 0 : mprint("Words appear before you, traced in blue flame!");
365 : 0 : mprint("'Return to the Prime Plane via the Circle of Sorcerors....'");
366 : : }
367 : 0 : break; /* elem mast */
368 : : }
369 [ - + ]: 2 : switch (m->specialf) {
370 : : case M_SP_COURT:
371 : : case M_SP_LAIR:
372 : 0 : m_status_set(m,HOSTILE);
373 : 0 : monster_action(m, m->specialf);
374 : : }
375 : : }
376 : 2 : }
377 : :
378 : 136 : void monster_move(pmt m)
379 : : {
380 : 136 : monster_action(m,m->movef);
381 : 136 : }
382 : :
383 : :
384 : 2 : void monster_strike(pmt m)
385 : : {
386 [ - + ]: 2 : if (player_on_sanctuary())
387 : 0 : print1("The aegis of your deity protects you!");
388 : : else {
389 : : /* being attacked wakes you up/stops fast move */
390 : 2 : resetgamestatus(FAST_MOVE);
391 : :
392 : : /* It's lawful to wait to be attacked */
393 [ + - ]: 2 : if (m->attacked==0) Player.alignment++;
394 : 2 : m->attacked++;
395 : 2 : monster_action(m,m->strikef);
396 : : }
397 : 2 : }
398 : :
399 : 15 : void monster_special(pmt m)
400 : : {
401 : : /* since many special functions are really attacks, cancel them
402 : : all if on sanctuary */
403 [ + - ]: 15 : if (! player_on_sanctuary())
404 : : {
405 : : /* being attacked wakes you up/stops fast move */
406 : 15 : resetgamestatus(FAST_MOVE);
407 : :
408 : 15 : monster_action(m,m->specialf);
409 : : }
410 : 15 : }
411 : :
412 : :
413 : 0 : void monster_talk(pmt m)
414 : : {
415 : 0 : monster_action(m,m->talkf);
416 : 0 : }
417 : :
418 : 153 : void monster_action(pmt m, int action)
419 : : {
420 : : int meleef;
421 [ + + ][ - + ]: 153 : if ((action >= M_MELEE_NORMAL) && (action < M_MOVE_NORMAL)) {
422 : : /* kluge allows multiple attack forms */
423 [ # # ]: 0 : if (distance(m->x,m->y,Player.x,Player.y)<2) {
424 : 0 : meleef = m->meleef;
425 : 0 : m->meleef = action;
426 : 0 : tacmonster(m);
427 : 0 : m->meleef = meleef;
428 : : }
429 : : }
430 [ + - - - : 153 : else switch(action) {
- - + - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- + - - -
- - - - -
- - - - -
- - - - -
- - - -
- ]
431 : :
432 : 11 : case M_NO_OP:m_no_op(m); break;
433 : :
434 : 0 : case M_MOVE_NORMAL:m_normal_move(m); break;
435 : 0 : case M_MOVE_FLUTTER:m_flutter_move(m); break;
436 : 0 : case M_MOVE_FOLLOW:m_follow_move(m); break;
437 : 0 : case M_MOVE_TELEPORT:m_teleport(m); break;
438 : 0 : case M_MOVE_RANDOM:m_random_move(m); break;
439 : 136 : case M_MOVE_SMART:m_smart_move(m); break;
440 : 0 : case M_MOVE_SPIRIT:m_spirit_move(m); break;
441 : 0 : case M_MOVE_CONFUSED:m_confused_move(m); break;
442 : 0 : case M_MOVE_SCAREDY:m_scaredy_move(m); break;
443 : 0 : case M_MOVE_ANIMAL:m_move_animal(m); break;
444 : 0 : case M_MOVE_LEASH:m_move_leash(m); break;
445 : :
446 : 0 : case M_STRIKE_MISSILE:m_nbolt(m); break;
447 : 0 : case M_STRIKE_FBOLT:m_firebolt(m); break;
448 : 0 : case M_STRIKE_LBALL:m_lball(m); break;
449 : 0 : case M_STRIKE_FBALL:m_fireball(m); break;
450 : 0 : case M_STRIKE_SNOWBALL:m_snowball(m); break;
451 : 0 : case M_STRIKE_BLIND:m_blind_strike(m); break;
452 : 0 : case M_STRIKE_SONIC:m_strike_sonic(m); break;
453 : :
454 : 0 : case M_TALK_HORSE:m_talk_horse(m); break;
455 : 0 : case M_TALK_THIEF:m_talk_thief(m);break;
456 : 0 : case M_TALK_STUPID:m_talk_stupid(m); break;
457 : 0 : case M_TALK_SILENT:m_talk_silent(m); break;
458 : 0 : case M_TALK_HUNGRY:m_talk_hungry(m); break;
459 : 0 : case M_TALK_GREEDY:m_talk_greedy(m); break;
460 : 0 : case M_TALK_TITTER:m_talk_titter(m); break;
461 : 0 : case M_TALK_MP:m_talk_mp(m); break;
462 : 0 : case M_TALK_IM:m_talk_im(m); break;
463 : 0 : case M_TALK_MAN:m_talk_man(m); break;
464 : 0 : case M_TALK_ROBOT:m_talk_robot(m); break;
465 : 0 : case M_TALK_EVIL:m_talk_evil(m); break;
466 : 0 : case M_TALK_GUARD:m_talk_guard(m); break;
467 : 0 : case M_TALK_MIMSY:m_talk_mimsy(m); break;
468 : 0 : case M_TALK_SLITHY:m_talk_slithy(m); break;
469 : 0 : case M_TALK_BURBLE:m_talk_burble(m); break;
470 : 0 : case M_TALK_BEG:m_talk_beg(m); break;
471 : 0 : case M_TALK_HINT:m_talk_hint(m); break;
472 : 0 : case M_TALK_EF:m_talk_ef(m); break;
473 : 0 : case M_TALK_GF:m_talk_gf(m); break;
474 : 0 : case M_TALK_SEDUCTOR:m_talk_seductor(m); break;
475 : 0 : case M_TALK_DEMONLOVER:m_talk_demonlover(m); break;
476 : 0 : case M_TALK_NINJA:m_talk_ninja(m); break;
477 : 0 : case M_TALK_ASSASSIN:m_talk_assassin(m); break;
478 : 0 : case M_TALK_SERVANT: m_talk_servant(m); break;
479 : 0 : case M_TALK_ANIMAL: m_talk_animal(m); break;
480 : 0 : case M_TALK_SCREAM: m_talk_scream(m); break;
481 : 0 : case M_TALK_PARROT: m_talk_parrot(m); break;
482 : 0 : case M_TALK_HYENA: m_talk_hyena(m); break;
483 : 0 : case M_TALK_DRUID: m_talk_druid(m); break;
484 : 0 : case M_TALK_ARCHMAGE: m_talk_archmage(m); break;
485 : 0 : case M_TALK_MERCHANT: m_talk_merchant(m); break;
486 : 0 : case M_TALK_PRIME: m_talk_prime(m); break;
487 : 0 : case M_TALK_MAHARAJA: m_talk_maharaja(m); break;
488 : :
489 : 0 : case M_SP_BOG:m_sp_bogthing(m); break;
490 : 0 : case M_SP_WERE:m_sp_were(m); break;
491 : 0 : case M_SP_WHISTLEBLOWER:m_sp_whistleblower(m); break;
492 : 0 : case M_SP_MERCHANT:m_sp_merchant(m); break;
493 : 0 : case M_SP_SURPRISE:m_sp_surprise(m); break;
494 : 0 : case M_SP_MP:m_sp_mp(m); break;
495 : 0 : case M_SP_THIEF:m_thief_f(m); break;
496 : 0 : case M_SP_DEMONLOVER:m_sp_demonlover(m); break;
497 : 0 : case M_SP_AGGRAVATE:m_aggravate(m); break;
498 : 0 : case M_SP_POISON_CLOUD:m_sp_poison_cloud(m); break;
499 : 0 : case M_SP_HUGE:m_huge_sounds(m); break;
500 : 0 : case M_SP_SUMMON:m_summon(m); break;
501 : 6 : case M_SP_ILLUSION:m_illusion(m); break;
502 : 0 : case M_SP_ESCAPE:m_sp_escape(m); break;
503 : 0 : case M_SP_FLUTTER:m_flutter_move(m); break;
504 : 0 : case M_SP_EXPLODE:m_sp_explode(m); break;
505 : 0 : case M_SP_DEMON:m_sp_demon(m); break;
506 : 0 : case M_SP_ACID_CLOUD:m_sp_acid_cloud(m); break;
507 : 0 : case M_SP_GHOST:m_sp_ghost(m); break;
508 : 0 : case M_SP_SPELL:m_sp_spell(m); break;
509 : 0 : case M_SP_SEDUCTOR:m_sp_seductor(m); break;
510 : 0 : case M_SP_EATER:m_sp_eater(m); break;
511 : 0 : case M_SP_DRAGONLORD:m_sp_dragonlord(m); break;
512 : 0 : case M_SP_BLACKOUT:m_sp_blackout(m); break;
513 : 0 : case M_SP_SWARM: m_sp_swarm(m); break;
514 : 0 : case M_SP_ANGEL: m_sp_angel(m); break;
515 : 0 : case M_SP_SERVANT: m_sp_servant(m); break;
516 : 0 : case M_SP_AV: m_sp_av(m); break;
517 : 0 : case M_SP_LW: m_sp_lw(m); break;
518 : 0 : case M_SP_MB: m_sp_mb(m); break;
519 : 0 : case M_SP_RAISE: m_sp_raise(m); break;
520 : 0 : case M_SP_MIRROR: m_sp_mirror(m); break;
521 : 0 : case M_SP_COURT: m_sp_court(m); break;
522 : 0 : case M_SP_LAIR: m_sp_lair(m); break;
523 : 0 : case M_SP_PRIME: m_sp_prime(m); break;
524 : : }
525 : 153 : }
526 : :
527 : : /* makes one of the highscore npcs */
528 : 0 : void make_hiscore_npc(pmt npc, int npcid)
529 : : {
530 : 0 : int st = -1;
531 : : pob ob;
532 : 0 : *npc = Monsters[HISCORE_NPC];
533 : 0 : npc->aux2 = npcid;
534 : : /* each of the high score npcs can be created here */
535 [ # # # # : 0 : switch(npcid) {
# # # # #
# # # # ]
536 : : case 0:
537 : 0 : strcpy(Str2,Hiscorer);
538 : 0 : determine_npc_behavior(npc,Hilevel,Hibehavior);
539 : 0 : break;
540 : : case 1: case 2: case 3: case 4: case 5: case 6:
541 : 0 : strcpy(Str2,Priest[npcid]);
542 : 0 : determine_npc_behavior(npc,Priestlevel[npcid],Priestbehavior[npcid]);
543 : 0 : st = ARTIFACTID+13+npcid; /* appropriate holy symbol... */
544 : 0 : Objects[st].uniqueness = UNIQUE_MADE;
545 [ # # ]: 0 : if (npcid == DRUID)
546 : 0 : npc->talkf = M_TALK_DRUID;
547 [ # # ]: 0 : if (Player.patron == npcid)
548 : 0 : m_status_reset(npc, HOSTILE);
549 : 0 : break;
550 : : case 7:
551 : 0 : strcpy(Str2,Shadowlord);
552 : 0 : determine_npc_behavior(npc,Shadowlordlevel,Shadowlordbehavior);
553 : 0 : break;
554 : : case 8:
555 : 0 : strcpy(Str2,Commandant);
556 : 0 : determine_npc_behavior(npc,Commandantlevel,Commandantbehavior);
557 [ # # ]: 0 : if (Player.rank[LEGION])
558 : 0 : m_status_reset(npc, HOSTILE);
559 : 0 : break;
560 : : case 9:
561 : 0 : strcpy(Str2,Archmage);
562 : 0 : determine_npc_behavior(npc,Archmagelevel,Archmagebehavior);
563 : 0 : st = OB_KOLWYNIA; /* kolwynia */
564 : 0 : npc->talkf = M_TALK_ARCHMAGE;
565 : 0 : m_status_reset(npc, WANDERING);
566 : 0 : m_status_reset(npc, HOSTILE);
567 : 0 : break;
568 : : case 10:
569 : 0 : strcpy(Str2,Prime);
570 : 0 : determine_npc_behavior(npc,Primelevel,Primebehavior);
571 : 0 : npc->talkf = M_TALK_PRIME;
572 : 0 : npc->specialf = M_SP_PRIME;
573 [ # # ]: 0 : if (Player.alignment < 0)
574 : 0 : m_status_reset(npc, HOSTILE);
575 : 0 : break;
576 : : case 11:
577 : 0 : strcpy(Str2,Champion);
578 : 0 : determine_npc_behavior(npc,Championlevel,Championbehavior);
579 [ # # ]: 0 : if (Player.rank[ARENA])
580 : 0 : m_status_reset(npc, HOSTILE);
581 : 0 : break;
582 : : case 12:
583 : 0 : strcpy(Str2,Duke);
584 : 0 : determine_npc_behavior(npc,Dukelevel,Dukebehavior);
585 : 0 : break;
586 : : case 13:
587 : 0 : strcpy(Str2,Chaoslord);
588 : 0 : determine_npc_behavior(npc,Chaoslordlevel,Chaoslordbehavior);
589 [ # # ][ # # ]: 0 : if (Player.alignment < 0 && random_range(2))
590 : 0 : m_status_reset(npc, HOSTILE);
591 : 0 : break;
592 : : case 14:
593 : 0 : strcpy(Str2,Lawlord);
594 : 0 : determine_npc_behavior(npc,Lawlordlevel,Lawlordbehavior);
595 [ # # ]: 0 : if (Player.alignment > 0)
596 : 0 : m_status_reset(npc, HOSTILE);
597 : 0 : break;
598 : : case 15:
599 : 0 : strcpy(Str2,Justiciar);
600 : 0 : determine_npc_behavior(npc,Justiciarlevel,Justiciarbehavior);
601 : 0 : st = OB_JUSTICIAR_BADGE; /* badge */
602 : 0 : npc->talkf = M_TALK_GUARD;
603 : 0 : npc->specialf = M_SP_WHISTLEBLOWER;
604 : 0 : m_status_reset(npc, WANDERING);
605 : 0 : m_status_reset(npc, HOSTILE);
606 : 0 : break;
607 : : case 16: /* PGM TODO */
608 : 0 : strcpy(Str2,Grandmaster);
609 : 0 : determine_npc_behavior(npc,Grandmasterlevel,Grandmasterbehavior);
610 : 0 : break;
611 : : }
612 [ # # ][ # # ]: 0 : if (st > -1 && Objects[st].uniqueness == UNIQUE_MADE) {
613 : 0 : ob = ((pob) checkmalloc(sizeof(objtype)));
614 : 0 : *ob = Objects[st];
615 : 0 : m_pickup(npc,ob);
616 : : }
617 : 0 : npc->monstring = salloc(Str2);
618 : 0 : strcpy(Str1,"The body of ");
619 : 0 : strcat(Str1,Str2);
620 : 0 : npc->corpsestr = salloc(Str1);
621 : 0 : m_status_set( npc, ALLOC );
622 : 0 : }
623 : :
624 : :
625 : : /* sets npc behavior given level and behavior code */
626 : 1 : void determine_npc_behavior(pmt npc, int level, int behavior)
627 : : {
628 : : int combatype,competence,talktype;
629 : 1 : npc->hp = (level+1)*20;
630 : 1 : npc->status = AWAKE+MOBILE+WANDERING;
631 : 1 : combatype = (behavior % 100) / 10;
632 : 1 : competence = (behavior % 1000) / 100;
633 : 1 : talktype = behavior / 1000;
634 : 1 : npc->level = competence;
635 [ - + ]: 1 : if (npc->level < 2*difficulty()) npc->status += HOSTILE;
636 : 1 : npc->xpv = npc->level*20;
637 [ + - - - : 1 : switch (combatype) {
- - ]
638 : : case 1: /* melee */
639 : 1 : npc->meleef = M_MELEE_NORMAL;
640 : 1 : npc->dmg = competence*5;
641 : 1 : npc->hit = competence*3;
642 : 1 : npc->speed = 3;
643 : 1 : break;
644 : : case 2: /*missile*/
645 : 0 : npc->meleef = M_MELEE_NORMAL;
646 : 0 : npc->strikef = M_STRIKE_MISSILE;
647 : 0 : npc->dmg = competence*3;
648 : 0 : npc->hit = competence*2;
649 : 0 : npc->speed = 4;
650 : 0 : break;
651 : : case 3: /* spellcasting */
652 : 0 : npc->meleef = M_MELEE_NORMAL;
653 : 0 : npc->dmg = competence;
654 : 0 : npc->hit = competence;
655 : 0 : npc->specialf = M_SP_SPELL;
656 : 0 : npc->speed = 6;
657 : 0 : break;
658 : : case 4: /* thievery */
659 : 0 : npc->meleef = M_MELEE_NORMAL;
660 : 0 : npc->dmg = competence;
661 : 0 : npc->hit = competence;
662 : 0 : npc->specialf=M_SP_THIEF;
663 : 0 : npc->speed = 3;
664 : 0 : break;
665 : : case 5: /* flee */
666 : 0 : npc->dmg = competence;
667 : 0 : npc->hit = competence;
668 : 0 : npc->meleef = M_MELEE_NORMAL;
669 : 0 : npc->specialf = M_MOVE_SCAREDY;
670 : 0 : npc->speed = 3;
671 : 0 : break;
672 : : }
673 [ - + ]: 1 : if (npc->talkf == M_TALK_MAN)
674 [ # # # # : 0 : switch (talktype) {
# # ]
675 : 0 : case 1: npc->talkf = M_TALK_EVIL; break;
676 : 0 : case 2: npc->talkf = M_TALK_MAN; break;
677 : 0 : case 3: npc->talkf = M_TALK_HINT; break;
678 : 0 : case 4: npc->talkf = M_TALK_BEG; break;
679 : 0 : case 5: npc->talkf = M_TALK_SILENT; break;
680 : 0 : default: mprint("Say Whutt? (npc talk weirdness)"); break;
681 : : }
682 : 1 : npc->uniqueness = UNIQUE_MADE;
683 : 1 : }
684 : :
685 : :
686 : : /* makes an ordinary npc (maybe undead) */
687 : 0 : void make_log_npc(pmt npc)
688 : : {
689 : : int i,n;
690 : : int behavior,status,level;
691 : : FILE *fd;
692 : :
693 : : /* in case the log file is null */
694 : 0 : behavior = 2718;
695 : 0 : level = 1;
696 : 0 : status = 2;
697 : 0 : strcpy(Str2,"Malaprop the Misnamed");
698 : :
699 : 0 : strcpy(Str1,Omegavar);
700 : 0 : strcat(Str1,"omega.log");
701 : 0 : fd = checkfopen(Str1,"r");
702 : 0 : n = 1;
703 [ # # ]: 0 : while(fgets(Str1,STRING_LEN, fd)) {
704 [ # # ]: 0 : if (random_range(n) == 0) { /* this algo. from Knuth 2 - cute, eh? */
705 : 0 : sscanf(Str1,"%d %d %d",&status,&level,&behavior);
706 [ # # ][ # # ]: 0 : for (i = 0; (Str1[i] < 'a' || Str1[i] > 'z') &&
[ # # ]
707 [ # # ]: 0 : (Str1[i] < 'A' || Str1[i] > 'Z'); i++)
708 : : ;
709 : 0 : strcpy(Str2, Str1 + i);
710 : 0 : Str2[strlen(Str2) - 1] = '\0'; /* 'cos fgets reads in the \n */
711 : : }
712 : 0 : n++;
713 : : }
714 : 0 : fclose(fd);
715 : 0 : npc->hp = level*20;
716 [ # # ]: 0 : if (status==1) {
717 [ # # ]: 0 : if (level < 3) {
718 : 0 : *npc = Monsters[GHOST];
719 : 0 : strcpy(Str1,"ghost named ");
720 : : }
721 [ # # ]: 0 : else if (level < 7) {
722 : 0 : *npc = Monsters[HAUNT];
723 : 0 : strcpy(Str1,"haunt named ");
724 : : }
725 [ # # ]: 0 : else if (level < 12) {
726 : 0 : *npc = Monsters[SPECTRE];
727 : 0 : strcpy(Str1,"spectre named ");
728 : : }
729 : : else {
730 : 0 : *npc = Monsters[LICHE];
731 : 0 : strcpy(Str1,"lich named ");
732 : : }
733 : 0 : strcat(Str1,Str2);
734 : 0 : npc->monstring = salloc(Str1);
735 : 0 : strcpy(Str3,"the mortal remains of ");
736 : 0 : strcat(Str3,Str2);
737 : 0 : npc->corpsestr = salloc(Str3);
738 : 0 : m_status_set( npc, ALLOC );
739 : : }
740 : : else {
741 : 0 : npc->monstring=salloc(Str2);
742 : 0 : strcpy(Str3,"the corpse of ");
743 : 0 : strcat(Str3,Str2);
744 : 0 : npc->corpsestr = salloc(Str3);
745 : 0 : m_status_set( npc, ALLOC );
746 : : }
747 : 0 : determine_npc_behavior(npc,level,behavior);
748 : 0 : }
749 : :
750 : :
751 : 0 : void m_trap_dart(pmt m)
752 : : {
753 [ # # ]: 0 : if (los_p(m->x,m->y,Player.x,Player.y)) {
754 [ # # ]: 0 : if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
755 : : else {
756 : 0 : strcpy(Str1,"The ");
757 : 0 : strcat(Str1,m->monstring);
758 : : }
759 : 0 : strcat(Str1," was hit by a dart!");
760 : 0 : mprint(Str1);
761 : 0 : Level->site[m->x][m->y].locchar = TRAP;
762 : 0 : lset(m->x, m->y, CHANGED);
763 : : }
764 : 0 : m_damage(m,difficulty()*2,NORMAL_DAMAGE);
765 : 0 : }
766 : :
767 : 0 : void m_trap_pit(pmt m)
768 : : {
769 [ # # ]: 0 : if (los_p(m->x,m->y,Player.x,Player.y)) {
770 [ # # ]: 0 : if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
771 : : else {
772 : 0 : strcpy(Str1,"The ");
773 : 0 : strcat(Str1,m->monstring);
774 : : }
775 : 0 : strcat(Str1," fell into a pit!");
776 : 0 : mprint(Str1);
777 : 0 : Level->site[m->x][m->y].locchar = TRAP;
778 : 0 : lset(m->x, m->y, CHANGED);
779 : : }
780 [ # # ]: 0 : if (! m_statusp(m,INTANGIBLE))
781 : 0 : m_status_reset(m,MOBILE);
782 : 0 : m_damage(m,difficulty()*5,NORMAL_DAMAGE);
783 : :
784 : 0 : }
785 : :
786 : 0 : void m_trap_door(pmt m)
787 : : {
788 [ # # ]: 0 : if (los_p(m->x,m->y,Player.x,Player.y)) {
789 [ # # ]: 0 : if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
790 : : else {
791 : 0 : strcpy(Str1,"The ");
792 : 0 : strcat(Str1,m->monstring);
793 : : }
794 : 0 : strcat(Str1," fell into a trap door!");
795 : 0 : mprint(Str1);
796 : 0 : Level->site[m->x][m->y].locchar = TRAP;
797 : 0 : lset(m->x, m->y, CHANGED);
798 : : }
799 : 0 : m_vanish(m);
800 : 0 : }
801 : :
802 : 0 : void m_trap_abyss(pmt m)
803 : : {
804 : : char Str1[80];
805 [ # # ]: 0 : if (los_p(m->x,m->y,Player.x,Player.y)) {
806 [ # # ]: 0 : if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
807 : : else {
808 : 0 : strcpy(Str1,"The ");
809 : 0 : strcat(Str1,m->monstring);
810 : : }
811 : 0 : strcat(Str1," fell into the infinite abyss!");
812 : 0 : mprint(Str1);
813 : 0 : Level->site[m->x][m->y].locchar = ABYSS;
814 : 0 : lset(m->x, m->y, CHANGED);
815 : 0 : Level->site[m->x][m->y].p_locf = L_ABYSS;
816 : 0 : lset(m->x, m->y, CHANGED);
817 : : }
818 : 0 : setgamestatus(SUPPRESS_PRINTING);
819 : 0 : m_vanish(m);
820 : 0 : resetgamestatus(SUPPRESS_PRINTING);
821 : 0 : }
822 : :
823 : 0 : void m_trap_snare(pmt m)
824 : : {
825 : : char Str1[80];
826 : 0 : Level->site[m->x][m->y].locchar = TRAP;
827 : 0 : lset(m->x, m->y, CHANGED);
828 [ # # ]: 0 : if (los_p(m->x,m->y,Player.x,Player.y)) {
829 [ # # ]: 0 : if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
830 : : else {
831 : 0 : strcpy(Str1,"The ");
832 : 0 : strcat(Str1,m->monstring);
833 : : }
834 : 0 : strcat(Str1," was caught in a snare!");
835 : 0 : mprint(Str1);
836 : : }
837 [ # # ]: 0 : if (! m_statusp(m,INTANGIBLE)) m_status_reset(m,MOBILE);
838 : 0 : }
839 : :
840 : 0 : void m_trap_blade(pmt m)
841 : : {
842 : : char Str1[80];
843 : 0 : Level->site[m->x][m->y].locchar = TRAP;
844 : 0 : lset(m->x, m->y, CHANGED);
845 [ # # ]: 0 : if (los_p(m->x,m->y,Player.x,Player.y)) {
846 [ # # ]: 0 : if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
847 : : else {
848 : 0 : strcpy(Str1,"The ");
849 : 0 : strcat(Str1,m->monstring);
850 : : }
851 : 0 : strcat(Str1," was hit by a blade trap!");
852 : 0 : mprint(Str1); }
853 : 0 : m_damage(m,(difficulty()+1)*7-Player.defense,NORMAL_DAMAGE);
854 : 0 : }
855 : :
856 : 0 : void m_trap_fire(pmt m)
857 : : {
858 : : char Str1[80];
859 : 0 : Level->site[m->x][m->y].locchar = TRAP;
860 : 0 : lset(m->x, m->y, CHANGED);
861 [ # # ]: 0 : if (los_p(m->x,m->y,Player.x,Player.y)) {
862 [ # # ]: 0 : if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
863 : : else {
864 : 0 : strcpy(Str1,"The ");
865 : 0 : strcat(Str1,m->monstring);
866 : : }
867 : 0 : strcat(Str1," was hit by a fire trap!");
868 : 0 : mprint(Str1);
869 : : }
870 : 0 : m_damage(m,(difficulty()+1)*5,FLAME);
871 : 0 : }
872 : :
873 : :
874 : 0 : void m_fire(pmt m)
875 : : {
876 : : char Str1[80];
877 [ # # ]: 0 : if (los_p(m->x,m->y,Player.x,Player.y)) {
878 [ # # ]: 0 : if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
879 : : else {
880 : 0 : strcpy(Str1,"The ");
881 : 0 : strcat(Str1,m->monstring);
882 : : }
883 : 0 : strcat(Str1," was blasted by fire!");
884 : 0 : mprint(Str1);
885 : : }
886 : 0 : m_damage(m,random_range(100),FLAME);
887 : 0 : }
888 : :
889 : 1 : void m_trap_teleport(pmt m)
890 : : {
891 : : char Str1[80];
892 : 1 : Level->site[m->x][m->y].locchar = TRAP;
893 : 1 : lset(m->x, m->y, CHANGED);
894 [ + - ]: 1 : if (los_p(m->x,m->y,Player.x,Player.y)) {
895 [ - + ]: 1 : if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
896 : : else {
897 : 1 : strcpy(Str1,"The ");
898 : 1 : strcat(Str1,m->monstring);
899 : : }
900 : 1 : strcat(Str1," walked into a teleport trap!");
901 : 1 : mprint(Str1);
902 : : }
903 : 1 : m_teleport(m);
904 : 1 : }
905 : :
906 : 0 : void m_trap_disintegrate(pmt m)
907 : : {
908 : : char Str1[80];
909 [ # # ]: 0 : if (los_p(m->x,m->y,Player.x,Player.y)) {
910 [ # # ]: 0 : if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
911 : : else {
912 : 0 : strcpy(Str1,"The ");
913 : 0 : strcat(Str1,m->monstring);
914 : : }
915 : 0 : strcat(Str1," walked into a disintegration trap!");
916 : 0 : mprint(Str1);
917 : 0 : Level->site[m->x][m->y].locchar = TRAP;
918 : 0 : lset(m->x, m->y, CHANGED);
919 : : }
920 : 0 : disintegrate(m->x,m->y);
921 : 0 : }
922 : :
923 : 0 : void m_trap_sleepgas(pmt m)
924 : : {
925 : : char Str1[80];
926 [ # # ]: 0 : if (los_p(m->x,m->y,Player.x,Player.y)) {
927 [ # # ]: 0 : if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
928 : : else {
929 : 0 : strcpy(Str1,"The ");
930 : 0 : strcat(Str1,m->monstring);
931 : : }
932 : 0 : strcat(Str1," walked into a sleepgas trap!");
933 : 0 : mprint(Str1);
934 : 0 : Level->site[m->x][m->y].locchar = TRAP;
935 : 0 : lset(m->x, m->y, CHANGED);
936 : : }
937 [ # # ]: 0 : if (! m_immunityp(m,SLEEP)) m_status_reset(m,AWAKE);
938 : 0 : }
939 : :
940 : 0 : void m_trap_acid(pmt m)
941 : : {
942 : : char Str1[80];
943 [ # # ]: 0 : if (los_p(m->x,m->y,Player.x,Player.y)) {
944 [ # # ]: 0 : if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
945 : : else {
946 : 0 : strcpy(Str1,"The ");
947 : 0 : strcat(Str1,m->monstring);
948 : : }
949 : 0 : strcat(Str1," walked into an acid bath trap!");
950 : 0 : mprint(Str1);
951 : 0 : Level->site[m->x][m->y].locchar = TRAP;
952 : 0 : lset(m->x, m->y, CHANGED);
953 : : }
954 : 0 : m_damage(m,random_range(difficulty()*difficulty()),ACID);
955 : 0 : }
956 : :
957 : 0 : void m_trap_manadrain(pmt m)
958 : : {
959 : : char Str1[80];
960 [ # # ]: 0 : if (los_p(m->x,m->y,Player.x,Player.y)) {
961 [ # # ]: 0 : if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
962 : : else {
963 : 0 : strcpy(Str1,"The ");
964 : 0 : strcat(Str1,m->monstring);
965 : : }
966 : 0 : strcat(Str1," walked into a manadrain trap!");
967 : 0 : mprint(Str1);
968 : 0 : Level->site[m->x][m->y].locchar = TRAP;
969 : 0 : lset(m->x, m->y, CHANGED);
970 : : }
971 [ # # ]: 0 : if (m->specialf == M_SP_SPELL) m->specialf = M_NO_OP;
972 : 0 : }
973 : :
974 : :
975 : 0 : void m_water(pmt m)
976 : : {
977 : : char Str1[80];
978 [ # # ][ # # ]: 0 : if ((! m_statusp(m,INTANGIBLE)) &&
979 [ # # ]: 0 : (! m_statusp(m,SWIMMING)) &&
980 : 0 : (! m_statusp(m,ONLYSWIM))) {
981 [ # # ]: 0 : if (los_p(m->x,m->y,Player.x,Player.y)) {
982 [ # # ]: 0 : if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
983 : : else {
984 : 0 : strcpy(Str1,"The ");
985 : 0 : strcat(Str1,m->monstring);
986 : : }
987 : 0 : strcat(Str1," drowned!");
988 : 0 : mprint(Str1);
989 : : }
990 : 0 : m_death(m);
991 : : }
992 : 0 : }
993 : :
994 : :
995 : 0 : void m_abyss(pmt m)
996 : : {
997 : : char Str1[80];
998 [ # # ]: 0 : if (los_p(m->x,m->y,Player.x,Player.y)) {
999 [ # # ]: 0 : if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
1000 : : else {
1001 : 0 : strcpy(Str1,"The ");
1002 : 0 : strcat(Str1,m->monstring);
1003 : : }
1004 : 0 : strcat(Str1," fell into the infinite abyss!");
1005 : 0 : mprint(Str1);
1006 : : }
1007 : 0 : m_vanish(m);
1008 : 0 : }
1009 : :
1010 : :
1011 : 0 : void m_lava(pmt m)
1012 : : {
1013 : : char Str1[80];
1014 [ # # ][ # # ]: 0 : if ((! m_immunityp(m,FLAME)) ||
1015 [ # # ]: 0 : ((! m_statusp(m,SWIMMING))&& (! m_statusp(m,ONLYSWIM)))) {
1016 [ # # ]: 0 : if (los_p(m->x,m->y,Player.x,Player.y)) {
1017 [ # # ]: 0 : if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
1018 : : else {
1019 : 0 : strcpy(Str1,"The ");
1020 : 0 : strcat(Str1,m->monstring);
1021 : : }
1022 : 0 : strcat(Str1," died in a pool of lava!");
1023 : 0 : mprint(Str1);
1024 : : }
1025 : 0 : m_death(m);
1026 : : }
1027 : 0 : }
1028 : :
1029 : 0 : void m_altar(pmt m)
1030 : : {
1031 : 0 : int visible = view_los_p(Player.x,Player.y,m->x,m->y);
1032 : 0 : int reaction = 0;
1033 : 0 : int altar = Level->site[m->x][m->y].aux;
1034 : :
1035 [ # # ]: 0 : if (visible) {
1036 [ # # ]: 0 : if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
1037 : : else {
1038 : 0 : strcpy(Str1,"The ");
1039 : 0 : strcat(Str1,m->monstring);
1040 : : }
1041 : 0 : strcat(Str1," walks next to an altar...");
1042 : 0 : mprint(Str1);
1043 : : }
1044 [ # # ]: 0 : if (!m_statusp(m, HOSTILE))
1045 : 0 : reaction = 0;
1046 [ # # ][ # # ]: 0 : else if (m->id == HISCORE_NPC && m->aux2 == altar)
1047 : 0 : reaction = 1; /* high priest of same deity */
1048 [ # # ][ # # ]: 0 : else if ((m->id == ANGEL || m->id == HIGH_ANGEL || m->id == ARCHANGEL) &&
[ # # ][ # # ]
1049 : 0 : m->aux1 == altar)
1050 : 0 : reaction = 1; /* angel of same deity */
1051 [ # # ]: 0 : else if (altar == Player.patron)
1052 : 0 : reaction = -1; /* friendly deity will zap hostile monster */
1053 [ # # ][ # # ]: 0 : else if (((Player.patron == ODIN || Player.patron == ATHENA) &&
[ # # ]
1054 [ # # ][ # # ]: 0 : (altar == SET || altar == HECATE)) ||
1055 [ # # ][ # # ]: 0 : ((Player.patron == SET || Player.patron == HECATE) &&
1056 [ # # ]: 0 : (altar == ODIN || altar == ATHENA)))
1057 : 0 : reaction = 1; /* hostile deity will help hostile monster */
1058 [ # # # ]: 0 : switch (reaction) {
1059 : : case -1:
1060 [ # # ]: 0 : if (visible) {
1061 : 0 : mprint("Your deity is angry!");
1062 : 0 : mprint("A bolt of godsfire strikes the monster....");
1063 : : }
1064 : 0 : disrupt(m->x,m->y,Player.rank[PRIESTHOOD]*50);
1065 : 0 : break;
1066 : : case 1:
1067 [ # # ]: 0 : if (visible) {
1068 : 0 : mprint("The deity of the altar smiles on the monster....");
1069 : 0 : mprint("A shaft of light zaps the altar...");
1070 : : }
1071 : 0 : m->hp = Monsters[m->id].hp*2;
1072 : 0 : break;
1073 : : default:
1074 [ # # ]: 0 : if (visible)
1075 : 0 : mprint("but nothing much seems to happen");
1076 : 0 : break;
1077 : : }
1078 : 0 : }
1079 : :
1080 : 0 : char *mancorpse(void)
1081 : : {
1082 [ # # # # : 0 : switch(random_range(20)) {
# # # # #
# # # # #
# # # # #
# ]
1083 : 0 : case 0: return "dead janitor";
1084 : 0 : case 1: return "dead beggar";
1085 : 0 : case 2: return "dead barbarian";
1086 : 0 : case 3: return "dead hairdresser";
1087 : 0 : case 4: return "dead accountant";
1088 : 0 : case 5: return "dead lawyer";
1089 : 0 : case 6: return "dead indian chief";
1090 : 0 : case 7: return "dead tinker";
1091 : 0 : case 8: return "dead tailor";
1092 : 0 : case 9: return "dead soldier";
1093 : 0 : case 10: return "dead spy";
1094 : 0 : case 11: return "dead doctor";
1095 : 0 : case 12: return "dead miner";
1096 : 0 : case 13: return "dead noble";
1097 : 0 : case 14: return "dead serf";
1098 : 0 : case 15: return "dead neer-do-well";
1099 : 0 : case 16: return "dead vendor";
1100 : 0 : case 17: return "dead dilettante";
1101 : 0 : case 18: return "dead surveyor";
1102 : : default:
1103 : 0 : case 19: return "dead jongleur";
1104 : : }
1105 : : }
1106 : :
1107 : 0 : char *angeltype(int mid, int deity)
1108 : : {
1109 [ # # ]: 0 : if (ANGEL == mid )
1110 : : {
1111 [ # # # # : 0 : switch (deity)
# # # ]
1112 : : {
1113 : 0 : case ODIN: return "angel of Odin";break;
1114 : 0 : case SET: return "angel of Set";break;
1115 : 0 : case HECATE: return "angel of Hecate";break;
1116 : 0 : case ATHENA: return "angel of Athena";break;
1117 : 0 : case DESTINY: return "angel of Destiny";break;
1118 : 0 : case DRUID: return "angel of the Balance";break;
1119 : : }
1120 : : }
1121 [ # # ]: 0 : else if (HIGH_ANGEL == mid )
1122 : : {
1123 [ # # # # : 0 : switch (deity)
# # # ]
1124 : : {
1125 : 0 : case ODIN: return "high angel of Odin";break;
1126 : 0 : case SET: return "high angel of Set";break;
1127 : 0 : case HECATE: return "high angel of Hecate";break;
1128 : 0 : case ATHENA: return "high angel of Athena";break;
1129 : 0 : case DESTINY: return "high angel of Destiny";break;
1130 : 0 : case DRUID: return "high angel of the Balance";break;
1131 : : }
1132 : : }
1133 : : else /* ARCHANGEL */
1134 : : {
1135 [ # # # # : 0 : switch (deity)
# # # ]
1136 : : {
1137 : 0 : case ODIN: return "archangel of Odin";break;
1138 : 0 : case SET: return "archangel of Set";break;
1139 : 0 : case HECATE: return "archangel of Hecate";break;
1140 : 0 : case ATHENA: return "archangel of Athena";break;
1141 : 0 : case DESTINY: return "archangel of Destiny";break;
1142 : 0 : case DRUID: return "archangel of the Balance";break;
1143 : : }
1144 : : }
1145 : : /* And, if none of those work, this function's broken -- I'm gonna die. */
1146 : 0 : return "angel of Death";
1147 : : }
1148 : :
1149 : 0 : void strengthen_death(pmt m)
1150 : : {
1151 : 0 : pol ol = ((pol)checkmalloc(sizeof(oltype)));
1152 : 0 : pob scythe = ((pob)checkmalloc(sizeof(objtype)));
1153 : : #ifdef MSDOS_SUPPORTED_ANTIQUE
1154 : : unsigned tmp;
1155 : : #endif
1156 : 0 : m->xpv += min(10000,m->xpv+1000);
1157 : 0 : m->hit += min(1000,m->hit+10);
1158 : 0 : m->dmg = min(10000,m->dmg*2);
1159 : 0 : m->ac += min(1000,m->ac+10);
1160 : 0 : m->speed = max(m->speed-1,1);
1161 : 0 : m->movef = M_MOVE_SMART;
1162 : : #ifndef MSDOS_SUPPORTED_ANTIQUE
1163 : 0 : m->hp = min(100000,100+m->dmg*10);
1164 : : #else
1165 : : /* In order not to have to make the hp's into longs or unsigned,
1166 : : which would involve lots of changes, I'll make it max out at 30000. */
1167 : : tmp = 100+m->dmg*10;
1168 : : m->hp = (tmp > 30000) ? 30000 : tmp;
1169 : : #endif
1170 : 0 : *scythe = Objects[OB_SCYTHE_DEATH];
1171 : 0 : ol->thing = scythe;
1172 : 0 : ol->next = NULL;
1173 : 0 : m->possessions = ol;
1174 : 0 : }
1175 : :
1176 : :
1177 : 110 : void m_no_op(pmt m)
1178 : : {
1179 : 110 : }
|