Mercurial > hg > early-roguelike
comparison arogue5/player.c @ 63:0ed67132cf10
Import Advanced Rogue 5.8 from the Roguelike Restoration Project (r1490)
author | elwin |
---|---|
date | Thu, 09 Aug 2012 22:58:48 +0000 |
parents | |
children | aeabbca6dc0b |
comparison
equal
deleted
inserted
replaced
62:0ef99244acb8 | 63:0ed67132cf10 |
---|---|
1 /* | |
2 * This file contains functions for dealing with special player abilities | |
3 * | |
4 * Advanced Rogue | |
5 * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T | |
6 * All rights reserved. | |
7 * | |
8 * See the file LICENSE.TXT for full copyright and licensing information. | |
9 */ | |
10 | |
11 #include "curses.h" | |
12 #include "rogue.h" | |
13 | |
14 | |
15 /* | |
16 * affect: | |
17 * cleric affecting undead | |
18 */ | |
19 | |
20 affect() | |
21 { | |
22 register struct linked_list *item; | |
23 register struct thing *tp; | |
24 register const char *mname; | |
25 bool see; | |
26 coord new_pos; | |
27 | |
28 if (player.t_ctype != C_CLERIC && cur_relic[HEIL_ANKH] == 0) { | |
29 msg("Only clerics can affect undead."); | |
30 return; | |
31 } | |
32 | |
33 new_pos.y = hero.y + delta.y; | |
34 new_pos.x = hero.x + delta.x; | |
35 | |
36 if (cansee(new_pos.y, new_pos.x)) see = TRUE; | |
37 else see = FALSE; | |
38 | |
39 /* Anything there? */ | |
40 if (new_pos.y < 0 || new_pos.y > LINES-3 || | |
41 new_pos.x < 0 || new_pos.x > COLS-1 || | |
42 mvwinch(mw, new_pos.y, new_pos.x) == ' ') { | |
43 msg("Nothing to affect."); | |
44 return; | |
45 } | |
46 | |
47 if ((item = find_mons(new_pos.y, new_pos.x)) == NULL) { | |
48 debug("Affect what @ %d,%d?", new_pos.y, new_pos.x); | |
49 return; | |
50 } | |
51 tp = THINGPTR(item); | |
52 mname = monsters[tp->t_index].m_name; | |
53 | |
54 if (on(player, ISINVIS) && off(*tp, CANSEE)) { | |
55 sprintf(outstring,"%s%s cannot see you", see ? "The " : "It", | |
56 see ? mname : ""); | |
57 msg(outstring); | |
58 return; | |
59 } | |
60 | |
61 if (off(*tp, TURNABLE) || on(*tp, WASTURNED)) | |
62 goto annoy; | |
63 turn_off(*tp, TURNABLE); | |
64 | |
65 /* Can cleric kill it? */ | |
66 if (pstats.s_lvl >= 3 * tp->t_stats.s_lvl) { | |
67 unsigned long test; /* For overflow check */ | |
68 | |
69 sprintf(outstring,"You have destroyed %s%s.", see ? "the " : "it", see ? mname : ""); | |
70 msg(outstring); | |
71 test = pstats.s_exp + tp->t_stats.s_exp; | |
72 | |
73 /* Be sure there is no overflow before increasing experience */ | |
74 if (test > pstats.s_exp) pstats.s_exp = test; | |
75 killed(item, FALSE, TRUE); | |
76 check_level(TRUE); | |
77 return; | |
78 } | |
79 | |
80 /* Can cleric turn it? */ | |
81 if (rnd(100) + 1 > | |
82 (100 * ((2 * tp->t_stats.s_lvl) - pstats.s_lvl)) / pstats.s_lvl) { | |
83 unsigned long test; /* Overflow test */ | |
84 | |
85 /* Make the monster flee */ | |
86 turn_on(*tp, WASTURNED); /* No more fleeing after this */ | |
87 turn_on(*tp, ISFLEE); | |
88 runto(tp, &hero); | |
89 | |
90 /* Let player know */ | |
91 sprintf(outstring,"You have turned %s%s.", see ? "the " : "it", see ? mname : ""); | |
92 msg(outstring); | |
93 | |
94 /* get points for turning monster -- but check overflow first */ | |
95 test = pstats.s_exp + tp->t_stats.s_exp/2; | |
96 if (test > pstats.s_exp) pstats.s_exp = test; | |
97 check_level(TRUE); | |
98 | |
99 /* If monster was suffocating, stop it */ | |
100 if (on(*tp, DIDSUFFOCATE)) { | |
101 turn_off(*tp, DIDSUFFOCATE); | |
102 extinguish(suffocate); | |
103 } | |
104 | |
105 /* If monster held us, stop it */ | |
106 if (on(*tp, DIDHOLD) && (--hold_count == 0)) | |
107 turn_off(player, ISHELD); | |
108 turn_off(*tp, DIDHOLD); | |
109 return; | |
110 } | |
111 | |
112 /* Otherwise -- no go */ | |
113 annoy: | |
114 sprintf(outstring,"You do not affect %s%s.", see ? "the " : "it", see ? mname : ""); | |
115 msg(outstring); | |
116 | |
117 /* Annoy monster */ | |
118 if (off(*tp, ISFLEE)) runto(tp, &hero); | |
119 } | |
120 | |
121 /* | |
122 * the magic user is going to try and cast a spell | |
123 */ | |
124 cast() | |
125 { | |
126 register int i, num_spells, spell_ability; | |
127 int which_spell; | |
128 bool nohw = FALSE; | |
129 | |
130 i = num_spells = spell_ability = which_spell = 0; | |
131 | |
132 if (player.t_ctype != C_MAGICIAN && pstats.s_intel < 16) { | |
133 msg("You are not permitted to cast spells."); | |
134 return; | |
135 } | |
136 if (cur_misc[WEAR_CLOAK] != NULL && | |
137 cur_misc[WEAR_CLOAK]->o_which == MM_R_POWERLESS) { | |
138 msg("You can't seem to cast a spell!"); | |
139 return; | |
140 } | |
141 num_spells = 0; | |
142 | |
143 /* Get the number of avilable spells */ | |
144 if (pstats.s_intel >= 16) | |
145 num_spells = pstats.s_intel - 15; | |
146 | |
147 if (player.t_ctype == C_MAGICIAN) | |
148 num_spells += pstats.s_lvl; | |
149 | |
150 if (num_spells > MAXSPELLS) | |
151 num_spells = MAXSPELLS; | |
152 | |
153 spell_ability = pstats.s_lvl * pstats.s_intel; | |
154 if (player.t_ctype != C_MAGICIAN) | |
155 spell_ability /= 2; | |
156 | |
157 /* Prompt for spells */ | |
158 msg("Which spell are you casting? (* for list): "); | |
159 | |
160 which_spell = (int) (readchar() - 'a'); | |
161 if (which_spell == (int) ESCAPE - (int) 'a') { | |
162 mpos = 0; | |
163 msg(""); | |
164 after = FALSE; | |
165 return; | |
166 } | |
167 if (which_spell >= 0 && which_spell < num_spells) nohw = TRUE; | |
168 | |
169 else if (slow_invent) { | |
170 register char c; | |
171 | |
172 for (i=0; i<num_spells; i++) { | |
173 msg(""); | |
174 mvwaddch(cw, 0, 0, '['); | |
175 waddch(cw, (char) ((int) 'a' + i)); | |
176 waddstr(cw, "] A spell of "); | |
177 if (magic_spells[i].s_type == TYP_POTION) | |
178 waddstr(cw, p_magic[magic_spells[i].s_which].mi_name); | |
179 else if (magic_spells[i].s_type == TYP_SCROLL) | |
180 waddstr(cw, s_magic[magic_spells[i].s_which].mi_name); | |
181 else if (magic_spells[i].s_type == TYP_STICK) | |
182 waddstr(cw, ws_magic[magic_spells[i].s_which].mi_name); | |
183 waddstr(cw, morestr); | |
184 draw(cw); | |
185 do { | |
186 c = readchar(); | |
187 } while (c != ' ' && c != ESCAPE); | |
188 if (c == ESCAPE) | |
189 break; | |
190 } | |
191 msg(""); | |
192 mvwaddstr(cw, 0, 0, "Which spell are you casting? "); | |
193 draw(cw); | |
194 } | |
195 else { | |
196 /* Set up for redraw */ | |
197 msg(""); | |
198 clearok(cw, TRUE); | |
199 touchwin(cw); | |
200 | |
201 /* Now display the possible spells */ | |
202 wclear(hw); | |
203 touchwin(hw); | |
204 mvwaddstr(hw, 2, 0, " Cost Spell"); | |
205 mvwaddstr(hw, 3, 0, "-----------------------------------------------"); | |
206 for (i=0; i<num_spells; i++) { | |
207 mvwaddch(hw, i+4, 0, '['); | |
208 waddch(hw, (char) ((int) 'a' + i)); | |
209 waddch(hw, ']'); | |
210 sprintf(prbuf, " %3d", magic_spells[i].s_cost); | |
211 waddstr(hw, prbuf); | |
212 waddstr(hw, " A spell of "); | |
213 if (magic_spells[i].s_type == TYP_POTION) | |
214 waddstr(hw, p_magic[magic_spells[i].s_which].mi_name); | |
215 else if (magic_spells[i].s_type == TYP_SCROLL) | |
216 waddstr(hw, s_magic[magic_spells[i].s_which].mi_name); | |
217 else if (magic_spells[i].s_type == TYP_STICK) | |
218 waddstr(hw, ws_magic[magic_spells[i].s_which].mi_name); | |
219 } | |
220 sprintf(prbuf,"[Current spell power = %d]",spell_ability - spell_power); | |
221 mvwaddstr(hw, 0, 0, prbuf); | |
222 waddstr(hw, " Which spell are you casting? "); | |
223 draw(hw); | |
224 } | |
225 | |
226 if (!nohw) { | |
227 which_spell = (int) (wgetch(hw) - 'a'); | |
228 while (which_spell < 0 || which_spell >= num_spells) { | |
229 if (which_spell == (int) ESCAPE - (int) 'a') { | |
230 after = FALSE; | |
231 return; | |
232 } | |
233 wmove(hw, 0, 0); | |
234 wclrtoeol(hw); | |
235 waddstr(hw, "Please enter one of the listed spells. "); | |
236 draw(hw); | |
237 which_spell = (int) (wgetch(hw) - 'a'); | |
238 } | |
239 } | |
240 | |
241 if ((spell_power + magic_spells[which_spell].s_cost) > spell_ability) { | |
242 msg("Your attempt fails."); | |
243 return; | |
244 } | |
245 if (nohw) | |
246 msg("Your spell is successful."); | |
247 else { | |
248 mvwaddstr(hw, 0, 0, "Your spell is successful.--More--"); | |
249 wclrtoeol(hw); | |
250 draw(hw); | |
251 wait_for(hw,' '); | |
252 } | |
253 if (magic_spells[which_spell].s_type == TYP_POTION) | |
254 quaff( magic_spells[which_spell].s_which, | |
255 magic_spells[which_spell].s_flag, | |
256 FALSE); | |
257 else if (magic_spells[which_spell].s_type == TYP_SCROLL) | |
258 read_scroll( magic_spells[which_spell].s_which, | |
259 magic_spells[which_spell].s_flag, | |
260 FALSE); | |
261 else if (magic_spells[which_spell].s_type == TYP_STICK) { | |
262 if (!do_zap( TRUE, | |
263 magic_spells[which_spell].s_which, | |
264 magic_spells[which_spell].s_flag)) { | |
265 after = FALSE; | |
266 return; | |
267 } | |
268 } | |
269 spell_power += magic_spells[which_spell].s_cost; | |
270 } | |
271 | |
272 /* Constitution bonus */ | |
273 | |
274 const_bonus() /* Hit point adjustment for changing levels */ | |
275 { | |
276 if (pstats.s_const > 6 && pstats.s_const <= 14) | |
277 return(0); | |
278 if (pstats.s_const > 14) | |
279 return(pstats.s_const-14); | |
280 if (pstats.s_const > 3) | |
281 return(-1); | |
282 return(-2); | |
283 } | |
284 | |
285 | |
286 /* Routines for thieves */ | |
287 | |
288 /* | |
289 * gsense: | |
290 * Sense gold | |
291 */ | |
292 | |
293 gsense() | |
294 { | |
295 /* Only thieves can do this */ | |
296 if (player.t_ctype != C_THIEF) { | |
297 msg("You seem to have no gold sense."); | |
298 return; | |
299 } | |
300 | |
301 if (lvl_obj != NULL) { | |
302 struct linked_list *gitem; | |
303 struct object *cur; | |
304 int gtotal = 0; | |
305 | |
306 wclear(hw); | |
307 for (gitem = lvl_obj; gitem != NULL; gitem = next(gitem)) { | |
308 cur = OBJPTR(gitem); | |
309 if (cur->o_type == GOLD) { | |
310 gtotal += cur->o_count; | |
311 mvwaddch(hw, cur->o_pos.y, cur->o_pos.x, GOLD); | |
312 } | |
313 } | |
314 if (gtotal) { | |
315 s_know[S_GFIND] = TRUE; | |
316 msg("You sense gold!"); | |
317 overlay(hw,cw); | |
318 return; | |
319 } | |
320 } | |
321 msg("You can sense no gold on this level."); | |
322 } | |
323 | |
324 /* | |
325 * the cleric asks his deity for a spell | |
326 */ | |
327 pray() | |
328 { | |
329 register int i, num_prayers, prayer_ability; | |
330 int which_prayer; | |
331 bool nohw = FALSE; | |
332 | |
333 which_prayer = num_prayers = prayer_ability = i = 0; | |
334 | |
335 if (player.t_ctype != C_CLERIC && pstats.s_wisdom < 17 && | |
336 cur_relic[HEIL_ANKH] == 0) { | |
337 msg("You are not permitted to pray."); | |
338 return; | |
339 } | |
340 if (cur_misc[WEAR_CLOAK] != NULL && | |
341 cur_misc[WEAR_CLOAK]->o_which == MM_R_POWERLESS) { | |
342 msg("You can't seem to pray!"); | |
343 return; | |
344 } | |
345 num_prayers = 0; | |
346 | |
347 /* Get the number of avilable prayers */ | |
348 if (pstats.s_wisdom > 16) | |
349 num_prayers = (pstats.s_wisdom - 15) / 2; | |
350 | |
351 if (player.t_ctype == C_CLERIC) | |
352 num_prayers += pstats.s_lvl; | |
353 | |
354 if (cur_relic[HEIL_ANKH]) num_prayers += 3; | |
355 | |
356 if (num_prayers > MAXPRAYERS) | |
357 num_prayers = MAXPRAYERS; | |
358 | |
359 prayer_ability = pstats.s_lvl * pstats.s_wisdom; | |
360 if (player.t_ctype != C_CLERIC) | |
361 prayer_ability /= 2; | |
362 | |
363 if (cur_relic[HEIL_ANKH]) prayer_ability *= 2; | |
364 | |
365 /* Prompt for prayer */ | |
366 msg("Which prayer are you offering? (* for list): "); | |
367 which_prayer = (int) (readchar() - 'a'); | |
368 if (which_prayer == (int) ESCAPE - (int) 'a') { | |
369 mpos = 0; | |
370 msg(""); | |
371 after = FALSE; | |
372 return; | |
373 } | |
374 if (which_prayer >= 0 && which_prayer < num_prayers) nohw = TRUE; | |