comparison rogue4/fight.c @ 12:9535a08ddc39

Import Rogue 5.2 from the Roguelike Restoration Project (r1490)
author edwarj4
date Sat, 24 Oct 2009 16:52:52 +0000
parents
children 1b73a8641b37
comparison
equal deleted inserted replaced
11:949d558c2162 12:9535a08ddc39
1 /*
2 * All the fighting gets done here
3 *
4 * @(#)fight.c 4.30 (Berkeley) 4/6/82
5 *
6 * Rogue: Exploring the Dungeons of Doom
7 * Copyright (C) 1980, 1981, 1982 Michael Toy, Ken Arnold and Glenn Wichman
8 * All rights reserved.
9 *
10 * See the file LICENSE.TXT for full copyright and licensing information.
11 */
12
13 #include <curses.h>
14 #include <ctype.h>
15 #include <string.h>
16 #include "rogue.h"
17
18 long e_levels[] = {
19 10L,20L,40L,80L,160L,320L,640L,1280L,2560L,5120L,10240L,20480L,
20 40920L, 81920L, 163840L, 327680L, 655360L, 1310720L, 2621440L, 0L
21 };
22
23 /*
24 * fight:
25 * The player attacks the monster.
26 */
27 fight(mp, mn, weap, thrown)
28 register coord *mp;
29 char mn;
30 register THING *weap;
31 bool thrown;
32 {
33 register THING *tp;
34 register bool did_hit = TRUE;
35 register const char *mname;
36
37 /*
38 * Find the monster we want to fight
39 */
40 #ifdef WIZARD
41 if ((tp = moat(mp->y, mp->x)) == NULL)
42 debug("Fight what @ %d,%d", mp->y, mp->x);
43 #else
44 tp = moat(mp->y, mp->x);
45 #endif
46 /*
47 * Since we are fighting, things are not quiet so no healing takes
48 * place.
49 */
50 count = quiet = 0;
51 runto(mp, &hero);
52 /*
53 * Let him know it was really a mimic (if it was one).
54 */
55 if (tp->t_type == 'M' && tp->t_disguise != 'M' && !on(player, ISBLIND))
56 {
57 tp->t_disguise = 'M';
58 if (!thrown)
59 return FALSE;
60 msg("wait! That's a mimic!");
61 }
62 did_hit = FALSE;
63 if (on(player, ISBLIND))
64 mname = "it";
65 else
66 mname = monsters[mn-'A'].m_name;
67 if (roll_em(&player, tp, weap, thrown))
68 {
69 did_hit = FALSE;
70 if (thrown)
71 thunk(weap, mname);
72 else
73 hit(NULL, mname);
74 if (on(player, CANHUH))
75 {
76 did_hit = TRUE;
77 tp->t_flags |= ISHUH;
78 player.t_flags &= ~CANHUH;
79 msg("your hands stop glowing red");
80 }
81 if (tp->t_stats.s_hpt <= 0)
82 killed(tp, TRUE);
83 else if (did_hit && !on(player, ISBLIND))
84 msg("the %s appears confused", mname);
85 did_hit = TRUE;
86 }
87 else
88 if (thrown)
89 bounce(weap, mname);
90 else
91 miss(NULL, mname);
92 return did_hit;
93 }
94
95 /*
96 * attack:
97 * The monster attacks the player
98 */
99 attack(mp)
100 register THING *mp;
101 {
102 register const char *mname;
103
104 /*
105 * Since this is an attack, stop running and any healing that was
106 * going on at the time.
107 */
108 running = FALSE;
109 count = quiet = 0;
110 if (mp->t_type == 'M' && !on(player, ISBLIND))
111 mp->t_disguise = 'M';
112 if (on(player, ISBLIND))
113 mname = "it";
114 else
115 mname = monsters[mp->t_type-'A'].m_name;
116 if (roll_em(mp, &player, NULL, FALSE))
117 {
118 if (mp->t_type != 'E')
119 hit(mname, NULL);
120 if (pstats.s_hpt <= 0)
121 death(mp->t_type); /* Bye bye life ... */
122 if (!on(*mp, ISCANC))
123 switch (mp->t_type)
124 {
125 case 'R':
126 /*
127 * If a rust monster hits, you lose armor, unless
128 * that armor is leather or there is a magic ring
129 */
130 if (cur_armor != NULL && cur_armor->o_ac < 9
131 && cur_armor->o_which != LEATHER)
132 if (ISWEARING(R_SUSTARM))
133 msg("The rust vanishes instantly");
134 else
135 {
136 cur_armor->o_ac++;
137 if (!terse)
138 msg("your armor appears to be weaker now. Oh my!");
139 else
140 msg("your armor weakens");
141 }
142 when 'E':
143 /*
144 * The gaze of the floating eye hypnotizes you
145 */
146 if (on(player, ISBLIND))
147 break;
148 player.t_flags &= ~ISRUN;
149 if (!no_command)
150 {
151 addmsg("you are transfixed");
152 if (!terse)
153 addmsg(" by the gaze of the floating eye");
154 endmsg();
155 }
156 no_command += rnd(2) + 2;
157 when 'A':
158 /*
159 * Ants have poisonous bites
160 */
161 if (!save(VS_POISON))
162 if (!ISWEARING(R_SUSTSTR))
163 {
164 chg_str(-1);
165 if (!terse)
166 msg("you feel a sting in your arm and now feel weaker");
167 else
168 msg("a sting has weakened you");
169 }
170 else
171 if (!terse)
172 msg("a sting momentarily weakens you");
173 else
174 msg("sting has no effect");
175 when 'W':
176 case 'V':
177 /*
178 * Wraiths might drain energy levels, and Vampires
179 * can steal max_hp
180 */
181 if (rnd(100) < (mp->t_type == 'W' ? 15 : 30))
182 {
183 register int fewer;
184
185 if (mp->t_type == 'W')
186 {
187 if (pstats.s_exp == 0)
188 death('W'); /* All levels gone */
189 if (--pstats.s_lvl == 0)
190 {
191 pstats.s_exp = 0;
192 pstats.s_lvl = 1;
193 }
194 else
195 pstats.s_exp = e_levels[pstats.s_lvl-1]+1;
196 fewer = roll(1, 10);
197 }
198 else
199 fewer = roll(1, 5);
200 pstats.s_hpt -= fewer;
201 max_hp -= fewer;
202 if (pstats.s_hpt < 1)
203 pstats.s_hpt = 1;
204 if (max_hp < 1)
205 death(mp->t_type);
206 msg("you suddenly feel weaker");
207 }
208 when 'F':
209 /*
210 * Violet fungi stops the poor guy from moving
211 */
212 player.t_flags |= ISHELD;
213 sprintf(monsters['F'-'A'].m_stats.s_dmg,"%dd1",++fung_hit);
214 when 'L':
215 {
216 /*
217 * Leperachaun steals some gold
218 */
219 register long lastpurse;
220
221 lastpurse = purse;
222 purse -= GOLDCALC;
223 if (!save(VS_MAGIC))
224 purse -= GOLDCALC + GOLDCALC + GOLDCALC + GOLDCALC;
225 if (purse < 0)
226 purse = 0;
227 remove_monster(&mp->t_pos, mp, FALSE);
228 mp = NULL;
229 if (purse != lastpurse)
230 msg("your purse feels lighter");
231 }
232 when 'N':
233 {
234 register THING *obj, *steal;
235 register int nobj;
236
237 /*
238 * Nymph's steal a magic item, look through the pack
239 * and pick out one we like.
240 */
241 steal = NULL;
242 for (nobj = 0, obj = pack; obj != NULL; obj = next(obj))
243 if (obj != cur_armor && obj != cur_weapon
244 && obj != cur_ring[LEFT] && obj != cur_ring[RIGHT]
245 && is_magic(obj) && rnd(++nobj) == 0)
246 steal = obj;
247 if (steal != NULL)
248 {
249 remove_monster(&mp->t_pos, moat(mp->t_pos.y, mp->t_pos.x), FALSE);
250 mp = NULL;
251 inpack--;
252 if (steal->o_count > 1 && steal->o_group == 0)
253 {
254 register int oc;
255
256 oc = steal->o_count--;
257 steal->o_count = 1;
258 msg("she stole %s!", inv_name(steal, TRUE));
259 steal->o_count = oc;
260 }
261 else
262 {
263 detach(pack, steal);
264 msg("she stole %s!", inv_name(steal, TRUE));
265 discard(steal);
266 }
267 }
268 }
269 otherwise:
270 break;
271 }
272 }
273 else if (mp->t_type != 'E')
274 {
275 if (mp->t_type == 'F')
276 {
277 pstats.s_hpt -= fung_hit;
278 if (pstats.s_hpt <= 0)
279 death(mp->t_type); /* Bye bye life ... */
280 }
281 miss(mname, NULL);
282 }
283 if (fight_flush)
284 flush_type();
285 count = 0;
286 status();
287
288 if (mp == NULL)
289 return(-1);
290 else
291 return(0);
292 }
293
294 /*
295 * swing:
296 * Returns true if the swing hits
297 */
298 swing(at_lvl, op_arm, wplus)
299 int at_lvl, op_arm, wplus;
300 {
301 register int res = rnd(20);
302 register int need = (20 - at_lvl) - op_arm;
303
304 return (res + wplus >= need);
305 }
306
307 /*
308 * check_level:
309 * Check to see if the guy has gone up a level.
310 */
311 check_level()
312 {
313 register int i, add, olevel;
314
315 for (i = 0; e_levels[i] != 0; i++)
316 if (e_levels[i] > pstats.s_exp)
317 break;
318 i++;
319 olevel = pstats.s_lvl;
320 pstats.s_lvl = i;
321 if (i > olevel)
322 {
323 add = roll(i - olevel, 10);
324 max_hp += add;
325 if ((pstats.s_hpt += add) > max_hp)
326 pstats.s_hpt = max_hp;
327 msg("welcome to level %d", i);
328 }
329 }
330
331 /*
332 * roll_em:
333 * Roll several attacks
334 */
335 roll_em(thatt, thdef, weap, hurl)
336 THING *thatt, *thdef, *weap;
337 bool hurl;
338 {
339 register struct stats *att, *def;
340 register char *cp;
341 register int ndice, nsides, def_arm;
342 register bool did_hit = FALSE;
343 register int hplus;
344 register int dplus;
345 register int damage;
346
347 att = &thatt->t_stats;
348 def = &thdef->t_stats;
349 if (weap == NULL)
350 {
351 cp = att->s_dmg;
352 dplus = 0;
353 hplus = 0;
354 }
355 else
356 {
357 hplus = (weap == NULL ? 0 : weap->o_hplus);
358 dplus = (weap == NULL ? 0 : weap->o_dplus);
359 if (weap == cur_weapon)
360 {
361 if (ISRING(LEFT, R_ADDDAM))
362 dplus += cur_ring[LEFT]->o_ac;
363 else if (ISRING(LEFT, R_ADDHIT))
364 hplus += cur_ring[LEFT]->o_ac;
365 if (ISRING(RIGHT, R_ADDDAM))
366 dplus += cur_ring[RIGHT]->o_ac;
367 else if (ISRING(RIGHT, R_ADDHIT))
368 hplus += cur_ring[RIGHT]->o_ac;
369 }
370 if (hurl)
371 if ((weap->o_flags&ISMISL) && cur_weapon != NULL &&
372 cur_weapon->o_which == weap->o_launch)
373 {
374 cp = weap->o_hurldmg;
375 hplus += cur_weapon->o_hplus;
376 dplus += cur_weapon->o_dplus;
377 }
378 else
379 cp = weap->o_hurldmg;
380 else
381 {
382 cp = weap->o_damage;