|
|
1.1 root 1: /*
2: * special_hit.c
3: *
4: * This source herein may be modified and/or distributed by anybody who
5: * so desires, with the following restrictions:
6: * 1.) No portion of this notice shall be removed.
7: * 2.) Credit shall not be taken for the creation of this source.
8: * 3.) This code is not to be traded, sold, or used for personal
9: * gain or profit.
10: *
11: */
12:
13: #ifndef lint
14: static char sccsid[] = "@(#)spec_hit.c 5.1 (Berkeley) 11/25/87";
15: #endif /* not lint */
16:
17: #include "rogue.h"
18:
19: short less_hp = 0;
20: boolean being_held;
21:
22: extern short cur_level, max_level, blind, levitate, ring_exp;
23: extern long level_points[];
24: extern boolean detect_monster, mon_disappeared;
25: extern boolean sustain_strength, maintain_armor;
26: extern char *you_can_move_again;
27:
28: special_hit(monster)
29: object *monster;
30: {
31: if ((monster->m_flags & CONFUSED) && rand_percent(66)) {
32: return;
33: }
34: if (monster->m_flags & RUSTS) {
35: rust(monster);
36: }
37: if ((monster->m_flags & HOLDS) && !levitate) {
38: being_held = 1;
39: }
40: if (monster->m_flags & FREEZES) {
41: freeze(monster);
42: }
43: if (monster->m_flags & STINGS) {
44: sting(monster);
45: }
46: if (monster->m_flags & DRAINS_LIFE) {
47: drain_life();
48: }
49: if (monster->m_flags & DROPS_LEVEL) {
50: drop_level();
51: }
52: if (monster->m_flags & STEALS_GOLD) {
53: steal_gold(monster);
54: } else if (monster->m_flags & STEALS_ITEM) {
55: steal_item(monster);
56: }
57: }
58:
59: rust(monster)
60: object *monster;
61: {
62: if ((!rogue.armor) || (get_armor_class(rogue.armor) <= 1) ||
63: (rogue.armor->which_kind == LEATHER)) {
64: return;
65: }
66: if ((rogue.armor->is_protected) || maintain_armor) {
67: if (monster && (!(monster->m_flags & RUST_VANISHED))) {
68: message("the rust vanishes instantly", 0);
69: monster->m_flags |= RUST_VANISHED;
70: }
71: } else {
72: rogue.armor->d_enchant--;
73: message("your armor weakens", 0);
74: print_stats(STAT_ARMOR);
75: }
76: }
77:
78: freeze(monster)
79: object *monster;
80: {
81: short freeze_percent = 99;
82: short i, n;
83:
84: if (rand_percent(12)) {
85: return;
86: }
87: freeze_percent -= (rogue.str_current+(rogue.str_current / 2));
88: freeze_percent -= ((rogue.exp + ring_exp) * 4);
89: freeze_percent -= (get_armor_class(rogue.armor) * 5);
90: freeze_percent -= (rogue.hp_max / 3);
91:
92: if (freeze_percent > 10) {
93: monster->m_flags |= FREEZING_ROGUE;
94: message("you are frozen", 1);
95:
96: n = get_rand(4, 8);
97: for (i = 0; i < n; i++) {
98: mv_mons();
99: }
100: if (rand_percent(freeze_percent)) {
101: for (i = 0; i < 50; i++) {
102: mv_mons();
103: }
104: killed_by((object *)0, HYPOTHERMIA);
105: }
106: message(you_can_move_again, 1);
107: monster->m_flags &= (~FREEZING_ROGUE);
108: }
109: }
110:
111: steal_gold(monster)
112: object *monster;
113: {
114: int amount;
115:
116: if ((rogue.gold <= 0) || rand_percent(10)) {
117: return;
118: }
119:
120: amount = get_rand((cur_level * 10), (cur_level * 30));
121:
122: if (amount > rogue.gold) {
123: amount = rogue.gold;
124: }
125: rogue.gold -= amount;
126: message("your purse feels lighter", 0);
127: print_stats(STAT_GOLD);
128: disappear(monster);
129: }
130:
131: steal_item(monster)
132: object *monster;
133: {
134: object *obj;
135: short i, n, t;
136: char desc[80];
137: boolean has_something = 0;
138:
139: if (rand_percent(15)) {
140: return;
141: }
142: obj = rogue.pack.next_object;
143:
144: if (!obj) {
145: goto DSPR;
146: }
147: while (obj) {
148: if (!(obj->in_use_flags & BEING_USED)) {
149: has_something = 1;
150: break;
151: }
152: obj = obj->next_object;
153: }
154: if (!has_something) {
155: goto DSPR;
156: }
157: n = get_rand(0, MAX_PACK_COUNT);
158: obj = rogue.pack.next_object;
159:
160: for (i = 0; i <= n; i++) {
161: obj = obj->next_object;
162: while ((!obj) || (obj->in_use_flags & BEING_USED)) {
163: if (!obj) {
164: obj = rogue.pack.next_object;
165: } else {
166: obj = obj->next_object;
167: }
168: }
169: }
170: (void) strcpy(desc, "she stole ");
171: if (obj->what_is != WEAPON) {
172: t = obj->quantity;
173: obj->quantity = 1;
174: }
175: get_desc(obj, desc+10);
176: message(desc, 0);
177:
178: obj->quantity = ((obj->what_is != WEAPON) ? t : 1);
179:
180: vanish(obj, 0, &rogue.pack);
181: DSPR:
182: disappear(monster);
183: }
184:
185: disappear(monster)
186: object *monster;
187: {
188: short row, col;
189:
190: row = monster->row;
191: col = monster->col;
192:
193: dungeon[row][col] &= ~MONSTER;
194: if (rogue_can_see(row, col)) {
195: mvaddch(row, col, get_dungeon_char(row, col));
196: }
197: take_from_pack(monster, &level_monsters);
198: free_object(monster);
199: mon_disappeared = 1;
200: }
201:
202: cough_up(monster)
203: object *monster;
204: {
205: object *obj;
206: short row, col, i, n;
207:
208: if (cur_level < max_level) {
209: return;
210: }
211:
212: if (monster->m_flags & STEALS_GOLD) {
213: obj = alloc_object();
214: obj->what_is = GOLD;
215: obj->quantity = get_rand((cur_level * 15), (cur_level * 30));
216: } else {
217: if (!rand_percent((int) monster->drop_percent)) {
218: return;
219: }
220: obj = gr_object();
221: }
222: row = monster->row;
223: col = monster->col;
224:
225: for (n = 0; n <= 5; n++) {
226: for (i = -n; i <= n; i++) {
227: if (try_to_cough(row+n, col+i, obj)) {
228: return;
229: }
230: if (try_to_cough(row-n, col+i, obj)) {
231: return;
232: }
233: }
234: for (i = -n; i <= n; i++) {
235: if (try_to_cough(row+i, col-n, obj)) {
236: return;
237: }
238: if (try_to_cough(row+i, col+n, obj)) {
239: return;
240: }
241: }
242: }
243: free_object(obj);
244: }
245:
246: try_to_cough(row, col, obj)
247: short row, col;
248: object *obj;
249: {
250: if ((row < MIN_ROW) || (row > (DROWS-2)) || (col < 0) || (col>(DCOLS-1))) {
251: return(0);
252: }
253: if ((!(dungeon[row][col] & (OBJECT | STAIRS | TRAP))) &&
254: (dungeon[row][col] & (TUNNEL | FLOOR | DOOR))) {
255: place_at(obj, row, col);
256: if (((row != rogue.row) || (col != rogue.col)) &&
257: (!(dungeon[row][col] & MONSTER))) {
258: mvaddch(row, col, get_dungeon_char(row, col));
259: }
260: return(1);
261: }
262: return(0);
263: }
264:
265: seek_gold(monster)
266: object *monster;
267: {
268: short i, j, rn, s;
269:
270: if ((rn = get_room_number(monster->row, monster->col)) < 0) {
271: return(0);
272: }
273: for (i = rooms[rn].top_row+1; i < rooms[rn].bottom_row; i++) {
274: for (j = rooms[rn].left_col+1; j < rooms[rn].right_col; j++) {
275: if ((gold_at(i, j)) && !(dungeon[i][j] & MONSTER)) {
276: monster->m_flags |= CAN_FLIT;
277: s = mon_can_go(monster, i, j);
278: monster->m_flags &= (~CAN_FLIT);
279: if (s) {
280: move_mon_to(monster, i, j);
281: monster->m_flags |= ASLEEP;
282: monster->m_flags &= (~(WAKENS | SEEKS_GOLD));
283: return(1);
284: }
285: monster->m_flags &= (~SEEKS_GOLD);
286: monster->m_flags |= CAN_FLIT;
287: mv_1_monster(monster, i, j);
288: monster->m_flags &= (~CAN_FLIT);
289: monster->m_flags |= SEEKS_GOLD;
290: return(1);
291: }
292: }
293: }
294: return(0);
295: }
296:
297: gold_at(row, col)
298: short row, col;
299: {
300: if (dungeon[row][col] & OBJECT) {
301: object *obj;
302:
303: if ((obj = object_at(&level_objects, row, col)) &&
304: (obj->what_is == GOLD)) {
305: return(1);
306: }
307: }
308: return(0);
309: }
310:
311: check_gold_seeker(monster)
312: object *monster;
313: {
314: monster->m_flags &= (~SEEKS_GOLD);
315: }
316:
317: check_imitator(monster)
318: object *monster;
319: {
320: char msg[80];
321:
322: if (monster->m_flags & IMITATES) {
323: wake_up(monster);
324: if (!blind) {
325: mvaddch(monster->row, monster->col,
326: get_dungeon_char(monster->row, monster->col));
327: check_message();
328: sprintf(msg, "wait, that's a %s!", mon_name(monster));
329: message(msg, 1);
330: }
331: return(1);
332: }
333: return(0);
334: }
335:
336: imitating(row, col)
337: register short row, col;
338: {
339: if (dungeon[row][col] & MONSTER) {
340: object *object_at(), *monster;
341:
342: if (monster = object_at(&level_monsters, row, col)) {
343: if (monster->m_flags & IMITATES) {
344: return(1);
345: }
346: }
347: }
348: return(0);
349: }
350:
351: sting(monster)
352: object *monster;
353: {
354: short sting_chance = 35;
355: char msg[80];
356:
357: if ((rogue.str_current <= 3) || sustain_strength) {
358: return;
359: }
360: sting_chance += (6 * (6 - get_armor_class(rogue.armor)));
361:
362: if ((rogue.exp + ring_exp) > 8) {
363: sting_chance -= (6 * ((rogue.exp + ring_exp) - 8));
364: }
365: if (rand_percent(sting_chance)) {
366: sprintf(msg, "the %s's bite has weakened you",
367: mon_name(monster));
368: message(msg, 0);
369: rogue.str_current--;
370: print_stats(STAT_STRENGTH);
371: }
372: }
373:
374: drop_level()
375: {
376: int hp;
377:
378: if (rand_percent(80) || (rogue.exp <= 5)) {
379: return;
380: }
381: rogue.exp_points = level_points[rogue.exp-2] - get_rand(9, 29);
382: rogue.exp -= 2;
383: hp = hp_raise();
384: if ((rogue.hp_current -= hp) <= 0) {
385: rogue.hp_current = 1;
386: }
387: if ((rogue.hp_max -= hp) <= 0) {
388: rogue.hp_max = 1;
389: }
390: add_exp(1, 0);
391: }
392:
393: drain_life()
394: {
395: short n;
396:
397: if (rand_percent(60) || (rogue.hp_max <= 30) || (rogue.hp_current < 10)) {
398: return;
399: }
400: n = get_rand(1, 3); /* 1 Hp, 2 Str, 3 both */
401:
402: if ((n != 2) || (!sustain_strength)) {
403: message("you feel weaker", 0);
404: }
405: if (n != 2) {
406: rogue.hp_max--;
407: rogue.hp_current--;
408: less_hp++;
409: }
410: if (n != 1) {
411: if ((rogue.str_current > 3) && (!sustain_strength)) {
412: rogue.str_current--;
413: if (coin_toss()) {
414: rogue.str_max--;
415: }
416: }
417: }
418: print_stats((STAT_STRENGTH | STAT_HP));
419: }
420:
421: m_confuse(monster)
422: object *monster;
423: {
424: char msg[80];
425:
426: if (!rogue_can_see(monster->row, monster->col)) {
427: return(0);
428: }
429: if (rand_percent(45)) {
430: monster->m_flags &= (~CONFUSES); /* will not confuse the rogue */
431: return(0);
432: }
433: if (rand_percent(55)) {
434: monster->m_flags &= (~CONFUSES);
435: sprintf(msg, "the gaze of the %s has confused you", mon_name(monster));
436: message(msg, 1);
437: cnfs();
438: return(1);
439: }
440: return(0);
441: }
442:
443: flame_broil(monster)
444: object *monster;
445: {
446: short row, col, dir;
447:
448: if ((!mon_sees(monster, rogue.row, rogue.col)) || coin_toss()) {
449: return(0);
450: }
451: row = rogue.row - monster->row;
452: col = rogue.col - monster->col;
453: if (row < 0) {
454: row = -row;
455: }
456: if (col < 0) {
457: col = -col;
458: }
459: if (((row != 0) && (col != 0) && (row != col)) ||
460: ((row > 7) || (col > 7))) {
461: return(0);
462: }
463: dir = get_dir(monster->row, monster->col, row, col);
464: bounce(FIRE, dir, monster->row, monster->col, 0);
465:
466: return(1);
467: }
468:
469: get_dir(srow, scol, drow, dcol)
470: short srow, scol, drow, dcol;
471: {
472: if (srow == drow) {
473: if (scol < dcol) {
474: return(RIGHT);
475: } else {
476: return(LEFT);
477: }
478: }
479: if (scol == dcol) {
480: if (srow < drow) {
481: return(DOWN);
482: } else {
483: return(UPWARD);
484: }
485: }
486: if ((srow > drow) && (scol > dcol)) {
487: return(UPLEFT);
488: }
489: if ((srow < drow) && (scol < dcol)) {
490: return(DOWNRIGHT);
491: }
492: if ((srow < drow) && (scol > dcol)) {
493: return(DOWNLEFT);
494: }
495: /*if ((srow > drow) && (scol < dcol)) {*/
496: return(UPRIGHT);
497: /*}*/
498: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.