comparison srogue/fight.c @ 36:2128c7dc8a40

Import Super-Rogue 9.0 from the Roguelike Restoration Project (r1490)
author elwin
date Thu, 25 Nov 2010 12:21:41 +0000
parents
children 94a0d9dd5ce1
comparison
equal deleted inserted replaced
35:05018c63a721 36:2128c7dc8a40
1 /*
2 * All the fighting gets done here
3 *
4 * @(#)fight.c 9.0 (rdk) 7/17/84
5 *
6 * Super-Rogue
7 * Copyright (C) 1984 Robert D. Kindelberger
8 * All rights reserved.
9 *
10 * Based on "Rogue: Exploring the Dungeons of Doom"
11 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
12 * All rights reserved.
13 *
14 * See the file LICENSE.TXT for full copyright and licensing information.
15 */
16
17 #include <ctype.h>
18 #include "rogue.h"
19 #include "rogue.ext"
20
21
22 /*
23 * fight:
24 * The player attacks the monster.
25 */
26 fight(mp, weap, thrown)
27 struct coord *mp;
28 struct object *weap;
29 bool thrown;
30 {
31
32 reg struct thing *tp;
33 reg struct stats *st;
34 reg struct linked_list *item;
35 bool did_hit = TRUE;
36
37 if (pl_on(ISETHER)) /* cant fight when ethereal */
38 return 0;
39
40 if ((item = find_mons(mp->y, mp->x)) == NULL) {
41 mvaddch(mp->y, mp->x, FLOOR);
42 mvwaddch(mw, mp->y, mp->x, ' ');
43 look(FALSE);
44 msg("That monster must have been an illusion.");
45 return 0;
46 }
47 tp = THINGPTR(item);
48 st = &tp->t_stats;
49 /*
50 * Since we are fighting, things are not quiet so
51 * no healing takes place.
52 */
53 quiet = 0;
54 isfight = TRUE;
55 runto(mp, &hero);
56 /*
57 * Let him know it was really a mimic (if it was one).
58 */
59 if(tp->t_type == 'M' && tp->t_disguise != 'M' && pl_off(ISBLIND)) {
60 msg("Wait! That's a mimic!");
61 tp->t_disguise = 'M';
62 did_hit = thrown;
63 }
64 if (did_hit) {
65 reg char *mname;
66
67 did_hit = FALSE;
68 if (pl_on(ISBLIND))
69 mname = "it";
70 else
71 mname = monsters[tp->t_indx].m_name;
72 /*
73 * If the hero can see the invisibles, then
74 * make it easier to hit.
75 */
76 if (pl_on(CANSEE) && on(*tp, ISINVIS) && off(*tp, WASHIT)) {
77 tp->t_flags |= WASHIT;
78 st->s_arm += 3;
79 }
80 if (roll_em(him, st, weap, thrown)) {
81 did_hit = TRUE;
82 if (thrown)
83 thunk(weap, mname);
84 else
85 hit(NULL);
86 if (pl_on(CANHUH)) {
87 msg("Your hands stop glowing red");
88 msg("The %s appears confused.", mname);
89 tp->t_flags |= ISHUH;
90 player.t_flags &= ~CANHUH;
91 /*
92 * If our hero was stuck by a bone devil,
93 * release him now because the devil is
94 * confused.
95 */
96 if (pl_on(ISHELD))
97 unhold(tp->t_type);
98 }
99 if (st->s_hpt <= 0)
100 killed(item, TRUE);
101 else if (monhurt(tp) && off(*tp, ISWOUND)) {
102 if (levtype != MAZELEV && tp->t_room != NULL &&
103 !rf_on(tp->t_room, ISTREAS)) {
104 tp->t_flags |= ISWOUND;
105 msg("You wounded %s.",prname(mname,FALSE));
106 unhold(tp->t_type);
107 }
108 }
109 }
110 else {
111 if (thrown)
112 bounce(weap, mname);
113 else
114 miss(NULL);
115 }
116 }
117 count = 0;
118 return did_hit;
119 }
120
121
122 /*
123 * attack:
124 * The monster attacks the player
125 */
126 attack(mp)
127 struct thing *mp;
128 {
129 reg char *mname;
130
131 if (pl_on(ISETHER)) /* ethereal players cant be hit */
132 return(0);
133 if (mp->t_flags & ISPARA) /* paralyzed monsters */
134 return(0);
135 running = FALSE;
136 quiet = 0;
137 isfight = TRUE;
138 if (mp->t_type == 'M' && pl_off(ISBLIND))
139 mp->t_disguise = 'M';
140 if (pl_on(ISBLIND))
141 mname = "it";
142 else
143 mname = monsters[mp->t_indx].m_name;
144 if (roll_em(&mp->t_stats, him, NULL, FALSE)) {
145 if (pl_on(ISINVINC)) {
146 msg("%s does not harm you.",prname(mname,TRUE));
147 }
148 else {
149 nochange = FALSE;
150 if (mp->t_type != 'E')
151 hit(mname);
152 if (him->s_hpt <= 0)
153 death(mp->t_indx);
154 if (off(*mp, ISCANC))
155 switch (mp->t_type) {
156 case 'R':
157 if (hurt_armor(cur_armor)) {
158 msg("Your armor weakens.");
159 cur_armor->o_ac++;
160 }
161 when 'E':
162 /*
163 * The gaze of the floating eye hypnotizes you
164 */
165 if (pl_off(ISBLIND) && player.t_nocmd <= 0) {
166 player.t_nocmd = rnd(16) + 25;
167 msg("You are transfixed.");
168 }
169 when 'Q':
170 if (!save(VS_POISON) && !iswearing(R_SUSAB)) {
171 if (him->s_ef.a_dex > MINABIL) {
172 chg_abil(DEX, -1, TRUE);
173 msg("You feel less agile.");
174 }
175 }
176 when 'A':
177 if (!save(VS_POISON) && herostr() > MINABIL) {
178 if (!iswearing(R_SUSTSTR) && !iswearing(R_SUSAB)) {
179 if (levcount > 0) {
180 chg_abil(STR, -1, TRUE);
181 msg("A sting has weakened you");
182 }
183 }
184 else
185 msg("Sting has no effect.");
186 }
187 when 'W':
188 if (rnd(100) < 15 && !iswearing(R_SUSAB)) {
189 if (him->s_exp <= 0)
190 death(mp->t_indx);
191 msg("You suddenly feel weaker.");
192 if (--him->s_lvl == 0) {
193 him->s_exp = 0;
194 him->s_lvl = 1;
195 }
196 else
197 him->s_exp = e_levels[him->s_lvl - 1] + 1;
198 chg_hpt(-roll(1,10),TRUE,mp->t_indx);
199 }
200 when 'F':
201 player.t_flags |= ISHELD;
202 sprintf(monsters[midx('F')].m_stats.s_dmg,"%dd1",++fung_hit);
203 when 'L': {
204 long lastpurse;
205 struct linked_list *lep;
206
207 lastpurse = purse;
208 purse -= GOLDCALC;
209 if (!save(VS_MAGIC))
210 purse -= GOLDCALC + GOLDCALC + GOLDCALC + GOLDCALC;
211 if (purse < 0)
212 purse = 0;
213 if (purse != lastpurse)
214 msg("Your purse feels lighter.");
215 lep = find_mons(mp->t_pos.y,mp->t_pos.x);
216 if (lep != NULL)
217 {
218 remove_monster(&mp->t_pos, lep);
219 mp = NULL;
220 }
221 }
222 when 'N': {
223 struct linked_list *steal, *list;
224 struct object *sobj;
225 int stworth = 0, wo;
226
227 /*
228 * Nymph's steal a magic item, look through the pack
229 * and pick out one we like, namely the object worth
230 * the most bucks.
231 */
232 steal = NULL;
233 for (list = pack; list != NULL; list = next(list)) {
234 wo = get_worth(OBJPTR(list));
235 if (wo > stworth) {
236 stworth = wo;
237 steal = list;
238 }
239 }
240 if (steal != NULL) {
241 sobj = OBJPTR(steal);
242 if (o_off(sobj, ISPROT)) {
243 struct linked_list *nym;
244
245 nym = find_mons(mp->t_pos.y, mp->t_pos.x);
246 if (nym != NULL)
247 {
248 remove_monster(&mp->t_pos, nym);
249 mp = NULL;
250 }
251 msg("She stole %s!", inv_name(sobj, TRUE));
252 detach(pack, steal);
253 discard(steal);
254 cur_null(sobj);
255 updpack();
256 }
257 }
258 }
259 when 'c':
260 if (!save(VS_PETRIFICATION)) {
261 msg("Your body begins to solidify.");
262 msg("You are turned to stone !!! --More--");
263 wait_for(cw, ' ');
264 death(mp->t_indx);
265 }
266 when 'd':
267 if (rnd(100) < 50 && !(mp->t_flags & ISHUH))
268 player.t_flags |= ISHELD;
269 if (!save(VS_POISON)) {
270 if (iswearing(R_SUSAB) || iswearing(R_SUSTSTR))
271 msg("Sting has no effect.");
272 else {
273 int fewer, ostr;
274
275 fewer = roll(1,4);
276 ostr = herostr();
277 chg_abil(STR,-fewer,TRUE);
278 if (herostr() < ostr) {
279 fewer = ostr - herostr();
280 fuse(rchg_str, fewer - 1, 10);
281 }
282 msg("You feel weaker now.");
283 }
284 }
285 when 'g':
286 if (!save(VS_BREATH) && !iswearing(R_BREATH)) {
287 msg("You feel singed.");
288 chg_hpt(-roll(1,8),FALSE,mp->t_indx);
289 }
290 when 'h':
291 if (!save(VS_BREATH) && !iswearing(R_BREATH)) {
292 msg("You are seared.");
293 chg_hpt(-roll(1,4),FALSE,mp->t_indx);
294 }
295 when 'p':
296 if (!save(VS_POISON) && herostr() > MINABIL) {
297 if (!iswearing(R_SUSTSTR) && !iswearing(R_SUSAB)) {
298 msg("You are gnawed.");
299 chg_abil(STR,-1,TRUE);
300 }
301 }
302 when 'u':
303 if (!save(VS_POISON) && herostr() > MINABIL) {
304 if (!iswearing(R_SUSTSTR) && !iswearing(R_SUSAB)) {
305 msg("You are bitten.");
306 chg_abil(STR, -1, TRUE);
307 fuse(rchg_str, 1, roll(5,10));
308 }
309 }
310 when 'w':
311 if (!save(VS_POISON) && !iswearing(R_SUSAB)) {
312 msg("You feel devitalized.");
313 chg_hpt(-1,TRUE,mp->t_indx);
314 }
315 when 'i':
316 if (!save(VS_PARALYZATION) && !iswearing(R_SUSAB)) {
317 if (pl_on(ISSLOW))
318 lengthen(notslow,roll(3,10));
319 else {
320 msg("You feel impaired.");
321 player.t_flags |= ISSLOW;
322 fuse(notslow,TRUE,roll(5,10));
323 }
324 }
325 otherwise:
326 break;
327 }
328 }
329 }
330 else if (mp->t_type != 'E') {
331 if (mp->t_type == 'F') {
332 him->s_hpt -= fung_hit;
333 if (him->s_hpt <= 0)
334 death(mp->t_indx);
335 }
336 miss(mname);
337 }
338 flushinp(); /* flush type ahead */
339 count = 0;
340
341 if (mp == NULL)
342 return(-1);
343 else
344 return(0);
345 }
346
347
348 /*
349 * swing:
350 * Returns true if the swing hits
351 */
352 swing(at_lvl, op_arm, wplus)
353 int at_lvl, op_arm, wplus;
354 {
355 reg int res = rnd(20)+1;
356 reg int need = (21 - at_lvl) - op_arm;
357
358 return (res + wplus >= need);
359 }
360
361
362 /*
363 * check_level:
364 * Check to see if the guy has gone up a level.
365 */
366 check_level()
367 {
368 reg int lev, add, dif;
369
370 for (lev = 0; e_levels[lev] != 0; lev++)
371 if (e_levels[lev] > him->s_exp)
372 break;
373 lev += 1;
374 if (lev > him->s_lvl) {
375 dif = lev - him->s_lvl;
376 add = roll(dif, 10) + (dif * getpcon(him));
377 him->s_maxhp += add;
378 if ((him->s_hpt += add) > him->s_maxhp)
379