Some calls to runto() were given a pointer to the player struct instead of to the player's coordinates. A call to death() was passed a pointer to a monster instead of the monster's type number.
1493 lines
44 KiB
C
1493 lines
44 KiB
C
/*
|
|
player.c - functions for dealing with special player abilities
|
|
|
|
XRogue: Expeditions into the Dungeons of Doom
|
|
Copyright (C) 1991 Robert Pietkivitch
|
|
All rights reserved.
|
|
|
|
Based on "Advanced Rogue"
|
|
Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
|
All rights reserved.
|
|
|
|
See the file LICENSE.TXT for full copyright and licensing information.
|
|
*/
|
|
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
#include <curses.h>
|
|
#include "rogue.h"
|
|
|
|
bool pick_spell(struct spells spells[], int ability, int num_spells, int power,
|
|
const char *prompt, const char *type);
|
|
/*
|
|
* affect:
|
|
* cleric affecting undead
|
|
*/
|
|
|
|
void
|
|
affect(void)
|
|
{
|
|
register struct linked_list *item;
|
|
register struct thing *tp;
|
|
register char *mname;
|
|
bool see;
|
|
coord new_pos;
|
|
int lvl;
|
|
|
|
if (!(player.t_ctype == C_CLERIC ||
|
|
(player.t_ctype == C_PALADIN && pstats.s_lvl > 4) ||
|
|
cur_relic[HEIL_ANKH] != 0)) {
|
|
msg("You cannot affect undead.");
|
|
return;
|
|
}
|
|
|
|
new_pos.y = hero.y + player.t_newpos.y;
|
|
new_pos.x = hero.x + player.t_newpos.x;
|
|
|
|
if (cansee(new_pos.y, new_pos.x)) see = TRUE;
|
|
else see = FALSE;
|
|
|
|
/* Anything there? */
|
|
if (new_pos.y < 0 || new_pos.y > lines-3 ||
|
|
new_pos.x < 0 || new_pos.x > cols-1 ||
|
|
mvwinch(mw, new_pos.y, new_pos.x) == ' ') {
|
|
msg("Nothing to affect.");
|
|
return;
|
|
}
|
|
|
|
if ((item = find_mons(new_pos.y, new_pos.x)) == 0) {
|
|
debug("Affect what @ %d,%d?", new_pos.y, new_pos.x);
|
|
return;
|
|
}
|
|
tp = THINGPTR(item);
|
|
mname = monster_name(tp);
|
|
|
|
if (on(player, ISINVIS) && off(*tp, CANSEE)) {
|
|
msg("%s%s cannot see you", see ? "The " : "It",
|
|
see ? mname : "");
|
|
return;
|
|
}
|
|
|
|
if (off(*tp, TURNABLE) || on(*tp, WASTURNED))
|
|
goto annoy;
|
|
turn_off(*tp, TURNABLE);
|
|
|
|
lvl = pstats.s_lvl;
|
|
if (player.t_ctype == C_PALADIN && cur_relic[HEIL_ANKH] == 0) {
|
|
lvl -= 4;
|
|
}
|
|
/* Can cleric kill it? */
|
|
if (lvl >= 3 * tp->t_stats.s_lvl) {
|
|
unsigned long test; /* For overflow check */
|
|
|
|
msg("You have destroyed %s%s.", see ? "the " : "it", see ? mname : "");
|
|
test = pstats.s_exp + tp->t_stats.s_exp;
|
|
|
|
/* Be sure there is no overflow before increasing experience */
|
|
if (test > pstats.s_exp) pstats.s_exp = test;
|
|
killed(item, FALSE, TRUE, TRUE);
|
|
check_level();
|
|
return;
|
|
}
|
|
|
|
/* Can cleric turn it? */
|
|
if (rnd(100) + 1 >
|
|
(100 * ((2 * tp->t_stats.s_lvl) - lvl)) / lvl) {
|
|
unsigned long test; /* Overflow test */
|
|
|
|
/* Make the monster flee */
|
|
turn_on(*tp, WASTURNED); /* No more fleeing after this */
|
|
turn_on(*tp, ISFLEE);
|
|
runto(tp, &hero);
|
|
|
|
/* Disrupt it */
|
|
dsrpt_monster(tp, TRUE, TRUE);
|
|
|
|
/* Let player know */
|
|
msg("You have turned %s%s.", see ? "the " : "it", see ? mname : "");
|
|
|
|
/* get points for turning monster -- but check overflow first */
|
|
test = pstats.s_exp + tp->t_stats.s_exp/2;
|
|
if (test > pstats.s_exp) pstats.s_exp = test;
|
|
check_level();
|
|
|
|
/* If monster was suffocating, stop it */
|
|
if (on(*tp, DIDSUFFOCATE)) {
|
|
turn_off(*tp, DIDSUFFOCATE);
|
|
extinguish(suffocate);
|
|
}
|
|
|
|
/* If monster held us, stop it */
|
|
if (on(*tp, DIDHOLD) && (--hold_count == 0))
|
|
turn_off(player, ISHELD);
|
|
turn_off(*tp, DIDHOLD);
|
|
|
|
/* It is okay to turn tail */
|
|
tp->t_oldpos = tp->t_pos;
|
|
|
|
return;
|
|
}
|
|
|
|
/* Otherwise -- no go */
|
|
annoy:
|
|
if (see && tp->t_stats.s_intel > 16)
|
|
msg("%s laughs at you...", prname(mname, TRUE));
|
|
else
|
|
msg("You do not affect %s%s.", see ? "the " : "it", see ? mname : "");
|
|
|
|
/* Annoy monster */
|
|
if (off(*tp, ISFLEE)) runto(tp, &hero);
|
|
}
|
|
|
|
/*
|
|
* the cleric asks his deity for a spell
|
|
*/
|
|
|
|
void
|
|
pray(void)
|
|
{
|
|
register int num_prayers, prayer_ability, which_prayer;
|
|
|
|
which_prayer = num_prayers = prayer_ability = 0;
|
|
|
|
if (player.t_ctype != C_CLERIC && player.t_ctype != C_PALADIN &&
|
|
cur_relic[HEIL_ANKH] == 0) {
|
|
msg("You are not permitted to pray.");
|
|
return;
|
|
}
|
|
if (cur_misc[WEAR_CLOAK] != NULL &&
|
|
cur_misc[WEAR_CLOAK]->o_which == MM_R_POWERLESS) {
|
|
msg("You can't seem to pray!");
|
|
return;
|
|
}
|
|
|
|
prayer_ability = pstats.s_lvl * pstats.s_wisdom - 5;
|
|
if (player.t_ctype != C_CLERIC)
|
|
prayer_ability /= 2;
|
|
|
|
if (cur_relic[HEIL_ANKH]) prayer_ability += 75;
|
|
|
|
if (player.t_action != C_PRAY) {
|
|
num_prayers = 0;
|
|
|
|
/* Get the number of avilable prayers */
|
|
if (pstats.s_wisdom > 16)
|
|
num_prayers += pstats.s_wisdom - 16;
|
|
|
|
num_prayers += pstats.s_lvl;
|
|
if (cur_relic[HEIL_ANKH])
|
|
num_prayers += pstats.s_wisdom - 18;
|
|
|
|
if (player.t_ctype != C_CLERIC)
|
|
num_prayers /= 2;
|
|
|
|
if (num_prayers > MAXPRAYERS)
|
|
num_prayers = MAXPRAYERS;
|
|
if (num_prayers < 1) {
|
|
msg("You are not permitted to pray yet.");
|
|
return;
|
|
}
|
|
|
|
/* Prompt for prayer */
|
|
if (pick_spell( cleric_spells,
|
|
prayer_ability,
|
|
num_prayers,
|
|
pray_time,
|
|
"offer",
|
|
"prayer"))
|
|
player.t_action = C_PRAY;
|
|
|
|
return;
|
|
}
|
|
|
|
/* We've waited our required praying time. */
|
|
which_prayer = player.t_selection;
|
|
player.t_selection = 0;
|
|
player.t_action = A_NIL;
|
|
|
|
if (cleric_spells[which_prayer].s_cost + pray_time > prayer_ability) {
|
|
msg("Your prayer fails.");
|
|
return;
|
|
}
|
|
|
|
msg("Your prayer has been granted. ");
|
|
|
|
if (cleric_spells[which_prayer].s_type == TYP_POTION)
|
|
quaff( cleric_spells[which_prayer].s_which,
|
|
0,
|
|
cleric_spells[which_prayer].s_flag,
|
|
FALSE);
|
|
else if (cleric_spells[which_prayer].s_type == TYP_SCROLL)
|
|
read_scroll( cleric_spells[which_prayer].s_which,
|
|
cleric_spells[which_prayer].s_flag,
|
|
FALSE);
|
|
else if (cleric_spells[which_prayer].s_type == TYP_STICK) {
|
|
if (!player_zap(cleric_spells[which_prayer].s_which,
|
|
cleric_spells[which_prayer].s_flag)) {
|
|
after = FALSE;
|
|
return;
|
|
}
|
|
}
|
|
pray_time += cleric_spells[which_prayer].s_cost;
|
|
}
|
|
|
|
/*
|
|
* the magician is going to try and cast a spell
|
|
*/
|
|
|
|
void
|
|
cast(void)
|
|
{
|
|
register int spell_ability, which_spell, num_spells;
|
|
|
|
if (player.t_ctype != C_MAGICIAN && player.t_ctype != C_RANGER) {
|
|
msg("You are not permitted to cast spells.");
|
|
return;
|
|
}
|
|
if (cur_misc[WEAR_CLOAK] != NULL &&
|
|
cur_misc[WEAR_CLOAK]->o_which == MM_R_POWERLESS) {
|
|
msg("You can't seem to cast spells!");
|
|
return;
|
|
}
|
|
spell_ability = pstats.s_lvl * pstats.s_intel - 5;
|
|
if (player.t_ctype != C_MAGICIAN)
|
|
spell_ability /= 2;
|
|
|
|
if (player.t_action != C_CAST) {
|
|
/*
|
|
* Get the number of avilable spells
|
|
*/
|
|
num_spells = 0;
|
|
if (pstats.s_intel > 16)
|
|
num_spells += pstats.s_intel - 16;
|
|
|
|
num_spells += pstats.s_lvl;
|
|
if (player.t_ctype != C_MAGICIAN)
|
|
num_spells /= 2;
|
|
if (num_spells > MAXSPELLS)
|
|
num_spells = MAXSPELLS;
|
|
if (num_spells < 1) {
|
|
msg("You are not allowed to cast spells yet.");
|
|
return;
|
|
}
|
|
|
|
/* prompt for spell */
|
|
if (pick_spell( magic_spells,
|
|
spell_ability,
|
|
num_spells,
|
|
spell_power,
|
|
"cast",
|
|
"spell"))
|
|
player.t_action = C_CAST;
|
|
return;
|
|
}
|
|
|
|
/* We've waited our required casting time. */
|
|
which_spell = player.t_selection;
|
|
player.t_selection = 0;
|
|
player.t_action = A_NIL;
|
|
|
|
if ((spell_power + magic_spells[which_spell].s_cost) > spell_ability) {
|
|
msg("Your attempt fails.");
|
|
return;
|
|
}
|
|
|
|
msg("Your spell is successful. ");
|
|
|
|
if (magic_spells[which_spell].s_type == TYP_POTION)
|
|
quaff( magic_spells[which_spell].s_which,
|
|
0,
|
|
magic_spells[which_spell].s_flag,
|
|
FALSE);
|
|
else if (magic_spells[which_spell].s_type == TYP_SCROLL)
|
|
read_scroll( magic_spells[which_spell].s_which,
|
|
magic_spells[which_spell].s_flag,
|
|
FALSE);
|
|
else if (magic_spells[which_spell].s_type == TYP_STICK) {
|
|
if (!player_zap(magic_spells[which_spell].s_which,
|
|
magic_spells[which_spell].s_flag)) {
|
|
after = FALSE;
|
|
return;
|
|
}
|
|
}
|
|
spell_power += magic_spells[which_spell].s_cost;
|
|
}
|
|
|
|
/*
|
|
* the druid asks his deity for a spell
|
|
*/
|
|
|
|
void
|
|
chant(void)
|
|
{
|
|
register int num_chants, chant_ability, which_chant;
|
|
|
|
which_chant = num_chants = chant_ability = 0;
|
|
|
|
if (player.t_ctype != C_DRUID && player.t_ctype != C_MONK) {
|
|
msg("You are not permitted to chant.");
|
|
return;
|
|
}
|
|
if (cur_misc[WEAR_CLOAK] != NULL &&
|
|
cur_misc[WEAR_CLOAK]->o_which == MM_R_POWERLESS) {
|
|
msg("You can't seem to chant!");
|
|
return;
|
|
}
|
|
chant_ability = pstats.s_lvl * pstats.s_wisdom - 5;
|
|
if (player.t_ctype != C_DRUID)
|
|
chant_ability /= 2;
|
|
|
|
if (player.t_action != C_CHANT) {
|
|
num_chants = 0;
|
|
|
|
/* Get the number of avilable chants */
|
|
if (pstats.s_wisdom > 16)
|
|
num_chants += pstats.s_wisdom - 16;
|
|
|
|
num_chants += pstats.s_lvl;
|
|
|
|
if (player.t_ctype != C_DRUID)
|
|
num_chants /= 2;
|
|
|
|
if (num_chants > MAXCHANTS)
|
|
num_chants = MAXCHANTS;
|
|
|
|
if (num_chants < 1) {
|
|
msg("You are not permitted to chant yet.");
|
|
return;
|
|
}
|
|
|
|
/* Prompt for chant */
|
|
if (pick_spell( druid_spells,
|
|
chant_ability,
|
|
num_chants,
|
|
chant_time,
|
|
"sing",
|
|
"chant"))
|
|
player.t_action = C_CHANT;
|
|
|
|
return;
|
|
}
|
|
|
|
/* We've waited our required chanting time. */
|
|
which_chant = player.t_selection;
|
|
player.t_selection = 0;
|
|
player.t_action = A_NIL;
|
|
|
|
if (druid_spells[which_chant].s_cost + chant_time > chant_ability) {
|
|
msg("Your chant fails.");
|
|
return;
|
|
}
|
|
|
|
msg("Your chant has been granted. ");
|
|
|
|
if (druid_spells[which_chant].s_type == TYP_POTION)
|
|
quaff( druid_spells[which_chant].s_which,
|
|
0,
|
|
druid_spells[which_chant].s_flag,
|
|
FALSE);
|
|
else if (druid_spells[which_chant].s_type == TYP_SCROLL)
|
|
read_scroll( druid_spells[which_chant].s_which,
|
|
druid_spells[which_chant].s_flag,
|
|
FALSE);
|
|
else if (druid_spells[which_chant].s_type == TYP_STICK) {
|
|
if (!player_zap(druid_spells[which_chant].s_which,
|
|
druid_spells[which_chant].s_flag)) {
|
|
after = FALSE;
|
|
return;
|
|
}
|
|
}
|
|
chant_time += druid_spells[which_chant].s_cost;
|
|
}
|
|
|
|
/* Constitution bonus */
|
|
|
|
int
|
|
const_bonus(void) /* Hit point adjustment for changing levels */
|
|
{
|
|
register int bonus;
|
|
if (pstats.s_const > 9 && pstats.s_const < 18)
|
|
bonus = 0;
|
|
else if (pstats.s_const >= 18 && pstats.s_const < 20)
|
|
bonus = 1;
|
|
else if (pstats.s_const >= 20 && pstats.s_const < 26)
|
|
bonus = 2;
|
|
else if (pstats.s_const >= 26 && pstats.s_const < 36)
|
|
bonus = 3;
|
|
else if (pstats.s_const >= 36)
|
|
bonus = 4;
|
|
else if (pstats.s_const > 7)
|
|
bonus = -1;
|
|
else
|
|
bonus = -2;
|
|
switch(player.t_ctype) {
|
|
case C_FIGHTER: bonus = min(bonus, 11);
|
|
when C_RANGER: bonus = min(bonus, 9);
|
|
when C_PALADIN: bonus = min(bonus, 9);
|
|
when C_MAGICIAN: bonus = min(bonus, 8);
|
|
when C_CLERIC: bonus = min(bonus, 8);
|
|
when C_THIEF: bonus = min(bonus, 10);
|
|
when C_ASSASSIN: bonus = min(bonus, 10);
|
|
when C_DRUID: bonus = min(bonus, 8);
|
|
when C_MONK: bonus = min(bonus, 9);
|
|
otherwise: bonus = min(bonus, 7);
|
|
}
|
|
return(bonus);
|
|
}
|
|
|
|
/*
|
|
* Give away slime-molds to monsters. If monster is friendly,
|
|
* it will give you a "regular" food ration in return. You have
|
|
* to give a slime-mold to Alteran (a unique monster) in order to
|
|
* get the special "Card of Alteran" quest item. There's no other
|
|
* way to get this artifact and remain alive.
|
|
*/
|
|
|
|
void
|
|
give(struct thing *th)
|
|
{
|
|
/*
|
|
* Find any monster within one space of you
|
|
*/
|
|
struct linked_list *ll;
|
|
struct object *lb;
|
|
register int x,y;
|
|
register struct linked_list *mon = NULL;
|
|
bool gotone = FALSE;
|
|
|
|
if (levtype != POSTLEV) { /* no monsters at trading post */
|
|
for (x = hero.x-1; x <= hero.x+1; x++) {
|
|
for (y = hero.y-1; y <= hero.y+1; y++) {
|
|
if (y < 1 || x < 0 || y > lines - 3 || x > cols - 1)
|
|
continue;
|
|
if (isalpha(mvwinch(mw, y, x))) {
|
|
if ((mon = find_mons(y, x)) != NULL) {
|
|
gotone = TRUE; /* found a monster to give away to */
|
|
th = THINGPTR(mon);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (gotone) {
|
|
if ((ll=get_item(pack, "give away", ALL, FALSE, FALSE)) != NULL) {
|
|
lb = OBJPTR(ll);
|
|
mpos = 0;
|
|
switch(lb->o_type) {
|
|
case FOOD:
|
|
switch (lb->o_which) {
|
|
case E_SLIMEMOLD: /* only slime-molds for now */
|
|
if (on(*th, CANSELL)) { /* quartermaster */
|
|
msg("%s laughs at you. ");
|
|
return;
|
|
}
|
|
if ((on(*th, ISFRIENDLY) || off(*th, ISMEAN)) &&
|
|
off(*th, ISUNIQUE) && off(*th, CANSELL)) {
|
|
turn_on(*th, ISRUN); /* we want him awake */
|
|
msg("%s accepts and promptly eats your gift of food. --More--", prname(monster_name(th), TRUE));
|
|
wait_for(' ');
|
|
del_pack(ll); /* delete slime-mold */
|
|
/* and add a food ration */
|
|
create_obj(FALSE, FOOD, E_RATION);
|
|
msg("%s gives you food in return and nods off to sleep. ", prname(monster_name(th), TRUE));
|
|
turn_off(*th, ISRUN); /* put him to sleep */
|
|
return;
|
|
}
|
|
else if (on(*th, CARRYCARD) && on(*th, ISUNIQUE)) {
|
|
/* Now you get the Card of Alteran */
|
|
msg("%s gives you a strange rectangular card. --More--", prname(monster_name(th), TRUE));
|
|
wait_for(' ');
|
|
del_pack(ll); /* get rid of slime-mold */
|
|
create_obj(FALSE, RELIC, ALTERAN_CARD);
|
|
msg("%s bids you farewell. ", prname(monster_name(th), TRUE));
|
|
killed(mon, FALSE, FALSE, FALSE);
|
|
return;
|
|
}
|
|
else if (on(*th, ISUNIQUE) && off(*th, ISMEAN)) {
|
|
/* Dragons */
|
|
msg("%s is set free by your generosity. ", prname(monster_name(th), TRUE));
|
|
del_pack(ll); /* get rid of it */
|
|
/* just let him roam around */
|
|
turn_on(*th, ISRUN);
|
|
if (on(*th, ISFLEE)) turn_off(*th, ISFLEE);
|
|
runto(th, &hero);
|
|
th->t_action = A_NIL;
|
|
return;
|
|
}
|
|
else if (on(*th, ISRUN) && off(*th, ISUNIQUE)) {
|
|
/* if NOT sleeping and not a unique */
|
|
switch (rnd(2)) {
|
|
case 0: msg("%s ignores you. ", prname(monster_name(th), TRUE));
|
|
when 1: {
|
|
msg("%s nips at your hand. ", prname(monster_name(th), TRUE));
|
|
if (rnd(100) < 10) {
|
|
del_pack(ll); /* delete it */
|
|
if (off(*th, ISMEAN)) {
|
|
msg("The slime-mold makes %s sleepy. ", prname(monster_name(th), TRUE));
|
|
/* put him to sleep */
|
|
turn_off(*th, ISRUN);
|
|
return;
|
|
}
|
|
else {
|
|
switch (rnd(2)) {
|
|
case 0: msg("%s's eyes roll back. ", prname(monster_name(th), TRUE));
|
|
when 1: msg("%s becomes wanderlust. ", prname(monster_name(th), TRUE));
|
|
}
|
|
/* just let him roam around */
|
|
turn_on(*th, ISRUN);
|
|
if (on(*th, ISFLEE))
|
|
turn_off(*th, ISFLEE);
|
|
runto(th, &hero);
|
|
th->t_action = A_NIL;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
msg("%s's mouth waters. ", prname(monster_name(th), TRUE));
|
|
/* this wakes him up */
|
|
if (off(*th, ISUNIQUE)) turn_on(*th, ISRUN);
|
|
return;
|
|
}
|
|
otherwise:
|
|
switch (rnd(3)) { /* mention food (hint hint) */
|
|
case 0: msg("You cannot give away the %s! ", foods[lb->o_which].mi_name);
|
|
when 1: msg("The %s looks rancid! ", foods[lb->o_which].mi_name);
|
|
when 2: msg("You change your mind. ");
|
|
}
|
|
return;
|
|
}
|
|
otherwise:
|
|
switch (rnd(3)) { /* do not mention other items */
|
|
case 0: msg("You feel foolish. ");
|
|
when 1: msg("You change your mind. ");
|
|
when 2: msg("%s ignores you. ", prname(monster_name(th), TRUE));
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
else msg("Your efforts are futile. ");
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* Frighten a monster. Useful for the 'good' characters.
|
|
*/
|
|
|
|
void
|
|
fright(struct thing *th)
|
|
{
|
|
/*
|
|
* Find any monster within one space of you
|
|
*/
|
|
register int x,y;
|
|
register struct linked_list *mon;
|
|
bool gotone = FALSE;
|
|
|
|
if (levtype != POSTLEV) { /* no monsters at trading post */
|
|
for (x = hero.x-1; x <= hero.x+1; x++) {
|
|
for (y = hero.y-1; y <= hero.y+1; y++) {
|
|
if (y < 1 || x < 0 || y > lines - 3 || x > cols - 1)
|
|
continue;
|
|
if (isalpha(mvwinch(mw, y, x))) {
|
|
if ((mon = find_mons(y, x)) != NULL) {
|
|
gotone = TRUE; /* found a monster to give away to */
|
|
th = THINGPTR(mon);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (gotone) { /* If 'good' character or is wearing a ring of fear */
|
|
if (player.t_ctype == C_RANGER || player.t_ctype == C_PALADIN ||
|
|
player.t_ctype == C_MONK || ISWEARING(R_FEAR) != 0) {
|
|
|
|
player.t_action = A_NIL;
|
|
player.t_no_move = movement(&player);
|
|
switch (player.t_ctype) {
|
|
case C_FIGHTER: /* loss of strength */
|
|
pstats.s_str--;
|
|
if (pstats.s_str < 3) pstats.s_str = 3;
|
|
when C_RANGER: /* loss of charisma */
|
|
case C_PALADIN:
|
|
pstats.s_charisma--;
|
|
if (pstats.s_charisma < 3) pstats.s_charisma = 3;
|
|
when C_CLERIC: /* loss of wisdom */
|
|
case C_DRUID:
|
|
pstats.s_wisdom--;
|
|
if (pstats.s_wisdom < 3) pstats.s_wisdom = 3;
|
|
when C_MAGICIAN: /* loss of wisdom intelligence */
|
|
pstats.s_intel--;
|
|
if (pstats.s_intel < 3) pstats.s_intel = 3;
|
|
when C_THIEF: /* loss of dexterity */
|
|
case C_ASSASSIN:
|
|
pstats.s_dext--;
|
|
if (pstats.s_dext < 3) pstats.s_dext = 3;
|
|
when C_MONK: /* loss of constitution */
|
|
pstats.s_const--;
|
|
if (pstats.s_const < 3) pstats.s_const = 3;
|
|
otherwise: /* this msg can induce great fear */
|
|
msg("You miss. ");
|
|
}
|
|
|
|
/* Cause a panic. Good thru level 16. */
|
|
if (level < 17) {
|
|
msg("You wave your arms and yell! ");
|
|
do_panic(th->t_index);
|
|
pstats.s_hpt -= (pstats.s_hpt/2)+1;
|
|
if (pstats.s_hpt < 25) msg("You heart quivers... ");
|
|
if (pstats.s_hpt < 1) {
|
|
msg("Your heart stops!! --More--");
|
|
wait_for(' ');
|
|
pstats.s_hpt = -1;
|
|
death(D_FRIGHT);
|
|
}
|
|
return;
|
|
}
|
|
else {
|
|
/* He can't do it after level 16 */
|
|
switch (rnd(20)) {
|
|
case 0: case 2:
|
|
msg("You stamp your foot!! ");
|
|
when 4: case 8:
|
|
msg("%s laughs at you! ",prname(monster_name(th),TRUE));
|
|
when 10: case 12:
|
|
msg("You forget what you are doing? ");
|
|
otherwise:
|
|
msg(nothing);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
else {
|
|
switch (rnd(25)) {
|
|
case 0: case 2: case 4:
|
|
msg("You motion angrily! ");
|
|
when 6: case 8: case 10:
|
|
msg("You can't frighten anything. ");
|
|
when 12: case 14: case 16:
|
|
msg("Your puff up your face. ");
|
|
otherwise:
|
|
msg(nothing);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
else {
|
|
msg("There is nothing to fear but fear itself. ");
|
|
return;
|
|
}
|
|
}
|
|
|
|
/* Routines for thieves */
|
|
|
|
/*
|
|
* gsense: Sense gold
|
|
*/
|
|
|
|
void
|
|
gsense(void)
|
|
{
|
|
/* Thief & assassin can do this, but fighter & ranger can later */
|
|
if (player.t_ctype == C_THIEF || player.t_ctype == C_ASSASSIN ||
|
|
((player.t_ctype == C_FIGHTER || player.t_ctype == C_RANGER) &&
|
|
pstats.s_lvl >= 12)) {
|
|
read_scroll(S_GFIND, 0, FALSE);
|
|
}
|
|
else msg("You seem to have no gold sense.");
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* xsense: Sense traps
|
|
*/
|
|
|
|
void
|
|
xsense(void)
|
|
{
|
|
/* Only thief can do this, but assassin, fighter, & monk can later */
|
|
if (player.t_ctype == C_THIEF || ((player.t_ctype == C_ASSASSIN ||
|
|
player.t_ctype == C_FIGHTER || player.t_ctype == C_MONK) &&
|
|
pstats.s_lvl >= 14)) {
|
|
read_scroll(S_FINDTRAPS, 0, FALSE);
|
|
}
|
|
else msg("You seem not to be able to sense traps.");
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* steal:
|
|
* Steal in direction given in delta
|
|
*/
|
|
|
|
void
|
|
steal(void)
|
|
{
|
|
register struct linked_list *item;
|
|
register struct thing *tp;
|
|
register char *mname;
|
|
coord new_pos;
|
|
int thief_bonus = -50;
|
|
bool isinvisible = FALSE;
|
|
|
|
|
|
/* let the fighter steal after level 15 */
|
|
if (player.t_ctype == C_FIGHTER && pstats.s_lvl < 15) {
|
|
msg(nothing);
|
|
return;
|
|
}
|
|
else if (player.t_ctype != C_THIEF &&
|
|
player.t_ctype != C_ASSASSIN &&
|
|
player.t_ctype != C_FIGHTER) {
|
|
msg("Only thieves and assassins can steal.");
|
|
return;
|
|
}
|
|
if (on(player, ISBLIND)) {
|
|
msg("You can't see anything.");
|
|
return;
|
|
}
|
|
|
|
new_pos.y = hero.y + player.t_newpos.y;
|
|
new_pos.x = hero.x + player.t_newpos.x;
|
|
|
|
/* Anything there? */
|
|
if (new_pos.y < 0 || new_pos.y > lines-3 ||
|
|
new_pos.x < 0 || new_pos.x > cols-1 ||
|
|
mvwinch(mw, new_pos.y, new_pos.x) == ' ') {
|
|
msg("Nothing to steal from.");
|
|
return;
|
|
}
|
|
|
|
if ((item = find_mons(new_pos.y, new_pos.x)) == NULL)
|
|
debug("Steal from what @ %d,%d?", new_pos.y, new_pos.x);
|
|
tp = THINGPTR(item);
|
|
if (on(*tp, ISSTONE)) {
|
|
msg ("You can't steal from stone!");
|
|
return;
|
|
}
|
|
|
|
if (on(*tp, ISFLEE)) {
|
|
msg("You can't get your hand in anywhere! ");
|
|
return;
|
|
}
|
|
|
|
isinvisible = invisible(tp);
|
|
if (isinvisible) mname = "creature";
|
|
else mname = monster_name(tp);
|
|
|
|
/* Can player steal something unnoticed? */
|
|
if (player.t_ctype == C_THIEF) thief_bonus = 9;
|
|
if (player.t_ctype == C_ASSASSIN) thief_bonus = 6;
|
|
if (player.t_ctype == C_FIGHTER) thief_bonus = 3;
|
|
if (on(*tp, ISUNIQUE)) thief_bonus -= 15;
|
|
if (isinvisible) thief_bonus -= 20;
|
|
if (on(*tp, ISINWALL) && off(player, CANINWALL)) thief_bonus -= 50;
|
|
|
|
if (on(*tp, ISHELD) || tp->t_action == A_FREEZE ||
|
|
rnd(100) <
|
|
(thief_bonus + 2*dex_compute() + 5*pstats.s_lvl -
|
|
5*(tp->t_stats.s_lvl - 3))) {
|
|
register struct linked_list *s_item, *pack_ptr;
|
|
int count = 0;
|
|
unsigned long test; /* Overflow check */
|
|
|
|
s_item = NULL; /* Start stolen goods out as nothing */
|
|
|
|
/* Find a good item to take */
|
|
for (pack_ptr=tp->t_pack; pack_ptr != NULL; pack_ptr=next(pack_ptr))
|
|
if ((OBJPTR(pack_ptr))->o_type != RELIC &&
|
|
pack_ptr != tp->t_using && /* Monster can't be using it */
|
|
rnd(++count) == 0)
|
|
s_item = pack_ptr;
|
|
|
|
/*
|
|
* Find anything?
|
|
*/
|
|
if (s_item == NULL) {
|
|
msg("%s apparently has nothing to steal.", prname(mname, TRUE));
|
|
return;
|
|
}
|
|
|
|
/* Take it from monster */
|
|
if (tp->t_pack) detach(tp->t_pack, s_item);
|
|
|
|
/* Recalculate the monster's encumberance */
|
|
updpack(TRUE, tp);
|
|
|
|
/* Give it to player */
|
|
if (add_pack(s_item, FALSE) == FALSE) {
|
|
(OBJPTR(s_item))->o_pos = hero;
|
|
fall(s_item, TRUE);
|
|
}
|
|
|
|
/* Get points for stealing -- but first check for overflow */
|
|
test = pstats.s_exp + tp->t_stats.s_exp/2;
|
|
if (test > pstats.s_exp) pstats.s_exp = test;
|
|
|
|
/*
|
|
* Do adjustments if player went up a level
|
|
*/
|
|
check_level();
|
|
}
|
|
|
|
else {
|
|
msg("Your attempt fails.");
|
|
|
|
/* Annoy monster (maybe) */
|
|
if (rnd(40) >= dex_compute() + thief_bonus) {
|
|
/*
|
|
* If this is a charmed creature, there is a chance it
|
|
* will become uncharmed.
|
|
*/
|
|
if (on(*tp, ISCHARMED) && save(VS_MAGIC, tp, 0)) {
|
|
msg("The eyes of %s turn clear.", prname(mname, FALSE));
|
|
turn_off(*tp, ISCHARMED);
|
|
}
|
|
if (on(*tp, CANSELL)) {
|
|
turn_off(*tp, CANSELL);
|
|
tp->t_action = A_NIL;
|
|
tp->t_movement = 0;
|
|
if (rnd(100) < 50) /* make him steal something */
|
|
turn_on(*tp, STEALMAGIC);
|
|
else
|
|
turn_on(*tp, STEALGOLD);
|
|
if (!isinvisible)
|
|
msg("%s looks insulted.", prname(mname, TRUE));
|
|
}
|
|
runto(tp, &hero);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Take charmed monsters with you via up or down commands.
|
|
*/
|
|
|
|
void
|
|
take_with(void)
|
|
{
|
|
register struct thing *tp;
|
|
register struct linked_list *item;
|
|
struct linked_list *nitem;
|
|
register int t;
|
|
|
|
t = 0;
|
|
for (item = mlist; item != NULL; item = nitem) {
|
|
nitem = next(item);
|
|
t++;
|
|
if (t > 5) break;
|
|
tp = THINGPTR(item);
|
|
if (on(*tp, ISCHARMED)) {
|
|
monsters[tp->t_index].m_normal = TRUE;
|
|
turn_on(*tp, ISELSEWHERE);
|
|
detach(mlist, item);
|
|
attach(tlist, item); /* remember him next level */
|
|
check_residue(tp);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* this routine lets the player pick the spell that they
|
|
* want to cast regardless of character class
|
|
* spells: spell list
|
|
* ability: spell ability
|
|
* num_spells: number of spells that can be cast
|
|
* power: spell power
|
|
* prompt: prompt for spell list
|
|
* type: type of thing--> spell, prayer, chant
|
|
*/
|
|
|
|
bool
|
|
pick_spell(struct spells spells[], int ability, int num_spells, int power,
|
|
const char *prompt, const char *type)
|
|
{
|
|
bool nohw = FALSE;
|
|
register int i;
|
|
int curlen,
|
|
maxlen = 0,
|
|
dummy = 0,
|
|
which_spell,
|
|
spell_left;
|
|
if (cur_misc[WEAR_CLOAK] != NULL &&
|
|
cur_misc[WEAR_CLOAK]->o_which == MM_R_POWERLESS) {
|
|
msg("You can't seem to start a %s!", type);
|
|
return(FALSE);
|
|
}
|
|
|
|
/* Prompt for spells */
|
|
msg("Which %s are you %sing? (* for list): ", type, prompt);
|
|
|
|
which_spell = (int) (wgetch(cw) - 'a');
|
|
msg(""); /* Get rid of the prompt */
|
|
if (which_spell == (int) ESC - (int) 'a') {
|
|
after = FALSE;
|
|
return(FALSE);
|
|
}
|
|
if (which_spell >= 0 && which_spell < num_spells) nohw = TRUE;
|
|
|
|
else if (slow_invent) {
|
|
register char c;
|
|
|
|
nohw = TRUE;
|
|
do {
|
|
for (i=0; i<num_spells; i++) {
|
|
msg("");
|
|
mvwaddch(msgw, 0, 0, '[');
|
|
waddch(msgw, (char) ((int) 'a' + i));
|
|
wprintw(msgw, "] A %s of ", type);
|
|
if (spells[i].s_type == TYP_POTION)
|
|
waddstr(msgw, p_magic[spells[i].s_which].mi_name);
|
|
else if (spells[i].s_type == TYP_SCROLL)
|
|
waddstr(msgw, s_magic[spells[i].s_which].mi_name);
|
|
else if (spells[i].s_type == TYP_STICK)
|
|
waddstr(msgw, ws_magic[spells[i].s_which].mi_name);
|
|
waddstr(msgw, morestr);
|
|
wclrtobot(msgw);
|
|
clearok(msgw, FALSE);
|
|
draw(msgw);
|
|
do {
|
|
c = wgetch(cw);
|
|
} while (c != ' ' && c != ESC);
|
|
if (c == ESC)
|
|
break;
|
|
}
|
|
msg("");
|
|
wmove(msgw, 0, 0);
|
|
wprintw(msgw, "Which %s are you %sing? ", type, prompt);
|
|
clearok(msgw, FALSE);
|
|
draw(msgw);
|
|
|
|
which_spell = (int) (wgetch(cw) - 'a');
|
|
} while (which_spell != (int) (ESC - 'a') &&
|
|
(which_spell < 0 || which_spell >= num_spells));
|
|
|
|
if (which_spell == (int) (ESC - 'a')) {
|
|
mpos = 0;
|
|
msg("");
|
|
after = FALSE;
|
|
return(FALSE);
|
|
}
|
|
}
|
|
else {
|
|
/* Now display the possible spells */
|
|
wclear(hw);
|
|
touchwin(hw);
|
|
wmove(hw, 2, 0);
|
|
wprintw(hw, " Cost %c%s", toupper(*type),type+1);
|
|
mvwaddstr(hw, 3, 0,
|
|
"-----------------------------------------------");
|
|
maxlen = 47; /* Maximum width of header */
|
|
|
|
for (i=0; i<num_spells; i++) {
|
|
sprintf(prbuf, "[%c] %3d A %s of ",
|
|
(char) ((int) 'a' + i), spells[i].s_cost, type);
|
|
if (spells[i].s_type == TYP_POTION)
|
|
strcat(prbuf, p_magic[spells[i].s_which].mi_name);
|
|
else if (spells[i].s_type == TYP_SCROLL)
|
|
strcat(prbuf, s_magic[spells[i].s_which].mi_name);
|
|
else if (spells[i].s_type == TYP_STICK)
|
|
strcat(prbuf, ws_magic[spells[i].s_which].mi_name);
|
|
mvwaddstr(hw, i+4, 0, prbuf);
|
|
|
|
/* Get the length of the line */
|
|
getyx(hw, dummy, curlen);
|
|
if (maxlen < curlen) maxlen = curlen;
|
|
}
|
|
|
|
spell_left = ability - power;
|
|
if (spell_left < 0) {
|
|
spell_left = 0;
|
|
if (spell_left < -20) power = ability + 20;
|
|
}
|
|
sprintf(prbuf, "[Current %s power = %d]", type, spell_left);
|
|
|
|
mvwaddstr(hw, 0, 0, prbuf);
|
|
wprintw(hw, " Which %s are you %sing? ", type, prompt);
|
|
getyx(hw, dummy, curlen);
|
|
if (maxlen < curlen) maxlen = curlen;
|
|
|
|
/* Should we overlay? */
|
|
if (menu_overlay && num_spells + 3 < lines - 3) {
|
|
over_win(cw, hw, num_spells + 5, maxlen + 3, 0, curlen, '\0');
|
|
}
|
|
else draw(hw);
|
|
}
|
|
|
|
if (!nohw) {
|
|
which_spell = (int) (wgetch(cw) - 'a');
|
|
while (which_spell < 0 || which_spell >= num_spells) {
|
|
if (which_spell == (int) ESC - (int) 'a') {
|
|
after = FALSE;
|
|
|
|
/* Restore the screen */
|
|
if (num_spells + 3 < lines / 2) {
|
|
clearok(cw, FALSE);
|
|
touchwin(cw);
|
|
}
|
|
else restscr(cw);
|
|
return(FALSE);
|
|
}
|
|
wmove(hw, 0, 0);
|
|
wclrtoeol(hw);
|
|
wprintw(hw, "Please enter one of the listed %ss. ", type);
|
|
getyx(hw, dummy, curlen);
|
|
if (maxlen < curlen) maxlen = curlen;
|
|
|
|
/* Should we overlay? */
|
|
if (menu_overlay && num_spells + 3 < lines - 3) {
|
|
over_win(cw, hw, num_spells + 5, maxlen + 3,
|
|
0, curlen, '\0');
|
|
}
|
|
else draw(hw);
|
|
|
|
which_spell = (int) (wgetch(cw) - 'a');
|
|
}
|
|
}
|
|
|
|
/* Now restore the screen if we have to */
|
|
if (!nohw) {
|
|
if (num_spells + 3 < lines / 2) {
|
|
touchwin(cw);
|
|
clearok(cw, FALSE);
|
|
}
|
|
else {
|
|
restscr(cw);
|
|
}
|
|
}
|
|
|
|
if (spells[which_spell].s_type == TYP_STICK &&
|
|
need_dir(STICK, spells[which_spell].s_which)) {
|
|
if (!get_dir(&player.t_newpos)) {
|
|
after = FALSE;
|
|
return(FALSE);
|
|
}
|
|
}
|
|
player.t_selection = which_spell;
|
|
player.t_no_move = (which_spell/3 + 1) * movement(&player);
|
|
|
|
spell_left = dummy; /* hack to stop IRIX complaint about dummy */
|
|
/* not being used. */
|
|
return(TRUE);
|
|
}
|
|
|
|
/*
|
|
* opt_player:
|
|
* Let the player know what's happening with himself
|
|
*/
|
|
|
|
void
|
|
opt_player(void)
|
|
{
|
|
int i = 1; /* initialize counters */
|
|
int j = 2;
|
|
|
|
wclear(hw);
|
|
wmove(hw, 0, 0);
|
|
wprintw(hw, "Current player effects:");
|
|
wmove(hw, 2, 0);
|
|
|
|
/* Print a list of what is happening.
|
|
* If longer than 16 lines, make it two columns.
|
|
* Currently, a maximum of 32 (out of 39) "effects"
|
|
* can be happening all at once to a player.
|
|
*/
|
|
|
|
/* 1 - Sense gold */
|
|
if (player.t_ctype == C_THIEF || player.t_ctype == C_ASSASSIN ||
|
|
((player.t_ctype == C_FIGHTER || player.t_ctype == C_RANGER) &&
|
|
pstats.s_lvl >= 12)) {
|
|
wprintw(hw, "You can sense gold\n");
|
|
i++;
|
|
}
|
|
/* 2 - Sense traps */
|
|
if (player.t_ctype == C_THIEF || ((player.t_ctype == C_ASSASSIN ||
|
|
player.t_ctype == C_FIGHTER || player.t_ctype == C_MONK) &&
|
|
pstats.s_lvl >= 14)) {
|
|
wprintw(hw, "You can sense traps\n");
|
|
i++;
|
|
}
|
|
/* 3 - Steal */
|
|
if (player.t_ctype == C_THIEF || player.t_ctype == C_ASSASSIN ||
|
|
(player.t_ctype == C_FIGHTER && pstats.s_lvl >= 15)) {
|
|
wprintw(hw, "You can steal\n");
|
|
i++;
|
|
}
|
|
/* 4 - Cast spells */
|
|
if (player.t_ctype == C_MAGICIAN ||
|
|
(player.t_ctype == C_RANGER && pstats.s_lvl > 1)) {
|
|
wprintw(hw, "You can cast spells\n");
|
|
i++;
|
|
}
|
|
/* 5 - Make chants */
|
|
if (player.t_ctype == C_DRUID ||
|
|
(player.t_ctype == C_MONK && pstats.s_lvl > 1)) {
|
|
wprintw(hw, "You can chant\n");
|
|
i++;
|
|
}
|
|
/* 6 - Give prayers */
|
|
if (cur_relic[HEIL_ANKH] != 0 || player.t_ctype == C_CLERIC ||
|
|
(player.t_ctype == C_PALADIN && pstats.s_lvl > 1)) {
|
|
wprintw(hw, "You can pray\n");
|
|
i++;
|
|
}
|
|
/* 7 - Affect the undead */
|
|
if (cur_relic[HEIL_ANKH] != 0 || player.t_ctype == C_CLERIC ||
|
|
(player.t_ctype == C_PALADIN && pstats.s_lvl > 4)) {
|
|
wprintw(hw, "You can affect the undead\n");
|
|
i++;
|
|
}
|
|
/* 8 - Cause fear */
|
|
if (ISWEARING(R_FEAR) != 0 || ((player.t_ctype == C_RANGER ||
|
|
player.t_ctype == C_PALADIN || player.t_ctype == C_MONK) &&
|
|
pstats.s_lvl > 1)) {
|
|
wprintw(hw, "You are fearful\n");
|
|
i++;
|
|
}
|
|
/* 9 - Confuse monster */
|
|
if (on(player, CANHUH) != 0) {
|
|
wprintw(hw, "You have multi-colored hands\n");
|
|
i++;
|
|
}
|
|
/* 10 - Confused yourself */
|
|
if (on(player, ISHUH) != 0) {
|
|
wprintw(hw, "You are confused\n");
|
|
i++;
|
|
} /* really ISHUH or ISCLEAR */
|
|
/* 11 - Clear thought */
|
|
if (on(player, ISCLEAR) != 0) {
|
|
wprintw(hw, "You are clear headed\n");
|
|
i++;
|
|
}
|
|
/* 12 - Slow */
|
|
if (on(player, ISSLOW) != 0) {
|
|
wprintw(hw, "You are moving slow\n");
|
|
i++;
|
|
} /* really ISSLOW or ISHASTE */
|
|
/* 13 - Haste */
|
|
if (on(player, ISHASTE) != 0) {
|
|
wprintw(hw, "You are moving fast\n");
|
|
i++;
|
|
}
|
|
/* 14 - Flying */
|
|
if (on(player, ISFLY) != 0) {
|
|
wprintw(hw, "You are flying\n");
|
|
i++;
|
|
}
|
|
/* 15 - Blind */
|
|
if (on(player, ISBLIND) != 0) {
|
|
wprintw(hw, "You are blind\n");
|
|
i++;
|
|
} /* really ISBLIND or CANSEE */
|
|
/* 16 - Extra sight */
|
|
if (on(player, CANSEE) != 0) {
|
|
wprintw(hw, "You have extra sight\n");
|
|
i++;
|
|
}
|
|
/* 17 - Invisibility */
|
|
if (on(player, ISINVIS) != 0) {
|
|
/* Okay, start a second column of effects to the screen. */
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You are invisible");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You are invisible\n");
|
|
i++;
|
|
}
|
|
}
|
|
/* 18 - Regeneration and vampiric regen */
|
|
if (ISWEARING(R_VAMPREGEN) != 0 || ISWEARING(R_REGEN) != 0) {
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You have regenerative powers");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You have regenerative powers\n");
|
|
i++;
|
|
}
|
|
}
|
|
/* 19 - Phasing */
|
|
if (on(player, CANINWALL) != 0) {
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You can walk through walls");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You can walk through walls\n");
|
|
i++;
|
|
}
|
|
}
|
|
/* 20 - Skill (good or bad, it won't last) */
|
|
if (find_slot(unskill) != 0) {
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You feel skillful");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You feel skillful\n");
|
|
i++;
|
|
}
|
|
}
|
|
/* 21 - Stealthy */
|
|
if (ISWEARING(R_STEALTH) != 0) {
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You have stealth");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You have stealth\n");
|
|
i++;
|
|
}
|
|
}
|
|
/* 22 - Alertness */
|
|
if (ISWEARING(R_ALERT) != 0) {
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You are awake and alert");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You are awake and alert\n");
|
|
i++;
|
|
}
|
|
}
|
|
/* 23 - Free action */
|
|
if (ISWEARING(R_FREEDOM) != 0) {
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You feel free");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You feel free\n");
|
|
i++;
|
|
}
|
|
}
|
|
/* 24 - Heroism */
|
|
if (ISWEARING(R_HEROISM) != 0) {
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You are brave");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You are brave\n");
|
|
i++;
|
|
}
|
|
}
|
|
/* 25 - Ice protection */
|
|
if (on(player, NOCOLD) != 0) {
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You are protected from ice");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You are protected from ice\n");
|
|
i++;
|
|
}
|
|
}
|
|
/* 26 - Fire protection */
|
|
if (on(player, NOFIRE) != 0) {
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You are protected from fire");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You are protected from fire\n");
|
|
i++;
|
|
}
|
|
}
|
|
/* 27 - Lightning protection */
|
|
if (on(player, NOBOLT) != 0) {
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You are protected from lightning");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You are protected from lightning\n");
|
|
i++;
|
|
}
|
|
}
|
|
/* 28 - Gas protection */
|
|
if (on(player, NOGAS) != 0) {
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You are protected from gas");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You are protected from gas\n");
|
|
i++;
|
|
}
|
|
}
|
|
/* 29 - Acid protection */
|
|
if (on(player, NOACID) != 0) {
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You are protected from acid");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You are protected from acid\n");
|
|
i++;
|
|
}
|
|
}
|
|
/* 30 - Breath protection */
|
|
if (cur_relic[YENDOR_AMULET] != 0) {
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You are protected from monster breath");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You are protected from monster breath\n");
|
|
i++;
|
|
} /* really only YENDOR or STONEBONES */
|
|
}
|
|
/* 31 - Magic missile protection */
|
|
if (cur_relic[STONEBONES_AMULET] != 0) {
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You are protected from magic missiles");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You are protected from magic missiles\n");
|
|
i++;
|
|
}
|
|
}
|
|
/* 32 - Sustain health */
|
|
if (ISWEARING(R_HEALTH) != 0 && (off(player, HASDISEASE) &&
|
|
off(player, HASINFEST) && off(player, DOROT))) {
|
|
if (i > 16) { /* he's really healthy */
|
|
mvwaddstr(hw, j, 37, "You are in good health");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You are in good health\n");
|
|
i++;
|
|
}
|
|
}
|
|
/* 33 - Being held */
|
|
if (on(player, ISHELD) != 0) {
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You are being held");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You are being held\n");
|
|
i++;
|
|
}
|
|
}
|
|
/* 34 - Stinks */
|
|
if (on(player, HASSTINK) != 0) {
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You are affronted by a bad smell");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You are affronted by a bad smell\n");
|
|
i++;
|
|
}
|
|
}
|
|
/* 35 - Any attribute that is down */
|
|
if (pstats.s_intel < max_stats.s_intel ||
|
|
pstats.s_str < max_stats.s_str ||
|
|
pstats.s_wisdom < max_stats.s_wisdom ||
|
|
pstats.s_dext < max_stats.s_dext ||
|
|
pstats.s_const < max_stats.s_const ||
|
|
pstats.s_charisma < max_stats.s_charisma) {
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You are afflicted");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You are afflicted\n");
|
|
i++;
|
|
}
|
|
}
|
|
/* 36 - Diseased */
|
|
if (on(player, HASDISEASE) != 0) {
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You have a disease");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You have a disease\n");
|
|
i++;
|
|
}
|
|
}
|
|
/* 37 - Infested */
|
|
if (on(player, HASINFEST) != 0) {
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You have an infestation");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You have an infestation\n");
|
|
i++;
|
|
}
|
|
}
|
|
/* 38 - Body rot */
|
|
if (on(player, DOROT) != 0) {
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You have body rot");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You have body rot\n");
|
|
i++;
|
|
}
|
|
}
|
|
/* 39 - Dancing */
|
|
if (on(player, ISDANCE) != 0) {
|
|
if (i > 16) {
|
|
mvwaddstr(hw, j, 37, "You are a dancing fool");
|
|
j++;
|
|
}
|
|
else {
|
|
wprintw(hw, "You are a dancing fool\n");
|
|
i++;
|
|
}
|
|
}
|
|
if (i == 1) {
|
|
wclear(hw);
|
|
msg("No player effects. ");
|
|
return;
|
|
}
|
|
else {
|
|
if (i > 1 && i < 17) {
|
|
j = 39;
|
|
if (menu_overlay) { /* Print the list. */
|
|
wmove(hw, i+2, 0);
|
|
wprintw(hw, spacemsg);
|
|
over_win(cw, hw, i+3, j, i+2, 27, '\0');
|
|
}
|
|
else {
|
|
wmove(hw, i+2, 0);
|
|
wprintw(hw, spacemsg);
|
|
draw(hw);
|
|
}
|
|
}
|
|
else {
|
|
i = 17;
|
|
if (menu_overlay) { /* Print the list. */
|
|
wmove(hw, i+2, 0);
|
|
wprintw(hw, spacemsg);
|
|
if (j > 2) j = 78;
|
|
else j = 39;
|
|
over_win(cw, hw, i+3, j, i+2, 27, '\0');
|
|
}
|
|
else {
|
|
wmove(hw, i+2, 0);
|
|
wprintw(hw, spacemsg);
|
|
draw(hw);
|
|
}
|
|
}
|
|
wait_for(' ');
|
|
wclear(hw);
|
|
status(FALSE);
|
|
touchwin(cw);
|
|
return;
|
|
}
|
|
}
|
|
|