Mercurial > hg > early-roguelike
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); | |