comparison urogue/fight.c @ 256:c495a4f288c6

Import UltraRogue from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 31 Jan 2017 19:56:04 -0500
parents
children 317166b49d8a
comparison
equal deleted inserted replaced
253:d9badb9c0179 256:c495a4f288c6
1 /*
2 fight.c - All the fighting gets done here
3
4 UltraRogue: The Ultimate Adventure in the Dungeons of Doom
5 Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
6 All rights reserved.
7
8 Based on "Advanced Rogue"
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
10 All rights reserved.
11
12 Based on "Rogue: Exploring the Dungeons of Doom"
13 Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
14 All rights reserved.
15
16 See the file LICENSE.TXT for full copyright and licensing information.
17 */
18
19 #include <stdlib.h>
20 #include <string.h>
21 #include <ctype.h>
22 #include "rogue.h"
23
24 /*
25 * This are the beginning experience levels for all players all further
26 * experience levels are computed by multiplying by 2
27 */
28
29 static long e_levels[10] =
30 {
31 143L, /* Fighter */
32 182L, /* Paladin */
33 169L, /* Ranger */
34 127L, /* Cleric */
35 154L, /* Druid */
36 185L, /* Magician */
37 169L, /* Illusionist */
38 112L, /* Thief */
39 126L, /* Assasin */
40 319L /* Ninja */
41 };
42
43 static struct matrix att_mat[11] =
44 {
45 /* Base, Max_lvl, Factor, Offset, Range */
46
47 { 10, 17, 2, 1, 2 }, /* fi */
48 { 10, 17, 2, 1, 2 }, /* pa */
49 { 10, 17, 2, 1, 2 }, /* ra */
50 { 10, 19, 2, 1, 3 }, /* cl */
51 { 10, 19, 2, 1, 3 }, /* dr */
52 { 9, 21, 2, 1, 5 }, /* mu */
53 { 9, 21, 2, 1, 5 }, /* il */
54 { 10, 21, 2, 1, 4 }, /* th */
55 { 10, 21, 2, 1, 4 }, /* as */
56 { 10, 21, 2, 1, 4 }, /* nj */
57 { 7, 25, 1, 0, 2 } /* mn */
58 };
59
60 void
61 do_fight(coord dir, int tothedeath)
62 {
63 int x,y;
64
65 x = dir.x;
66 y = dir.y;
67
68 if (!tothedeath && pstats.s_hpt < max_stats.s_hpt / 3)
69 {
70 msg("That's not wise.");
71
72 after = fighting = FALSE;
73 return;
74 }
75
76 if (isalpha(CCHAR(winat(hero.y + y, hero.x + x))))
77 {
78 after = fighting = TRUE;
79 do_move(y, x);
80 }
81 else
82 {
83 if (fighting == FALSE)
84 msg("Nothing there.");
85
86 after = fighting = FALSE;
87 }
88
89 return;
90 }
91
92 /*
93 fight()
94 The player attacks the monster.
95 */
96
97 int
98 fight(coord *mp, struct object *weap, int thrown)
99 {
100 struct thing *tp;
101 struct linked_list *item;
102 int did_hit = TRUE;
103 char *mname;
104
105 /* Find the monster we want to fight */
106
107 if ((item = find_mons(mp->y, mp->x)) == NULL)
108 {
109 debug("Fight what @ %d,%d", mp->y, mp->x);
110 return 0;
111 }
112
113 tp = THINGPTR(item);
114
115 mname = (on(player, ISBLIND)) ? "it" : monsters[tp->t_index].m_name;
116
117 /* Since we are fighting, things are not quiet so no healing takes place */
118
119 player.t_rest_hpt = player.t_rest_pow = 0;
120 tp->t_rest_hpt = tp->t_rest_pow = 0;
121
122 /* Let him know it was really a mimic (if it was one). */
123
124 if (off(player, ISBLIND))
125 {
126 if (on(*tp, ISDISGUISE) && (tp->t_type != tp->t_disguise))
127 {
128 msg("Wait! That's a %s!", mname);
129 turn_off(*tp, ISDISGUISE);
130 did_hit = thrown;
131 }
132
133 if (on(*tp, CANSURPRISE))
134 {
135 turn_off(*tp, CANSURPRISE);
136 if ((player.t_ctype == C_RANGER && rnd(6) != 0) ||
137 (player.t_ctype == C_NINJA && rnd(pstats.s_lvl / 2)
138 != 0))
139 msg("You notice a %s trying to hide!", mname);
140 else
141 {
142 msg("Wait! There's a %s!", mname);
143 did_hit = thrown;
144 }
145 }
146 }
147
148 /* Protection from Normal Missiles */
149
150 if (thrown && on(*tp, HASMSHIELD))
151 {
152 msg("The %s slows as it approaches %s.",
153 weaps[weap->o_which].w_name, mname);
154
155 did_hit = FALSE;
156 }
157
158 if (did_hit)
159 {
160 did_hit = FALSE;
161
162 if (!can_blink(tp) &&
163 (off(*tp, MAGICHIT) || (weap != NULL &&
164 (weap->o_hplus > 0 || weap->o_dplus > 0))) &&
165 (off(*tp, BMAGICHIT) || (weap != NULL &&
166 (weap->o_hplus > 2 || weap->o_dplus > 2))) &&
167 roll_em(&player, tp, weap, thrown, cur_weapon))
168 {
169 did_hit = TRUE;
170 tp->t_wasshot = TRUE;
171
172 if (thrown)
173 {
174 if (weap != NULL && weap->o_type == WEAPON
175 && weap->o_which == GRENADE)
176 {
177 hearmsg("BOOOM!");
178 aggravate();
179 }
180
181 thunk(weap, mname);
182 }
183 else
184 hit(mname);
185
186 /* hitting a friendly monster is curtains */
187
188 if (on(*tp, ISFRIENDLY))
189 {
190 turn_off(*tp, ISFRIENDLY);
191 turn_on(*tp, ISMEAN);
192 }
193
194 /* Charmed monsters become uncharmed */
195
196 if (on(*tp, ISCHARMED))
197 {
198 turn_off(*tp, ISCHARMED);
199 turn_on(*tp, ISMEAN);
200 }
201
202 /*
203 * If the player hit a rust monster, he better have a
204 * + weapon
205 */
206
207 if (on(*tp, CANRUST))
208 {
209 if (!thrown && (weap != NULL) &&
210 (weap->o_flags & ISMETAL) &&
211 !(weap->o_flags & ISPROT) &&
212 !(weap->o_flags & ISSILVER) &&
213 (weap->o_hplus < 1) && (weap->o_dplus < 1))
214 {
215 if (rnd(100) < 50)
216 weap->o_hplus--;
217 else
218 weap->o_dplus--;
219
220 msg("Your %s weakens!", weaps[weap->o_which].w_name);
221 }
222 else if (!thrown && weap != NULL && (weap->o_flags & ISMETAL))
223 msg("The rust vanishes from your %s!",
224 weaps[weap->o_which].w_name);
225 }
226
227 /* flammable monsters die from burning weapons */
228
229 if (thrown && on(*tp, CANBBURN) &&
230 (weap->o_flags & CANBURN) &&
231 !save_throw(VS_WAND, tp))
232 {
233 msg("The %s vanishes in a ball of flame.",
234 monsters[tp->t_index].m_name);
235
236 tp->t_stats.s_hpt = 0;
237 }
238
239 /* spores explode and infest hero */
240
241 if (on(*tp, CANSPORE))
242 {
243 msg("The %s explodes in a cloud of dust.",
244 monsters[tp->t_index].m_name);
245
246 if (is_wearing(R_HEALTH) ||
247 player.t_ctype == C_PALADIN ||
248 (player.t_ctype == C_NINJA && pstats.s_lvl
249 > 6) ||
250 thrown && rnd(50) > 0 ||
251 rnd(20) > 0)
252 {
253 msg("The dust makes it hard to breath.");
254 }
255 else
256 {
257 msg("You have contracted a parasitic infestation!");
258
259 infest_dam++;
260 turn_on(player, HASINFEST);
261 }
262
263 tp->t_stats.s_hpt = 0;
264 }
265
266 /* fireproof monsters laugh at you when burning weapon hits */
267
268 if (thrown && on(*tp, NOFIRE) && (weap->o_flags & CANBURN))
269 msg("The %s laughs as the %s bounces.",
270 monsters[tp->t_index].m_name,
271 weaps[weap->o_which].w_name);
272
273 /* sharp weapons have no effect on NOSHARP monsters */
274
275 if (on(*tp, NOSHARP) && (weap != NULL) &&
276 (weap->o_flags & ISSHARP))
277 {
278 msg("The %s has no effect on the %s!",
279 weaps[weap->o_which].w_name,
280 monsters[tp->t_index].m_name);
281
282 fighting = FALSE;
283 }
284
285 /* metal weapons pass through NOMETAL monsters */
286
287 if (on(*tp, NOMETAL) && (weap != NULL) &&
288 (weap->o_flags & ISMETAL))
289 {
290 msg("The %s passes through the %s!",
291 weaps[weap->o_which].w_name,
292 monsters[tp->t_index].m_name);
293
294 fighting = FALSE;
295 }
296
297 /*
298 * If the player hit something that shrieks, wake the
299 * dungeon
300 */
301
302 if (on(*tp, CANSHRIEK))
303 {
304 turn_off(*tp, CANSHRIEK);
305
306 if (on(player, CANHEAR))
307 {
308 msg("You are stunned by the %s's shriek.", mname);
309 no_command += 4 + rnd(8);
310 }
311 else if (off(player, ISDEAF))
312 msg("The %s emits a piercing shriek.", mname);
313 else
314 msg("The %s seems to be trying to make some noise.", mname);
315
316 aggravate();
317
318 if (rnd(wizard ? 3 : 39) == 0 && cur_armor
319 != NULL
320 && cur_armor->o_which == CRYSTAL_ARMOR)
321 {
322 struct linked_list *itm;
323 struct object *obj;
324
325 for (itm = pack; itm != NULL; itm = next(itm))
326 {
327 obj = OBJPTR(itm);
328
329 if (obj == cur_armor)
330 break;
331 }
332
333 if (itm == NULL)
334 debug("Can't find crystalline armor being worn.");
335 else
336 {
337 msg("Your armor shatters from the shriek.");
338 cur_armor = NULL;
339 del_pack(itm);
340 }
341 }
342 }
343
344 /*
345 * If the player hit something that can surprise, it
346 * can't now
347 */
348
349 if (on(*tp, CANSURPRISE))
350 turn_off(*tp, CANSURPRISE);
351
352 /*
353 * If the player hit something that can summon, it
354 * will try to
355 */
356
357 summon_help(tp, NOFORCE);
358
359 /* Can the player confuse? */
360
361 if (on(player, CANHUH) && !thrown)
362 {
363 seemsg("Your hands stop glowing red!");
364 seemsg("The %s appears confused.", mname);
365 turn_on(*tp, ISHUH);