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; | |
