summaryrefslogtreecommitdiff
path: root/src/xtra2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xtra2.c')
-rw-r--r--src/xtra2.c6158
1 files changed, 0 insertions, 6158 deletions
diff --git a/src/xtra2.c b/src/xtra2.c
deleted file mode 100644
index 70978e47..00000000
--- a/src/xtra2.c
+++ /dev/null
@@ -1,6158 +0,0 @@
-/* File: xtra2.c */
-/* File: xtra2.c */
-
-/* Purpose: effects of various "objects", targetting and panel handling */
-
-/*
- * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
- *
- * This software may be copied and distributed for educational, research, and
- * not for profit purposes provided that this copyright and statement are
- * included in all such copies.
- */
-
-#include "angband.h"
-
-/*
- * Invoke The Rush
- */
-bool_ set_rush(int v)
-{
- int j;
-
- /* Invoke The Bust */
- if (!v)
- {
- p_ptr->rush = 0;
-
- j = 50 - randint(p_ptr->lev);
- set_paralyzed(j);
- set_slow(j + 50 - randint(p_ptr->lev));
- return TRUE;
- }
-
- /* When is The Bust going to happen? */
- p_ptr->rush = v;
-
- /* The bonuses of The Rush */
- set_hero(p_ptr->hero + v);
- set_tim_deadly(p_ptr->tim_deadly + v);
- set_strike(p_ptr->strike + v);
- if (magik(p_ptr->lev / 2))
- {
- set_light_speed(p_ptr->lightspeed + v);
- }
- else
- {
- set_fast(p_ptr->fast + v, 10);
- }
- if (magik(p_ptr->lev / 2)) set_tim_esp(p_ptr->tim_esp + v);
- return TRUE;
-}
-
-
-/*
- * Set "p_ptr->parasite" and "p_ptr->parasite_r_idx"
- * notice observable changes
- */
-bool_ set_parasite(int v, int r)
-{
- bool_ notice = FALSE;
-
- /* Hack -- Force good values */
- v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
-
- /* Open */
- if (v)
- {
- if (!p_ptr->parasite)
- {
- msg_print("You feel something growing in you.");
- notice = TRUE;
- }
- }
-
- /* Shut */
- else
- {
- if (p_ptr->parasite)
- {
- if (magik(80))
- {
- char r_name[80];
- int wx, wy;
- int attempts = 500;
-
- monster_race_desc(r_name, p_ptr->parasite_r_idx, 0);
-
- do
- {
- scatter(&wy, &wx, p_ptr->py, p_ptr->px, 10);
- }
- while (!(in_bounds(wy, wx) && cave_floor_bold(wy, wx)) && --attempts);
-
- if (place_monster_one(wy, wx, p_ptr->parasite_r_idx, 0, FALSE, MSTATUS_ENEMY))
- {
- cmsg_format(TERM_L_BLUE, "Your body convulses and spawns %s.", r_name);
- p_ptr->food -= 750;
- if (p_ptr->food < 100) p_ptr->food = 100;
- }
- }
- else
- {
- cmsg_print(TERM_L_BLUE, "The hideous thing growing in you seems to die.");
- }
- notice = TRUE;
- }
- }
-
- /* Use the value */
- p_ptr->parasite = v;
- p_ptr->parasite_r_idx = r;
-
- /* Nothing to notice */
- if (!notice) return (FALSE);
-
- /* Disturb */
- if (disturb_state) disturb(0, 0);
-
- /* Recalculate bonuses */
- p_ptr->update |= (PU_BONUS);
-
- /* Result */
- return (TRUE);
-}
-
-/*
- * Set a simple player field.
- */
-static bool_ set_simple_field(
- s16b *p_field,
- s16b v,
- byte activate_color,
- cptr activate_msg,
- byte deactivate_color,
- cptr deactivate_msg)
-{
- bool_ notice = FALSE;
-
- /* Hack -- Force good values */
- v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
-
- /* Open */
- if (v)
- {
- if (!*p_field)
- {
- cmsg_print(activate_color, activate_msg);
- notice = TRUE;
- }
- }
-
- /* Shut */
- else
- {
- if (*p_field)
- {
- cmsg_print(deactivate_color, deactivate_msg);
- notice = TRUE;
- }
- }
-
- /* Use the value */
- *p_field = v;
-
- /* Nothing to notice */
- if (!notice)
- return (FALSE);
-
- /* Disturb */
- if (disturb_state)
- disturb(0, 0);
-
- /* Recalculate bonuses */
- p_ptr->update |= (PU_BONUS);
-
- /* Result */
- return (TRUE);
-}
-
-/*
- * Set "p_ptr->tim_project" and others
- * notice observable changes
- */
-bool_ set_project(int v, s16b gf, s16b dam, s16b rad, s16b flag)
-{
- bool_ notice = set_simple_field(
- &p_ptr->tim_project, v,
- TERM_WHITE, "Your weapon starts glowing.",
- TERM_WHITE, "Your weapon stops glowing.");
-
- /* Use the values */
- p_ptr->tim_project_gf = gf;
- p_ptr->tim_project_dam = dam;
- p_ptr->tim_project_rad = rad;
- p_ptr->tim_project_flag = flag;
-
- /* Result */
- return notice;
-}
-
-/*
- * Set "p_ptr->tim_roots" and others
- * notice observable changes
- */
-bool_ set_roots(int v, s16b ac, s16b dam)
-{
- bool_ notice = set_simple_field(
- &p_ptr->tim_roots, v,
- TERM_WHITE, "Roots dive into the floor from your feet.",
- TERM_WHITE, "The roots of your feet suddenly vanish.");
-
- /* Use the values */
- p_ptr->tim_roots_dam = dam;
- p_ptr->tim_roots_ac = ac;
-
- /* Result */
- return notice;
-}
-
-/*
- * Set "p_ptr->tim_(magic|water)_breath" and others
- * notice observable changes
- */
-bool_ set_tim_breath(int v, bool_ magical)
-{
- if (magical)
- {
- return set_simple_field(
- &p_ptr->tim_magic_breath, v,
- TERM_WHITE, "Air seems to fill your lungs without breathing.",
- TERM_WHITE, "You need to breathe again.");
- }
- else
- {
- return set_simple_field(
- &p_ptr->tim_water_breath, v,
- TERM_WHITE, "Water seems to fill your lungs.",
- TERM_WHITE, "The water filling your lungs evaporates.");
- }
-}
-
-/*
- * Set "p_ptr->absorb_soul"
- * notice observable changes
- */
-bool_ set_absorb_soul(int v)
-{
- return set_simple_field(
- &p_ptr->absorb_soul, v,
- TERM_L_DARK, "You start absorbing the souls of your foes.",
- TERM_L_DARK, "You stop absorbing the souls of dead foes.");
-}
-
-/*
- * Set "p_ptr->disrupt_shield"
- * notice observable changes
- */
-bool_ set_disrupt_shield(int v)
-{
- return set_simple_field(
- &p_ptr->disrupt_shield, v,
- TERM_L_BLUE, "You feel invulnerable.",
- TERM_L_RED, "You are more vulnerable.");
-}
-
-/*
- * Set "p_ptr->prob_travel"
- * notice observable changes
- */
-bool_ set_prob_travel(int v)
-{
- return set_simple_field(
- &p_ptr->prob_travel, v,
- TERM_WHITE, "You feel instable.",
- TERM_WHITE, "You are more stable.");
-}
-
-/*
- * Set "p_ptr->tim_invis", and "p_ptr->tim_inv_pow",
- * notice observable changes
- */
-bool_ set_invis(int v, int p)
-{
- bool_ notice = set_simple_field(
- &p_ptr->tim_invisible, v,
- TERM_WHITE, "You feel your body fade away.",
- TERM_WHITE, "You are no longer invisible.");
-
- /* Use the power value */
- p_ptr->tim_inv_pow = p;
-
- /* Result */
- return notice;
-}
-
-/*
- * Set "p_ptr->tim_poison",
- * notice observable changes
- */
-bool_ set_poison(int v)
-{
- return set_simple_field(
- &p_ptr->tim_poison, v,
- TERM_WHITE, "Your hands are dripping with venom.",
- TERM_WHITE, "The venom source dries out.");
-}
-
-/*
- * Set "no_breeds"
- */
-bool_ set_no_breeders(int v)
-{
- return set_simple_field(
- &no_breeds, v,
- TERM_WHITE, "You feel an anti-sexual aura.",
- TERM_WHITE, "You no longer feel an anti-sexual aura.");
-}
-
-/*
- * Set "p_ptr->tim_deadly"
- */
-bool_ set_tim_deadly(int v)
-{
- return set_simple_field(
- &p_ptr->tim_deadly, v,
- TERM_WHITE, "You feel extremely accurate.",
- TERM_WHITE, "You are suddenly much less accurate.");
-}
-
-/*
- * Set "p_ptr->tim_ffall"
- */
-bool_ set_tim_ffall(int v)
-{
- return set_simple_field(
- &p_ptr->tim_ffall, v,
- TERM_WHITE, "You feel very light.",
- TERM_WHITE, "You are suddenly heavier.");
-}
-
-/*
- * Set "p_ptr->tim_fly"
- */
-bool_ set_tim_fly(int v)
-{
- return set_simple_field(
- &p_ptr->tim_fly, v,
- TERM_WHITE, "You feel able to reach the clouds.",
- TERM_WHITE, "You are suddenly a lot heavier.");
-}
-
-/*
- * Set "p_ptr->meditation"
- */
-bool_ set_meditation(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->meditation, v,
- TERM_WHITE, "You start meditating on yourself...",
- TERM_WHITE, "You stop your self meditation.");
-
- /* Recalculate bonuses */
- if (notice)
- {
- p_ptr->update |= (PU_MANA);
- }
-
- /* Result */
- return notice;
-}
-
-/*
- * Set "p_ptr->tim_reflect"
- */
-bool_ set_tim_reflect(int v)
-{
- return set_simple_field(
- &p_ptr->tim_reflect, v,
- TERM_WHITE, "You start reflecting the world around you.",
- TERM_WHITE, "You stop reflecting.");
-}
-
-/*
- * Set "p_ptr->tim_res_time"
- */
-bool_ set_tim_res_time(int v)
-{
- return set_simple_field(
- &p_ptr->tim_res_time, v,
- TERM_WHITE, "You are now protected against space-time distortions.",
- TERM_WHITE, "You are no longer protected against space-time distortions.");
-}
-
-/*
- * Set "p_ptr->tim_fire_aura"
- */
-bool_ set_tim_fire_aura(int v)
-{
- return set_simple_field(
- &p_ptr->tim_fire_aura, v,
- TERM_WHITE, "You are enveloped in flames.",
- TERM_WHITE, "You are no longer enveloped in flames.");
-}
-
-/*
- * Set "p_ptr->strike"
- */
-bool_ set_strike(int v)
-{
- return set_simple_field(
- &p_ptr->strike, v,
- TERM_WHITE, "You feel very accurate.",
- TERM_WHITE, "You are no longer very accurate.");
-}
-
-/*
- * Set "p_ptr->oppose_ld"
- */
-bool_ set_oppose_ld(int v)
-{
- return set_simple_field(
- &p_ptr->oppose_ld, v,
- TERM_WHITE, "You feel protected against light's fluctuation.",
- TERM_WHITE, "You are no longer protected against light's fluctuation.");
-}
-
-/*
- * Set "p_ptr->oppose_cc"
- */
-bool_ set_oppose_cc(int v)
-{
- return set_simple_field(
- &p_ptr->oppose_cc, v,
- TERM_WHITE, "You feel protected against raw chaos.",
- TERM_WHITE, "You are no longer protected against chaos.");
-}
-
-/*
- * Set "p_ptr->oppose_ss"
- */
-bool_ set_oppose_ss(int v)
-{
- return set_simple_field(
- &p_ptr->oppose_ss, v,
- TERM_WHITE, "You feel protected against the ravages of sound and shards.",
- TERM_WHITE, "You are no longer protected against the ravages of sound and shards.");
-}
-
-/*
- * Set "p_ptr->oppose_nex"
- */
-bool_ set_oppose_nex(int v)
-{
- return set_simple_field(
- &p_ptr->oppose_nex, v,
- TERM_WHITE, "You feel protected against the strange forces of nexus.",
- TERM_WHITE, "You are no longer protected against the strange forces of nexus.");
-}
-
-/*
- * Set "p_ptr->tim_mimic", and "p_ptr->mimic_form",
- * notice observable changes
- */
-bool_ set_mimic(int v, int p, int level)
-{
- bool_ notice = FALSE;
-
- /* Hack -- Force good values */
- v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
-
- /* Open */
- if (v)
- {
- if (!p_ptr->tim_mimic)
- {
- msg_print("You feel your body change.");
- p_ptr->mimic_form = p;
- notice = TRUE;
- }
- }
-
- /* Shut */
- else
- {
- if (p_ptr->tim_mimic)
- {
- msg_print("You are no longer transformed.");
- p_ptr->mimic_form = 0;
- notice = TRUE;
- if (p == resolve_mimic_name("Bear"))
- {
- s_info[SKILL_BEAR].hidden = TRUE;
- select_default_melee();
- }
- p = 0;
- }
- }
-
- /* Use the value */
- p_ptr->tim_mimic = v;
- p_ptr->mimic_level = level;
-
- /* Nothing to notice */
- if (!notice) return (FALSE);
-
- /* Disturb */
- if (disturb_state) disturb(0, 0);
-
- /* Redraw title */
- p_ptr->redraw |= (PR_TITLE);
-
- /* Recalculate bonuses */
- p_ptr->update |= (PU_BODY | PU_BONUS | PU_SANITY);
-
- /* Result */
- return (TRUE);
-}
-
-/*
- * Set "p_ptr->blind", notice observable changes
- *
- * Note the use of "PU_UN_VIEW", which is needed to memorize any terrain
- * features which suddenly become "visible".
- * Note that blindness is currently the only thing which can affect
- * "player_can_see_bold()".
- */
-bool_ set_blind(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->blind, v,
- TERM_WHITE, "You are blind!",
- TERM_WHITE, "You can see again.");
-
- if (notice)
- {
- /* Fully update the visuals */
- p_ptr->update |= (PU_UN_VIEW | PU_VIEW | PU_MONSTERS | PU_MON_LITE);
-
- /* Redraw map */
- p_ptr->redraw |= (PR_MAP);
-
- /* Redraw the "blind" */
- p_ptr->redraw |= (PR_BLIND);
-
- /* Window stuff */
- p_ptr->window |= (PW_OVERHEAD);
-
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-/*
- * Set "p_ptr->tim_lite", notice observable changes
- *
- * Note the use of "PU_VIEW", which is needed to
- * memorize any terrain features which suddenly become "visible".
- * Note that blindness is currently the only thing which can affect
- * "player_can_see_bold()".
- */
-bool_ set_lite(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->tim_lite, v,
- TERM_WHITE, "You suddenly seem brighter!",
- TERM_WHITE, "You are no longer bright.");
-
- if (notice)
- {
- /* Fully update the visuals */
- p_ptr->update |= (PU_VIEW | PU_MONSTERS);
-
- /* Redraw map */
- p_ptr->redraw |= (PR_MAP);
-
- /* Window stuff */
- p_ptr->window |= (PW_OVERHEAD);
-
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-/*
- * Set "p_ptr->confused", notice observable changes
- */
-bool_ set_confused(int v)
-{
- bool_ notice =
- set_simple_field(
- &p_ptr->confused, v,
- TERM_WHITE, "You are confused!",
- TERM_WHITE, "You feel less confused now.");
-
- if (notice)
- {
- /* Redraw the "confused" */
- p_ptr->redraw |= (PR_CONFUSED);
-
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-
-/*
- * Set "p_ptr->poisoned", notice observable changes
- */
-bool_ set_poisoned(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->poisoned, v,
- TERM_WHITE, "You are poisoned!",
- TERM_WHITE, "You are no longer poisoned.");
-
- if (notice)
- {
- /* Redraw the "poisoned" */
- p_ptr->redraw |= (PR_POISONED);
-
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-
-/*
- * Set "p_ptr->afraid", notice observable changes
- */
-bool_ set_afraid(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->afraid, v,
- TERM_WHITE, "You are terrified!",
- TERM_WHITE, "You feel bolder now.");
-
- if (notice)
- {
- /* Redraw the "afraid" */
- p_ptr->redraw |= (PR_AFRAID);
-
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-
-/*
- * Set "p_ptr->paralyzed", notice observable changes
- */
-bool_ set_paralyzed(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->paralyzed, v,
- TERM_WHITE, "You are paralyzed!",
- TERM_WHITE, "You can move again.");
-
- if (notice)
- {
- /* Redraw the state */
- p_ptr->redraw |= (PR_STATE);
-
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-
-/*
- * Set "p_ptr->image", notice observable changes
- *
- * Note that we must redraw the map when hallucination changes.
- */
-bool_ set_image(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->image, v,
- TERM_WHITE, "Oh, wow! Everything looks so cosmic now!",
- TERM_WHITE, "You can see clearly again.");
-
- if (notice)
- {
- /* Redraw map */
- p_ptr->redraw |= (PR_MAP);
-
- /* Update monsters */
- p_ptr->update |= (PU_MONSTERS);
-
- /* Window stuff */
- p_ptr->window |= (PW_OVERHEAD | PW_M_LIST);
-
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-/*
- * Set "p_ptr->lightspeed", notice observable changes
- */
-bool_ set_light_speed(int v)
-{
- bool_ notice =
- set_simple_field(
- &p_ptr->lightspeed, v,
- TERM_WHITE, "You feel as if time has stopped!",
- TERM_WHITE, "You feel time returning to its normal rate.");
-
- if (notice)
- {
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-bool_ set_fast(int v, int p)
-{
- bool_ notice = FALSE;
-
- /* Hack -- Force good values */
- v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
-
- /* Open */
- if (v)
- {
- if (!p_ptr->fast)
- {
- msg_print("You feel yourself moving faster!");
- notice = TRUE;
- }
- }
-
- /* Shut */
- else
- {
- if (p_ptr->fast)
- {
- msg_print("You feel yourself slow down.");
- p = 0;
- notice = TRUE;
- }
- }
-
- /* Use the value */
- p_ptr->fast = v;
- p_ptr->speed_factor = p;
-
- /* Nothing to notice */
- if (!notice) return (FALSE);
-
- /* Disturb */
- if (disturb_state) disturb(0, 0);
-
- /* Recalculate bonuses */
- p_ptr->update |= (PU_BONUS);
-
- /* Handle stuff */
- handle_stuff();
-
- /* Result */
- return (TRUE);
-}
-
-
-/*
- * Set "p_ptr->slow", notice observable changes
- */
-bool_ set_slow(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->slow, v,
- TERM_WHITE, "You feel yourself moving slower!",
- TERM_WHITE, "You feel yourself speed up.");
-
- if (notice)
- {
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-
-/*
- * Set "p_ptr->shield", notice observable changes
- */
-bool_ set_shield(int v, int p, s16b o, s16b d1, s16b d2)
-{
- bool_ notice = set_simple_field(
- &p_ptr->shield, v,
- TERM_WHITE, "A mystic shield forms around your body!",
- TERM_WHITE, "Your mystic shield crumbles away.");
-
- /* Use the values */
- p_ptr->shield_power = p;
- p_ptr->shield_opt = o;
- p_ptr->shield_power_opt = d1;
- p_ptr->shield_power_opt2 = d2;
-
- /* Notice? */
- if (notice)
- {
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-
-
-/*
- * Set "p_ptr->blessed", notice observable changes
- */
-bool_ set_blessed(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->blessed, v,
- TERM_WHITE, "You feel righteous!",
- TERM_WHITE, "The prayer has expired.");
-
- if (notice)
- {
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-
-/*
- * Set "p_ptr->hero", notice observable changes
- */
-bool_ set_hero(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->hero, v,
- TERM_WHITE, "You feel like a hero!",
- TERM_WHITE, "The heroism wears off.");
-
- if (notice)
- {
- /* Recalculate hitpoints */
- p_ptr->update |= (PU_HP);
-
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-/*
- * Set "p_ptr->holy", notice observable changes
- */
-bool_ set_holy(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->holy, v,
- TERM_WHITE, "You feel a holy aura around you!",
- TERM_WHITE, "The holy aura vanishes.");
-
- if (notice)
- {
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-/*
- * Set "p_ptr->walk_water", notice observable changes
- */
-bool_ set_walk_water(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->walk_water, v,
- TERM_WHITE, "You feel strangely buoyant!",
- TERM_WHITE, "You feel much less buoyant.");
-
- if (notice)
- {
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-/*
- * Set "p_ptr->shero", notice observable changes
- */
-bool_ set_shero(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->shero, v,
- TERM_WHITE, "You feel like a killing machine!",
- TERM_WHITE, "You feel less berserk.");
-
- if (notice)
- {
- /* Redraw map */
- p_ptr->redraw |= (PR_MAP);
-
- /* Update monsters */
- p_ptr->update |= (PU_MONSTERS | PU_HP);
-
- /* Window stuff */
- p_ptr->window |= (PW_OVERHEAD);
-
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-
-/*
- * Set "p_ptr->protevil", notice observable changes
- */
-bool_ set_protevil(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->protevil, v,
- TERM_WHITE, "You feel safe from evil!",
- TERM_WHITE, "You no longer feel safe from evil.");
-
- if (notice)
- {
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-/*
- * Set "p_ptr->protgood", notice observable changes
- */
-bool_ set_protgood(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->protgood, v,
- TERM_WHITE, "You feel safe from good!",
- TERM_WHITE, "You no longer feel safe from good.");
-
- if (notice)
- {
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-/*
- * Set "p_ptr->protundead", notice observable changes
- */
-bool_ set_protundead(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->protundead, v,
- TERM_WHITE, "You feel safe from undead!",
- TERM_WHITE, "You no longer feel safe from undead.");
-
- if (notice) {
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-/*
- * Set "p_ptr->set_shadow", notice observable changes
- */
-bool_ set_shadow(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->tim_wraith, v,
- TERM_WHITE, "You leave the physical world and turn into a wraith-being!",
- TERM_WHITE, "You feel opaque.");
-
- if (notice)
- {
- /* Redraw map */
- p_ptr->redraw |= (PR_MAP);
-
- /* Update monsters */
- p_ptr->update |= (PU_MONSTERS);
-
- /* Window stuff */
- p_ptr->window |= (PW_OVERHEAD);
-
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-
-
-
-/*
- * Set "p_ptr->invuln", notice observable changes
- */
-bool_ set_invuln(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->invuln, v,
- TERM_L_BLUE, "Invulnerability!",
- TERM_L_RED, "The invulnerability wears off.");
-
- if (notice)
- {
- /* Redraw map */
- p_ptr->redraw |= (PR_MAP);
-
- /* Update monsters */
- p_ptr->update |= (PU_MONSTERS);
-
- /* Window stuff */
- p_ptr->window |= (PW_OVERHEAD);
-
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-
-
-/*
- * Set "p_ptr->tim_esp", notice observable changes
- */
-bool_ set_tim_esp(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->tim_esp, v,
- TERM_WHITE, "You feel your consciousness expand!",
- TERM_WHITE, "Your consciousness contracts again.");
-
- if (notice)
- {
- /* Update the monsters */
- p_ptr->update |= (PU_MONSTERS);
-
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-/*
- * Set "p_ptr->tim_thunder", notice observable changes
- */
-bool_ set_tim_thunder(int v, int p1, int p2)
-{
- bool_ notice = FALSE;
-
- /* Hack -- Force good values */
- v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
-
- /* Open */
- if (v)
- {
- if (!p_ptr->tim_thunder)
- {
- msg_print("The air around you charges with lightning!");
- notice = TRUE;
- }
- }
-
- /* Shut */
- else
- {
- if (p_ptr->tim_thunder)
- {
- msg_print("The air around you discharges.");
- notice = TRUE;
- p1 = p2 = 0;
- }
- }
-
- /* Use the value */
- p_ptr->tim_thunder = v;
- p_ptr->tim_thunder_p1 = p1;
- p_ptr->tim_thunder_p2 = p2;
-
- /* Nothing to notice */
- if (!notice) return (FALSE);
-
- /* Disturb */
- if (disturb_state) disturb(0, 0);
-
- /* Recalculate bonuses */
- p_ptr->update |= (PU_BONUS);
-
- /* Update the monsters */
- p_ptr->update |= (PU_MONSTERS);
-
- /* Handle stuff */
- handle_stuff();
-
- /* Result */
- return (TRUE);
-}
-
-/*
- * Set "p_ptr->tim_invis", notice observable changes
- */
-bool_ set_tim_invis(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->tim_invis, v,
- TERM_WHITE, "Your eyes feel very sensitive!",
- TERM_WHITE, "Your eyes feel less sensitive.");
-
- if (notice)
- {
- /* Update the monsters */
- p_ptr->update |= (PU_MONSTERS);
-
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-
-/*
- * Set "p_ptr->tim_infra", notice observable changes
- */
-bool_ set_tim_infra(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->tim_infra, v,
- TERM_WHITE, "Your eyes begin to tingle!",
- TERM_WHITE, "Your eyes stop tingling.");
-
- if (notice)
- {
- /* Update the monsters */
- p_ptr->update |= (PU_MONSTERS);
-
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-
-/*
- * Set "p_ptr->tim_mental_barrier", notice observable changes
- */
-bool_ set_mental_barrier(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->tim_mental_barrier, v,
- TERM_WHITE, "Your mind grows stronger!",
- TERM_WHITE, "Your mind is no longer especially strong.");
-
- if (notice)
- {
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-/*
- * Set "p_ptr->oppose_acid", notice observable changes
- */
-bool_ set_oppose_acid(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->oppose_acid, v,
- TERM_WHITE, "You feel resistant to acid!",
- TERM_WHITE, "You feel less resistant to acid.");
-
- if (notice)
- {
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-
-/*
- * Set "p_ptr->oppose_elec", notice observable changes
- */
-bool_ set_oppose_elec(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->oppose_elec, v,
- TERM_WHITE, "You feel resistant to electricity!",
- TERM_WHITE, "You feel less resistant to electricity.");
-
- if (notice)
- {
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-
-/*
- * Set "p_ptr->oppose_fire", notice observable changes
- */
-bool_ set_oppose_fire(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->oppose_fire, v,
- TERM_WHITE, "You feel resistant to fire!",
- TERM_WHITE, "You feel less resistant to fire.");
-
- if (notice)
- {
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-
-/*
- * Set "p_ptr->oppose_cold", notice observable changes
- */
-bool_ set_oppose_cold(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->oppose_cold, v,
- TERM_WHITE, "You feel resistant to cold!",
- TERM_WHITE, "You feel less resistant to cold.");
-
- if (notice)
- {
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-
-/*
- * Set "p_ptr->oppose_pois", notice observable changes
- */
-bool_ set_oppose_pois(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->oppose_pois, v,
- TERM_WHITE, "You feel resistant to poison!",
- TERM_WHITE, "You feel less resistant to poison.");
-
- if (notice)
- {
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-
-/*
- * Set "p_ptr->tim_regen", notice observable changes
- */
-bool_ set_tim_regen(int v, int p)
-{
- bool_ notice = FALSE;
-
- /* Hack -- Force good values */
- v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
-
- /* Open */
- if (v)
- {
- if (!p_ptr->tim_regen)
- {
- msg_print("Your body regenerates much more quickly!");
- notice = TRUE;
- }
- }
-
- /* Shut */
- else
- {
- if (p_ptr->tim_regen)
- {
- p = 0;
- msg_print("Your body regenerates much more slowly.");
- notice = TRUE;
- }
- }
-
- /* Use the value */
- p_ptr->tim_regen = v;
- p_ptr->tim_regen_pow = p;
-
- /* Nothing to notice */
- if (!notice) return (FALSE);
-
- /* Disturb */
- if (disturb_state) disturb(0, 0);
-
- /* Handle stuff */
- handle_stuff();
-
- /* Result */
- return (TRUE);
-}
-
-
-/*
- * Set "p_ptr->stun", notice observable changes
- *
- * Note the special code to only notice "range" changes.
- */
-bool_ set_stun(int v)
-{
- int old_aux, new_aux;
- bool_ notice = FALSE;
-
-
- /* Hack -- Force good values */
- v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
-
- if (PRACE_FLAG(PR1_NO_STUN)) v = 0;
-
- /* Knocked out */
- if (p_ptr->stun > 100)
- {
- old_aux = 3;
- }
-
- /* Heavy stun */
- else if (p_ptr->stun > 50)
- {
- old_aux = 2;
- }
-
- /* Stun */
- else if (p_ptr->stun > 0)
- {
- old_aux = 1;
- }
-
- /* None */
- else
- {
- old_aux = 0;
- }
-
- /* Knocked out */
- if (v > 100)
- {
- new_aux = 3;
- }
-
- /* Heavy stun */
- else if (v > 50)
- {
- new_aux = 2;
- }
-
- /* Stun */
- else if (v > 0)
- {
- new_aux = 1;
- }
-
- /* None */
- else
- {
- new_aux = 0;
- }
-
- /* Increase cut */
- if (new_aux > old_aux)
- {
- /* Describe the state */
- switch (new_aux)
- {
- /* Stun */
- case 1:
- msg_print("You have been stunned.");
- break;
-
- /* Heavy stun */
- case 2:
- msg_print("You have been heavily stunned.");
- break;
-
- /* Knocked out */
- case 3:
- msg_print("You have been knocked out.");
- break;
- }
-
- if (randint(1000) < v || randint(16) == 1)
- {
-
- msg_print("A vicious blow hits your head.");
- if (randint(3) == 1)
- {
- if (!p_ptr->sustain_int)
- {
- (void) do_dec_stat(A_INT, STAT_DEC_NORMAL);
- }
- if (!p_ptr->sustain_wis)
- {
- (void) do_dec_stat(A_WIS, STAT_DEC_NORMAL);
- }
- }
- else if (randint(2) == 1)
- {
- if (!p_ptr->sustain_int)
- {
- (void) do_dec_stat(A_INT, STAT_DEC_NORMAL);
- }
- }
- else
- {
- if (!p_ptr->sustain_wis)
- {
- (void) do_dec_stat(A_WIS, STAT_DEC_NORMAL);
- }
- }
- }
-
- /* Notice */
- notice = TRUE;
- }
-
- /* Decrease cut */
- else if (new_aux < old_aux)
- {
- /* Describe the state */
- switch (new_aux)
- {
- /* None */
- case 0:
- msg_print("You are no longer stunned.");
- if (disturb_state) disturb(0, 0);
- break;
- }
-
- /* Notice */
- notice = TRUE;
- }
-
- /* Use the value */
- p_ptr->stun = v;
-
- /* No change */
- if (!notice) return (FALSE);
-
- /* Disturb */
- if (disturb_state) disturb(0, 0);
-
- /* Recalculate bonuses */
- p_ptr->update |= (PU_BONUS);
-
- /* Redraw the "stun" */
- p_ptr->redraw |= (PR_STUN);
-
- /* Handle stuff */
- handle_stuff();
-
- /* Result */
- return (TRUE);
-}
-
-
-/*
- * Set "p_ptr->cut", notice observable changes
- *
- * Note the special code to only notice "range" changes.
- */
-bool_ set_cut(int v)
-{
- int old_aux, new_aux;
-
- bool_ notice = FALSE;
-
- /* Hack -- Force good values */
- v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
-
- if (PRACE_FLAG(PR1_NO_CUT)) v = 0;
-
- /* Mortal wound */
- if (p_ptr->cut > 1000)
- {
- old_aux = 7;
- }
-
- /* Deep gash */
- else if (p_ptr->cut > 200)
- {
- old_aux = 6;
- }
-
- /* Severe cut */
- else if (p_ptr->cut > 100)
- {
- old_aux = 5;
- }
-
- /* Nasty cut */
- else if (p_ptr->cut > 50)
- {
- old_aux = 4;
- }
-
- /* Bad cut */
- else if (p_ptr->cut > 25)
- {
- old_aux = 3;
- }
-
- /* Light cut */
- else if (p_ptr->cut > 10)
- {
- old_aux = 2;
- }
-
- /* Graze */
- else if (p_ptr->cut > 0)
- {
- old_aux = 1;
- }
-
- /* None */
- else
- {
- old_aux = 0;
- }
-
- /* Mortal wound */
- if (v > 1000)
- {
- new_aux = 7;
- }
-
- /* Deep gash */
- else if (v > 200)
- {
- new_aux = 6;
- }
-
- /* Severe cut */
- else if (v > 100)
- {
- new_aux = 5;
- }
-
- /* Nasty cut */
- else if (v > 50)
- {
- new_aux = 4;
- }
-
- /* Bad cut */
- else if (v > 25)
- {
- new_aux = 3;
- }
-
- /* Light cut */
- else if (v > 10)
- {
- new_aux = 2;
- }
-
- /* Graze */
- else if (v > 0)
- {
- new_aux = 1;
- }
-
- /* None */
- else
- {
- new_aux = 0;
- }
-
- /* Increase cut */
- if (new_aux > old_aux)
- {
- /* Describe the state */
- switch (new_aux)
- {
- /* Graze */
- case 1:
- msg_print("You have been given a graze.");
- break;
-
- /* Light cut */
- case 2:
- msg_print("You have been given a light cut.");
- break;
-
- /* Bad cut */
- case 3:
- msg_print("You have been given a bad cut.");
- break;
-
- /* Nasty cut */
- case 4:
- msg_print("You have been given a nasty cut.");
- break;
-
- /* Severe cut */
- case 5:
- msg_print("You have been given a severe cut.");
- break;
-
- /* Deep gash */
- case 6:
- msg_print("You have been given a deep gash.");
- break;
-
- /* Mortal wound */
- case 7:
- msg_print("You have been given a mortal wound.");
- break;
- }
-
- /* Notice */
- notice = TRUE;
-
- if (randint(1000) < v || randint(16) == 1)
- {
- if (!p_ptr->sustain_chr)
- {
- msg_print("You have been horribly scarred.");
-
- do_dec_stat(A_CHR, STAT_DEC_NORMAL);
- }
- }
- }
-
- /* Decrease cut */
- else if (new_aux < old_aux)
- {
- /* Describe the state */
- switch (new_aux)
- {
- /* None */
- case 0:
- msg_print("You are no longer bleeding.");
- if (disturb_state) disturb(0, 0);
- break;
- }
-
- /* Notice */
- notice = TRUE;
- }
-
- /* Use the value */
- p_ptr->cut = v;
-
- /* No change */
- if (!notice) return (FALSE);
-
- /* Disturb */
- if (disturb_state) disturb(0, 0);
-
- /* Recalculate bonuses */
- p_ptr->update |= (PU_BONUS);
-
- /* Redraw the "cut" */
- p_ptr->redraw |= (PR_CUT);
-
- /* Handle stuff */
- handle_stuff();
-
- /* Result */
- return (TRUE);
-}
-
-void drop_from_wild()
-{
- /* Hack -- Not if player were in normal mode in previous turn */
- if (!p_ptr->old_wild_mode) return;
-
- if (p_ptr->wild_mode && (!dun_level))
- {
- p_ptr->wilderness_x = p_ptr->px;
- p_ptr->wilderness_y = p_ptr->py;
- change_wild_mode();
- p_ptr->energy = 100;
- energy_use = 0;
- }
-}
-
-/*
- * Set "p_ptr->food", notice observable changes
- *
- * The "p_ptr->food" variable can get as large as 20000, allowing the
- * addition of the most "filling" item, Elvish Waybread, which adds
- * 7500 food units, without overflowing the 32767 maximum limit.
- *
- * Perhaps we should disturb the player with various messages,
- * especially messages about hunger status changes. XXX XXX XXX
- *
- * Digestion of food is handled in "dungeon.c", in which, normally,
- * the player digests about 20 food units per 100 game turns, more
- * when "fast", more when "regenerating", less with "slow digestion",
- * but when the player is "gorged", he digests 100 food units per 10
- * game turns, or a full 1000 food units per 100 game turns.
- *
- * Note that the player's speed is reduced by 10 units while gorged,
- * so if the player eats a single food ration (5000 food units) when
- * full (15000 food units), he will be gorged for (5000/100)*10 = 500
- * game turns, or 500/(100/5) = 25 player turns (if nothing else is
- * affecting the player speed).
- */
-bool_ set_food(int v)
-{
- int old_aux, new_aux;
-
- bool_ notice = FALSE;
-
- /* Hack -- Force good values */
- v = (v > 20000) ? 20000 : (v < 0) ? 0 : v;
-
- /* Fainting / Starving */
- if (p_ptr->food < PY_FOOD_FAINT)
- {
- old_aux = 0;
- }
-
- /* Weak */
- else if (p_ptr->food < PY_FOOD_WEAK)
- {
- old_aux = 1;
- }
-
- /* Hungry */
- else if (p_ptr->food < PY_FOOD_ALERT)
- {
- old_aux = 2;
- }
-
- /* Normal */
- else if (p_ptr->food < PY_FOOD_FULL)
- {
- old_aux = 3;
- }
-
- /* Full */
- else if (p_ptr->food < PY_FOOD_MAX)
- {
- old_aux = 4;
- }
-
- /* Gorged */
- else
- {
- old_aux = 5;
- }
-
- /* Fainting / Starving */
- if (v < PY_FOOD_FAINT)
- {
- new_aux = 0;
- }
-
- /* Weak */
- else if (v < PY_FOOD_WEAK)
- {
- new_aux = 1;
- }
-
- /* Hungry */
- else if (v < PY_FOOD_ALERT)
- {
- new_aux = 2;
- }
-
- /* Normal */
- else if (v < PY_FOOD_FULL)
- {
- new_aux = 3;
- }
-
- /* Full */
- else if (v < PY_FOOD_MAX)
- {
- new_aux = 4;
- }
-
- /* Gorged */
- else
- {
- new_aux = 5;
- }
-
- /* Food increase */
- if (new_aux > old_aux)
- {
- /* Describe the state */
- switch (new_aux)
- {
- /* Weak */
- case 1:
- msg_print("You are still weak.");
- break;
-
- /* Hungry */
- case 2:
- msg_print("You are still hungry.");
- break;
-
- /* Normal */
- case 3:
- msg_print("You are no longer hungry.");
- break;
-
- /* Full */
- case 4:
- msg_print("You are full!");
- break;
-
- /* Bloated */
- case 5:
- msg_print("You have gorged yourself!");
- break;
- }
-
- /* Change */
- notice = TRUE;
- }
-
- /* Food decrease */
- else if (new_aux < old_aux)
- {
- /* Describe the state */
- switch (new_aux)
- {
- /* Fainting / Starving */
- case 0:
- msg_print("You are getting faint from hunger!");
- drop_from_wild();
- break;
-
- /* Weak */
- case 1:
- msg_print("You are getting weak from hunger!");
- drop_from_wild();
- break;
-
- /* Hungry */
- case 2:
- msg_print("You are getting hungry.");
- break;
-
- /* Normal */
- case 3:
- msg_print("You are no longer full.");
- break;
-
- /* Full */
- case 4:
- msg_print("You are no longer gorged.");
- break;
- }
-
- /* Change */
- notice = TRUE;
- }
-
- /* Use the value */
- p_ptr->food = v;
-
- /* Nothing to notice */
- if (!notice) return (FALSE);
-
- /* Disturb */
- if (disturb_state) disturb(0, 0);
-
- /* Recalculate bonuses */
- p_ptr->update |= (PU_BONUS);
-
- /* Redraw hunger */
- p_ptr->redraw |= (PR_HUNGER);
-
- /* Handle stuff */
- handle_stuff();
-
- /* Result */
- return (TRUE);
-}
-
-
-/*
- * Advance experience levels and print experience
- */
-void check_experience(void)
-{
- int gained = 0;
- bool_ level_reward = FALSE;
- bool_ level_corruption = FALSE;
-
-
- /* Hack -- lower limit */
- if (p_ptr->exp < 0) p_ptr->exp = 0;
-
- /* Hack -- lower limit */
- if (p_ptr->max_exp < 0) p_ptr->max_exp = 0;
-
- /* Hack -- upper limit */
- if (p_ptr->exp > PY_MAX_EXP) p_ptr->exp = PY_MAX_EXP;
-
- /* Hack -- upper limit */
- if (p_ptr->max_exp > PY_MAX_EXP) p_ptr->max_exp = PY_MAX_EXP;
-
- /* Hack -- maintain "max" experience */
- if (p_ptr->exp > p_ptr->max_exp) p_ptr->max_exp = p_ptr->exp;
-
- /* Redraw experience */
- p_ptr->redraw |= (PR_EXP);
-
- /* Handle stuff */
- handle_stuff();
-
-
- /* Lose levels while possible */
- while ((p_ptr->lev > 1) &&
- (p_ptr->exp < (player_exp[p_ptr->lev - 2] * p_ptr->expfact / 100L)))
- {
- /* Lose a level */
- p_ptr->lev--;
- gained--;
- lite_spot(p_ptr->py, p_ptr->px);
-
- /* Update some stuff */
- p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS | PU_SANITY);
-
- /* Redraw some stuff */
- p_ptr->redraw |= (PR_LEV | PR_TITLE | PR_EXP);
-
- /* Window stuff */
- p_ptr->window |= (PW_PLAYER);
-
- /* Handle stuff */
- handle_stuff();
- }
-
-
- /* Gain levels while possible */
- while ((p_ptr->lev < PY_MAX_LEVEL) && (p_ptr->lev < max_plev) &&
- (p_ptr->exp >= (player_exp[p_ptr->lev - 1] * p_ptr->expfact / 100L)))
- {
- /* Gain a level */
- p_ptr->lev++;
- gained++;
- lite_spot(p_ptr->py, p_ptr->px);
-
- /* Save the highest level */
- if (p_ptr->lev > p_ptr->max_plv)
- {
- p_ptr->max_plv = p_ptr->lev;
- if ((PRACE_FLAG(PR1_CORRUPT)) &&
- (randint(3) == 1))
- {
- level_corruption = TRUE;
- }
- }
-
- /* Sound */
- sound(SOUND_LEVEL);
-
- /* Message */
- cmsg_format(TERM_L_GREEN, "Welcome to level %d.", p_ptr->lev);
-
- if (p_ptr->skill_last_level < p_ptr->lev)
- {
- s32b pts;
- call_lua("exec_module_info", "(s)", "d", "skill_per_level", &pts);
-
- p_ptr->skill_last_level = p_ptr->lev;
- p_ptr->skill_points += pts;
- cmsg_format(TERM_L_GREEN, "You can increase %d more skills.", p_ptr->skill_points);
- p_ptr->redraw |= PR_STUDY;
- }
-
- /* Gain this level's abilities */
- apply_level_abilities(p_ptr->lev);
-
- /* If auto-note taking enabled, write a note to the file.
- * Only write this note when the level is gained for the first
- * time.
- */
- if (take_notes && auto_notes)
- {
- char note[80];
-
- /* Write note */
- sprintf(note, "Reached level %d", p_ptr->lev);
- add_note(note, 'L');
- }
-
- /* Update some stuff */
- p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS | PU_SANITY);
-
- /* Redraw some stuff */
- p_ptr->redraw |= (PR_LEV | PR_TITLE | PR_EXP);
-
- /* Window stuff */
- p_ptr->window |= (PW_PLAYER);
-
- /* Handle stuff */
- handle_stuff();
-
- if (level_reward)
- {
- gain_level_reward(0);
- level_reward = FALSE;
- }
-
- if (level_corruption)
- {
- msg_print("You feel different...");
- corrupt_corrupted();
- level_corruption = FALSE;
- }
- }
-
- /* Hook it! */
- process_hooks(HOOK_PLAYER_LEVEL, "(d)", gained);
-}
-/*
- * Advance experience levels and print experience
- */
-void check_experience_obj(object_type *o_ptr)
-{
- /* Hack -- lower limit */
- if (o_ptr->exp < 0) o_ptr->exp = 0;
-
- /* Hack -- upper limit */
- if (o_ptr->exp > PY_MAX_EXP) o_ptr->exp = PY_MAX_EXP;
-
- /* Gain levels while possible */
- while ((o_ptr->elevel < PY_MAX_LEVEL) &&
- (o_ptr->exp >= (player_exp[o_ptr->elevel - 1] * 5 / 2)))
- {
- char buf[100];
-
- /* Add a level */
- o_ptr->elevel++;
-
- /* Get object name */
- object_desc(buf, o_ptr, 1, 0);
- cmsg_format(TERM_L_BLUE, "%s gains a level!", buf);
-
- /* What does it gains ? */
- object_gain_level(o_ptr);
- }
-}
-
-
-/*
- * Gain experience (share it to objects if needed)
- */
-void gain_exp(s32b amount)
-{
- int i, num = 1;
-
- /* Count the gaining xp objects */
- for (i = INVEN_WIELD; i < INVEN_TOTAL; i++)
- {
- object_type *o_ptr = &p_ptr->inventory[i];
- u32b f1, f2, f3, f4, f5, esp;
-
- object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
-
- if (!o_ptr->k_idx) continue;
-
- if (f4 & TR4_ART_EXP) num++;
- }
-
- /* Now give the xp */
- for (i = INVEN_WIELD; i < INVEN_TOTAL; i++)
- {
- object_type *o_ptr = &p_ptr->inventory[i];
- u32b f1, f2, f3, f4, f5, esp;
-
- object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
-
- if (!o_ptr->k_idx) continue;
-
- if (f4 & TR4_ART_EXP)
- {
- o_ptr->exp += 2 * amount / (num * 3);
-
- /* Hack -- upper limit */
- if (o_ptr->exp > PY_MAX_EXP) o_ptr->exp = PY_MAX_EXP;
- }
- }
-
- if ((p_ptr->max_exp > 0) && (PRACE_FLAG(PR1_CORRUPT)))
- {
- if ((randint(p_ptr->max_exp) < amount) || (randint(12000000) < amount))
- {
- msg_print("You feel different...");
- corrupt_corrupted();
- };
- /* 12,000,000 is equal to double Morgoth's raw XP value (60,000 * his Dlev (100))*/
- };
-
- /* Gain some experience */
- p_ptr->exp += amount / num;
-
- /* Hook it! */
- process_hooks(HOOK_PLAYER_EXP, "(d)", amount / num);
-
- /* Slowly recover from experience drainage */
- if (p_ptr->exp < p_ptr->max_exp)
- {
- /* Gain max experience (20%) (was 10%) */
- p_ptr->max_exp += amount / 5;
- }
-
- /* Check Experience */
- check_experience();
-}
-
-
-/*
- * Lose experience
- */
-void lose_exp(s32b amount)
-{
- /* Never drop below zero experience */
- if (amount > p_ptr->exp) amount = p_ptr->exp;
-
- /* Lose some experience */
- p_ptr->exp -= amount;
-
- /* Hook it! */
- process_hooks(HOOK_PLAYER_EXP, "(d)", amount);
-
- /* Check Experience */
- check_experience();
-}
-
-
-
-
-/*
- * Hack -- Return the "automatic coin type" of a monster race
- * Used to allocate proper treasure when "Creeping coins" die
- *
- * XXX XXX XXX Note the use of actual "monster names"
- */
-int get_coin_type(monster_race *r_ptr)
-{
- cptr name = (r_name + r_ptr->name);
-
- /* Analyze "coin" monsters */
- if (r_ptr->d_char == '$')
- {
- /* Look for textual clues */
- if (strstr(name, " copper ")) return (2);
- if (strstr(name, " silver ")) return (5);
- if (strstr(name, " gold ")) return (10);
- if (strstr(name, " mithril ")) return (16);
- if (strstr(name, " adamantite ")) return (17);
-
- /* Look for textual clues */
- if (strstr(name, "Copper ")) return (2);
- if (strstr(name, "Silver ")) return (5);
- if (strstr(name, "Gold ")) return (10);
- if (strstr(name, "Mithril ")) return (16);
- if (strstr(name, "Adamantite ")) return (17);
- }
-
- /* Assume nothing */
- return (0);
-}
-
-/*
- * This routine handles the production of corpses/skeletons/heads/skulls
- * when a monster is killed.
- */
-void place_corpse(monster_type *m_ptr)
-{
- monster_race *r_ptr = race_inf(m_ptr);
-
- object_type *i_ptr;
- object_type object_type_body;
-
- int x = m_ptr->fx;
- int y = m_ptr->fy;
-
- /* Get local object */
- i_ptr = &object_type_body;
-
- /* It has a physical form */
- if (r_ptr->flags9 & RF9_DROP_CORPSE)
- {
- /* Wipe the object */
- object_prep(i_ptr, lookup_kind(TV_CORPSE, SV_CORPSE_CORPSE));
-
- /* Unique corpses are unique */
- if (r_ptr->flags1 & RF1_UNIQUE)
- {
- object_aware(i_ptr);
- i_ptr->name1 = 201;
- }
-
- /* Calculate length of time before decay */
- i_ptr->pval = r_ptr->weight + rand_int(r_ptr->weight);
-
- /* Set weight */
- i_ptr->weight = (r_ptr->weight + rand_int(r_ptr->weight) / 10) + 1;
-
- /* Remember what we are */
- i_ptr->pval2 = m_ptr->r_idx;
-
- /* Some hp */
- i_ptr->pval3 = ((maxroll(r_ptr->hdice, r_ptr->hside) + p_ptr->mhp) / 2);
- i_ptr->pval3 -= randint(i_ptr->pval3) / 3;
-
- i_ptr->found = OBJ_FOUND_MONSTER;
- i_ptr->found_aux1 = m_ptr->r_idx;
- i_ptr->found_aux2 = m_ptr->ego;
- i_ptr->found_aux3 = dungeon_type;
- i_ptr->found_aux4 = level_or_feat(dungeon_type, dun_level);
-
- /* Drop it in the dungeon */
- drop_near(i_ptr, -1, y, x);
- }
-
- /* The creature is an animated skeleton. */
- if (!(r_ptr->flags9 & RF9_DROP_CORPSE) && (r_ptr->flags9 & RF9_DROP_SKELETON))
- {
- /* Wipe the object */
- object_prep(i_ptr, lookup_kind(TV_CORPSE, SV_CORPSE_SKELETON));
-
- /* Unique corpses are unique */
- if (r_ptr->flags1 & RF1_UNIQUE)
- {
- object_aware(i_ptr);
- i_ptr->name1 = 201;
- }
-
- i_ptr->pval = 0;
-
- /* Set weight */
- i_ptr->weight = (r_ptr->weight / 4 + rand_int(r_ptr->weight) / 40) + 1;
-
- /* Remember what we are */
- i_ptr->pval2 = m_ptr->r_idx;
-
- i_ptr->found = OBJ_FOUND_MONSTER;
- i_ptr->found_aux1 = m_ptr->r_idx;
- i_ptr->found_aux2 = m_ptr->ego;
- i_ptr->found_aux3 = dungeon_type;
- i_ptr->found_aux4 = level_or_feat(dungeon_type, dun_level);
-
- /* Drop it in the dungeon */
- drop_near(i_ptr, -1, y, x);
- }
-
-}
-
-
-/*
- * Handle the "death" of a monster.
- *
- * Disperse treasures centered at the monster location based on the
- * various flags contained in the monster flags fields.
- *
- * Check for "Quest" completion when a quest monster is killed.
- *
- * Note that only the player can induce "monster_death()" on Uniques.
- * Thus (for now) all Quest monsters should be Uniques.
- *
- * Note that monsters can now carry objects, and when a monster dies,
- * it drops all of its objects, which may disappear in crowded rooms.
- */
-void monster_death(int m_idx)
-{
- int i, y, x, ny, nx;
-
- int dump_item = 0;
- int dump_gold = 0;
-
- s16b this_o_idx, next_o_idx = 0;
-
- monster_type *m_ptr = &m_list[m_idx];
-
- monster_race *r_ptr = race_inf(m_ptr);
-
- bool_ visible = (m_ptr->ml || (r_ptr->flags1 & (RF1_UNIQUE)));
-
-
- bool_ create_stairs = FALSE;
- int force_coin = get_coin_type(r_ptr);
-
- object_type forge;
- object_type *q_ptr;
-
- /* Get the location */
- y = m_ptr->fy;
- x = m_ptr->fx;
-
- /* Process the appropriate hooks */
- process_hooks(HOOK_MONSTER_DEATH, "(d)", m_idx);
-
- /* If companion dies, take note */
- if (m_ptr->status == MSTATUS_COMPANION) p_ptr->companion_killed++;
-
- /* Handle reviving if undead */
- if ((p_ptr->necro_extra & CLASS_UNDEAD) && p_ptr->necro_extra2)
- {
- p_ptr->necro_extra2--;
-
- if (!p_ptr->necro_extra2)
- {
- msg_print("Your death has been avenged -- you return to life.");
- p_ptr->necro_extra &= ~CLASS_UNDEAD;
-
- /* Display the hitpoints */
- p_ptr->update |= (PU_HP);
- p_ptr->redraw |= (PR_HP);
-
- /* Window stuff */
- p_ptr->window |= (PW_PLAYER);
- }
- else
- {
- msg_format("You still have to kill %d monster%s.", p_ptr->necro_extra2, (p_ptr->necro_extra2 == 1) ? "" : "s");
- }
- }
-
- /* Handle the possibility of player vanquishing arena combatant -KMW- */
- if (p_ptr->inside_arena)
- {
- p_ptr->exit_bldg = TRUE;
- msg_print("Victorious! You're on your way to becoming Champion.");
- p_ptr->arena_number++;
- }
-
- /* If the doppleganger die, the variable must be set accordingly */
- if (r_ptr->flags9 & RF9_DOPPLEGANGER) doppleganger = 0;
-
- /* Drop objects being carried */
- for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
- {
- object_type * o_ptr;
-
- /* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
-
- /* Paranoia */
- o_ptr->held_m_idx = 0;
-
- /* Get local object */
- q_ptr = &forge;
-
- /* Copy the object */
- object_copy(q_ptr, o_ptr);
-
- /* Delete the object */
- delete_object_idx(this_o_idx);
-
- if (q_ptr->tval == TV_GOLD) dump_gold++;
- else dump_item++;
-
- /* Drop it */
- drop_near(q_ptr, -1, y, x);
- }
-
- /* Forget objects */
- m_ptr->hold_o_idx = 0;
-
- /* Average dungeon and monster levels */
- object_level = (dun_level + m_ptr->level) / 2;
-
- /* Mega^2-hack -- destroying the Stormbringer gives it us! */
- if (strstr((r_name + r_ptr->name), "Stormbringer"))
- {
- /* Get local object */
- q_ptr = &forge;
-
- /* Prepare to make the Stormbringer */
- object_prep(q_ptr, lookup_kind(TV_SWORD, SV_BLADE_OF_CHAOS));
-
- /* Mega-Hack -- Name the sword */
-
- q_ptr->art_name = quark_add("'Stormbringer'");
- q_ptr->to_h = 16;
- q_ptr->to_d = 16;
- q_ptr->ds = 6;
- q_ptr->dd = 6;
- q_ptr->pval = 2;
-
- q_ptr->art_flags1 |= ( TR1_VAMPIRIC | TR1_STR | TR1_CON | TR1_BLOWS );
- q_ptr->art_flags2 |= ( TR2_FREE_ACT | TR2_HOLD_LIFE |
- TR2_RES_NEXUS | TR2_RES_CHAOS | TR2_RES_NETHER |
- TR2_RES_CONF ); /* No longer resist_disen */
- q_ptr->art_flags3 |= ( TR3_IGNORE_ACID | TR3_IGNORE_ELEC |
- TR3_IGNORE_FIRE | TR3_IGNORE_COLD);
- /* Just to be sure */
-
- q_ptr->art_flags3 |= TR3_NO_TELE; /* How's that for a downside? */
-
- /* For game balance... */
- q_ptr->art_flags3 |= (TR3_CURSED | TR3_HEAVY_CURSE);
- q_ptr->ident |= IDENT_CURSED;
-
- if (randint(2) == 1)
- q_ptr->art_flags3 |= (TR3_DRAIN_EXP);
- else
- q_ptr->art_flags3 |= (TR3_AGGRAVATE);
-
- q_ptr->found = OBJ_FOUND_MONSTER;
- q_ptr->found_aux1 = m_ptr->r_idx;
- q_ptr->found_aux2 = m_ptr->ego;
- q_ptr->found_aux3 = dungeon_type;
- q_ptr->found_aux4 = level_or_feat(dungeon_type, dun_level);
-
- /* Drop it in the dungeon */
- drop_near(q_ptr, -1, y, x);
- }
-
- /*
- * Mega^3-hack: killing a 'Warrior of the Dawn' is likely to
- * spawn another in the fallen one's place!
- */
- else if (strstr((r_name + r_ptr->name), "the Dawn"))
- {
- if (!(randint(20) == 13))
- {
- int wy = p_ptr->py, wx = p_ptr->px;
- int attempts = 100;
-
- do
- {
- scatter(&wy, &wx, p_ptr->py, p_ptr->px, 20);
- }
- while (!(in_bounds(wy, wx) && cave_floor_bold(wy, wx)) && --attempts);
-
- if (attempts > 0)
- {
- if (is_friend(m_ptr) > 0)
- {
- if (summon_specific_friendly(wy, wx, 100, SUMMON_DAWN, FALSE))
- {
- if (player_can_see_bold(wy, wx))
- msg_print ("A new warrior steps forth!");
- }
- }
- else
- {
- if (summon_specific(wy, wx, 100, SUMMON_DAWN))
- {
- if (player_can_see_bold(wy, wx))
- msg_print ("A new warrior steps forth!");
- }
- }
- }
- }
- }
-
- /* One more ultra-hack: An Unmaker goes out with a big bang! */
- else if (strstr((r_name + r_ptr->name), "Unmaker"))
- {
- int flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
- (void)project(m_idx, 6, y, x, 100, GF_CHAOS, flg);
- }
- /* Pink horrors are replaced with 2 Blue horrors */
- else if (strstr((r_name + r_ptr->name), "ink horror"))
- {
- for (i = 0; i < 2; i++)
- {
- int wy = p_ptr->py, wx = p_ptr->px;
- int attempts = 100;
-
- do
- {
- scatter(&wy, &wx, p_ptr->py, p_ptr->px, 3);
- }
- while (!(in_bounds(wy, wx) && cave_floor_bold(wy, wx)) && --attempts);
-
- if (attempts > 0)
- {
- if (summon_specific(wy, wx, 100, SUMMON_BLUE_HORROR))
- {
- if (player_can_see_bold(wy, wx))
- msg_print ("A blue horror appears!");
- }
- }
- }
- }
-
- /* Mega-Hack -- drop "winner" treasures */
- else if (r_ptr->flags1 & (RF1_DROP_CHOSEN))
- {
- if (strstr((r_name + r_ptr->name), "Morgoth, Lord of Darkness"))
- {
- /* Get local object */
- q_ptr = &forge;
-
- /* Mega-Hack -- Prepare to make "Grond" */
- object_prep(q_ptr, lookup_kind(TV_HAFTED, SV_GROND));
-
- /* Mega-Hack -- Mark this item as "Grond" */
- q_ptr->name1 = ART_GROND;
-
- /* Mega-Hack -- Actually create "Grond" */
- apply_magic(q_ptr, -1, TRUE, TRUE, TRUE);
-
- /* Drop it in the dungeon */
- drop_near(q_ptr, -1, y, x);
-
- /* Get local object */
- q_ptr = &forge;
-
- /* Mega-Hack -- Prepare to make "Morgoth" */
- object_prep(q_ptr, lookup_kind(TV_CROWN, SV_MORGOTH));
-
- /* Mega-Hack -- Mark this item as "Morgoth" */
- q_ptr->name1 = ART_MORGOTH;
-
- /* Mega-Hack -- Actually create "Morgoth" */
- apply_magic(q_ptr, -1, TRUE, TRUE, TRUE);
-
- q_ptr->found = OBJ_FOUND_MONSTER;
- q_ptr->found_aux1 = m_ptr->r_idx;
- q_ptr->found_aux2 = m_ptr->ego;
- q_ptr->found_aux3 = dungeon_type;
- q_ptr->found_aux4 = level_or_feat(dungeon_type, dun_level);
-
- /* Drop it in the dungeon */
- drop_near(q_ptr, -1, y, x);
- }
- else if (strstr((r_name + r_ptr->name), "Smeagol"))
- {
- /* Get local object */
- q_ptr = &forge;
-
- object_wipe(q_ptr);
-
- /* Mega-Hack -- Prepare to make a ring of invisibility */
- object_prep(q_ptr, lookup_kind(TV_RING, SV_RING_INVIS));
- q_ptr->number = 1;
-
- apply_magic(q_ptr, -1, TRUE, TRUE, FALSE);
-
- q_ptr->found = OBJ_FOUND_MONSTER;
- q_ptr->found_aux1 = m_ptr->r_idx;
- q_ptr->found_aux2 = m_ptr->ego;
- q_ptr->found_aux3 = dungeon_type;
- q_ptr->found_aux4 = level_or_feat(dungeon_type, dun_level);
-
- /* Drop it in the dungeon */
- drop_near(q_ptr, -1, y, x);
- }
- else if (r_ptr->flags7 & RF7_NAZGUL)
- {
- /* Get local object */
- q_ptr = &forge;
-
- object_wipe(q_ptr);
-
- /* Mega-Hack -- Prepare to make a Ring of Power */
- object_prep(q_ptr, lookup_kind(TV_RING, SV_RING_SPECIAL));
- q_ptr->number = 1;
-
- apply_magic(q_ptr, -1, TRUE, TRUE, FALSE);
-
- /* Create a random artifact */
- create_artifact(q_ptr, TRUE, FALSE);
-
- /* Save the inscription */
- q_ptr->art_name = quark_add(format("of %s", r_name + r_ptr->name));
-
- q_ptr->found = OBJ_FOUND_MONSTER;
- q_ptr->found_aux1 = m_ptr->r_idx;
- q_ptr->found_aux2 = m_ptr->ego;
- q_ptr->found_aux3 = dungeon_type;
- q_ptr->found_aux4 = level_or_feat(dungeon_type, dun_level);
-
- /* Drop it in the dungeon */
- drop_near(q_ptr, -1, y, x);
- }
- else
- {
- byte a_idx = 0;
- int chance = 0;
- int I_kind = 0;
-
- if (strstr((r_name + r_ptr->name), "Marda, rider of the Gold Laronth"))
- {
- a_idx = ART_MARDA;
- chance = 50;
- }
- else if (strstr((r_name + r_ptr->name), "Saruman of Many Colours"))
- {
- a_idx = ART_PALANTIR;
- chance = 30;
- }
- else if (strstr((r_name + r_ptr->name), "Hagen, son of Alberich"))
- {
- a_idx = ART_NIMLOTH;
- chance = 66;
- }
- else if (strstr((r_name + r_ptr->name), "Durin's Bane"))
- {
- a_idx = ART_CALRIS;
- chance = 60;
- }
- else if (strstr((r_name + r_ptr->name), "Gothmog, the High Captain of Balrogs"))
- {
- a_idx = ART_GOTHMOG;
- chance = 50;
- }
- else if (strstr((r_name + r_ptr->name), "Eol, the Dark Elf"))
- {
- a_idx = ART_ANGUIREL;
- chance = 50;
- }
-
- if ((a_idx > 0) && ((randint(99) < chance) || (wizard)))
- {
- if (a_info[a_idx].cur_num == 0)
- {
- artifact_type *a_ptr = &a_info[a_idx];
-
- /* Get local object */
- q_ptr = &forge;
-
- /* Wipe the object */
- object_wipe(q_ptr);
-
- /* Acquire the "kind" index */
- I_kind = lookup_kind(a_ptr->tval, a_ptr->sval);
-
- /* Create the artifact */
- object_prep(q_ptr, I_kind);
-
- /* Save the name */
- q_ptr->name1 = a_idx;
-
- /* Extract the fields */
- q_ptr->pval = a_ptr->pval;
- q_ptr->ac = a_ptr->ac;
- q_ptr->dd = a_ptr->dd;
- q_ptr->ds = a_ptr->ds;
- q_ptr->to_a = a_ptr->to_a;
- q_ptr->to_h = a_ptr->to_h;
- q_ptr->to_d = a_ptr->to_d;
- q_ptr->weight = a_ptr->weight;
-
- /* Hack -- acquire "cursed" flag */
- if (a_ptr->flags3 & (TR3_CURSED)) q_ptr->ident |= (IDENT_CURSED);
-
- random_artifact_resistance(q_ptr);
-
- a_info[a_idx].cur_num = 1;
-
- q_ptr->found = OBJ_FOUND_MONSTER;
- q_ptr->found_aux1 = m_ptr->r_idx;
- q_ptr->found_aux2 = m_ptr->ego;
- q_ptr->found_aux3 = dungeon_type;
- q_ptr->found_aux4 = level_or_feat(dungeon_type, dun_level);
-
- /* Drop the artifact from heaven */
- drop_near(q_ptr, -1, y, x);
- }
- }
- }
- }
-
- /* Hack - the protected monsters must be advanged */
- else if (r_ptr->flags9 & RF9_WYRM_PROTECT)
- {
- int xx = x, yy = y;
- int attempts = 100;
-
- cmsg_print(TERM_VIOLET, "This monster was under the protection of a Great Wyrm of Power!");
-
- do
- {
- scatter(&yy, &xx, y, x, 6);
- }
- while (!(in_bounds(yy, xx) && cave_floor_bold(yy, xx)) && --attempts);
-
- place_monster_aux(yy, xx, test_monster_name("Great Wyrm of Power"), FALSE, FALSE, m_ptr->status);
- }
-
- /* Let monsters explode! */
- for (i = 0; i < 4; i++)
- {
- if (m_ptr->blow[i].method == RBM_EXPLODE)
- {
- int flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
- int typ = GF_MISSILE;
- int d_dice = m_ptr->blow[i].d_dice;
- int d_side = m_ptr->blow[i].d_side;
- int damage = damroll(d_dice, d_side);
-
- switch (m_ptr->blow[i].effect)
- {
- case RBE_HURT:
- typ = GF_MISSILE;
- break;
- case RBE_POISON:
- typ = GF_POIS;
- break;
- case RBE_UN_BONUS:
- typ = GF_DISENCHANT;
- break;
- case RBE_UN_POWER:
- typ = GF_MISSILE;
- break; /* ToDo: Apply the correct effects */
- case RBE_EAT_GOLD:
- typ = GF_MISSILE;
- break;
- case RBE_EAT_ITEM:
- typ = GF_MISSILE;
- break;
- case RBE_EAT_FOOD:
- typ = GF_MISSILE;
- break;
- case RBE_EAT_LITE:
- typ = GF_MISSILE;
- break;
- case RBE_ACID:
- typ = GF_ACID;
- break;
- case RBE_ELEC:
- typ = GF_ELEC;
- break;
- case RBE_FIRE:
- typ = GF_FIRE;
- break;
- case RBE_COLD:
- typ = GF_COLD;
- break;
- case RBE_BLIND:
- typ = GF_MISSILE;
- break;
- case RBE_HALLU:
- typ = GF_CONFUSION;
- break;
- case RBE_CONFUSE:
- typ = GF_CONFUSION;
- break;
- case RBE_TERRIFY:
- typ = GF_MISSILE;
- break;
- case RBE_PARALYZE:
- typ = GF_MISSILE;
- break;
- case RBE_LOSE_STR:
- typ = GF_MISSILE;
- break;
- case RBE_LOSE_DEX:
- typ = GF_MISSILE;
- break;
- case RBE_LOSE_CON:
- typ = GF_MISSILE;
- break;
- case RBE_LOSE_INT:
- typ = GF_MISSILE;
- break;
- case RBE_LOSE_WIS:
- typ = GF_MISSILE;
- break;
- case RBE_LOSE_CHR:
- typ = GF_MISSILE;
- break;
- case RBE_LOSE_ALL:
- typ = GF_MISSILE;
- break;
- case RBE_PARASITE:
- typ = GF_MISSILE;
- break;
- case RBE_SHATTER:
- typ = GF_ROCKET;
- break;
- case RBE_EXP_10:
- typ = GF_MISSILE;
- break;
- case RBE_EXP_20:
- typ = GF_MISSILE;
- break;
- case RBE_EXP_40:
- typ = GF_MISSILE;
- break;
- case RBE_EXP_80:
- typ = GF_MISSILE;
- break;
- case RBE_DISEASE:
- typ = GF_POIS;
- break;
- case RBE_TIME:
- typ = GF_TIME;
- break;
- case RBE_SANITY:
- typ = GF_MISSILE;
- break;
- }
-
- project(m_idx, 3, y, x, damage, typ, flg);
- break;
- }
- }
-
- if ((!force_coin) && (magik(10 + get_skill_scale(SKILL_PRESERVATION, 75))) && (!(m_ptr->mflag & MFLAG_NO_DROP)))
- place_corpse(m_ptr);
-
- /* Take note of any dropped treasure */
- if (visible && (dump_item || dump_gold))
- {
- /* Take notes on treasure */
- lore_treasure(m_idx, dump_item, dump_gold);
- }
-
- /* Current quest */
- i = p_ptr->inside_quest;
-
- /* Create a magical staircase */
- if (create_stairs && (dun_level < d_info[dungeon_type].maxdepth))
- {
- int i, j;
-
- for (i = -1; i <= 1; i++)
- for (j = -1; j <= 1; j++)
- if (!(f_info[cave[y + j][x + i].feat].flags1 & FF1_PERMANENT)) cave_set_feat(y + j, x + i, d_info[dungeon_type].floor1);
-
- /* Stagger around */
- while (!cave_valid_bold(y, x))
- {
- int d = 1;
-
- /* Pick a location */
- scatter(&ny, &nx, y, x, d);
-
- /* Stagger */
- y = ny;
- x = nx;
- }
-
- /* Destroy any objects */
- delete_object(y, x);
-
- /* Explain the staircase */
- msg_print("A magical staircase appears...");
-
- /* Create stairs down */
- cave_set_feat(y, x, FEAT_MORE);
-
- /* Remember to update everything */
- p_ptr->update |= (PU_VIEW | PU_FLOW | PU_MONSTERS);
- }
-}
-
-
-
-
-/*
- * Decreases monsters hit points, handling monster death.
- *
- * We return TRUE if the monster has been killed (and deleted).
- *
- * We announce monster death (using an optional "death message"
- * if given, and a otherwise a generic killed/destroyed message).
- *
- * Only "physical attacks" can induce the "You have slain" message.
- * Missile and Spell attacks will induce the "dies" message, or
- * various "specialized" messages. Note that "You have destroyed"
- * and "is destroyed" are synonyms for "You have slain" and "dies".
- *
- * Hack -- unseen monsters yield "You have killed it." message.
- *
- * Added fear (DGK) and check whether to print fear messages -CWS
- *
- * Genericized name, sex, and capitilization -BEN-
- *
- * Hack -- we "delay" fear messages by passing around a "fear" flag.
- *
- * XXX XXX XXX Consider decreasing monster experience over time, say,
- * by using "(m_exp * m_lev * (m_lev)) / (p_lev * (m_lev + n_killed))"
- * instead of simply "(m_exp * m_lev) / (p_lev)", to make the first
- * monster worth more than subsequent monsters. This would also need
- * to induce changes in the monster recall code.
- */
-bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note)
-{
- monster_type *m_ptr = &m_list[m_idx];
- monster_race *r_ptr = race_inf(m_ptr);
- s32b div, new_exp, new_exp_frac;
-
-
- /* Redraw (later) if needed */
- if (health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
-
- /* Some mosnters are immune to death */
- if (r_ptr->flags7 & RF7_NO_DEATH) return FALSE;
-
- /* Wake it up */
- m_ptr->csleep = 0;
-
- /* Hurt it */
- m_ptr->hp -= dam;
-
- /* It is dead now */
- if (m_ptr->hp < 0)
- {
- char m_name[80];
-
- /* Lets face it, you cannot get rid of a possessor that easily */
- if (m_ptr->possessor)
- {
- ai_deincarnate(m_idx);
-
- return FALSE;
- }
-
- /* Extract monster name */
- monster_desc(m_name, m_ptr, 0);
-
- if ((r_ptr->flags7 & RF7_DG_CURSE) && (randint(2) == 1))
- {
- int curses = 2 + randint(5);
-
- cmsg_format(TERM_VIOLET, "%^s puts a terrible Morgothian curse on you!", m_name);
- curse_equipment_dg(100, 50);
-
- do
- {
- activate_dg_curse();
- }
- while (--curses);
- }
-
- if (speak_unique && (r_ptr->flags2 & (RF2_CAN_SPEAK)))
- {
- char line_got[80];
- /* Dump a message */
-
- get_rnd_line("mondeath.txt", line_got);
- msg_format("%^s says: %s", m_name, line_got);
- }
-
-
- /* Make a sound */
- sound(SOUND_KILL);
-
- /* Death by Missile/Spell attack */
- if (note)
- {
- cmsg_format(TERM_L_RED, "%^s%s", m_name, note);
- }
-
- /* Death by physical attack -- invisible monster */
- else if (!m_ptr->ml)
- {
- cmsg_format(TERM_L_RED, "You have killed %s.", m_name);
- }
-
- /* Death by Physical attack -- non-living monster */
- else if ((r_ptr->flags3 & (RF3_DEMON)) ||
- (r_ptr->flags3 & (RF3_UNDEAD)) ||
- (r_ptr->flags2 & (RF2_STUPID)) ||
- (r_ptr->flags3 & (RF3_NONLIVING)) ||
- (strchr("Evg", r_ptr->d_char)))
- {
- cmsg_format(TERM_L_RED, "You have destroyed %s.", m_name);
- }
-
- /* Death by Physical attack -- living monster */
- else
- {
- cmsg_format(TERM_L_RED, "You have slain %s.", m_name);
- }
-
- /* Maximum player level */
- div = p_ptr->max_plv;
-
- if (m_ptr->status < MSTATUS_FRIEND)
- {
- /* Give some experience for the kill */
- new_exp = ((long)r_ptr->mexp * m_ptr->level) / div;
-
- /* Handle fractional experience */
- new_exp_frac = ((((long)r_ptr->mexp * m_ptr->level) % div)
- * 0x10000L / div) + p_ptr->exp_frac;
-
- /* Keep track of experience */
- if (new_exp_frac >= 0x10000L)
- {
- new_exp++;
- p_ptr->exp_frac = new_exp_frac - 0x10000L;
- }
- else
- {
- p_ptr->exp_frac = new_exp_frac;
- }
-
- /* Gain experience */
- gain_exp(new_exp);
- }
-
- if (!note)
- {
- object_type *o_ptr;
- u32b f1, f2, f3, f4, f5, esp;
-
- /* Access the weapon */
- o_ptr = &p_ptr->inventory[INVEN_WIELD];
- object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
-
- /* Can the weapon gain levels ? */
- if ((o_ptr->k_idx) && (f4 & TR4_LEVELS))
- {
- /* Give some experience for the kill */
- new_exp = ((long)r_ptr->mexp * m_ptr->level) / (div * 2);
-
- /* Gain experience */
- o_ptr->exp += new_exp;
- check_experience_obj(o_ptr);
- }
- }
-
- /* When the player kills a Unique, it stays dead */
- if (r_ptr->flags1 & (RF1_UNIQUE))
- {
- r_ptr->max_num = 0;
- }
-
- /* Generate treasure */
- monster_death(m_idx);
-
- /* Eru doesn't appreciate good monster death */
- if (r_ptr->flags3 & RF3_GOOD)
- {
- inc_piety(GOD_ERU, -7 * m_ptr->level);
- inc_piety(GOD_MANWE, -10 * m_ptr->level);
- inc_piety(GOD_MELKOR, 3 * m_ptr->level);
- }
- else
- {
- inc_piety(GOD_MELKOR, 1 + m_ptr->level / 2);
- }
-
- /* Manwe appreciate evil monster death */
- if (r_ptr->flags3 & RF3_EVIL)
- {
- int inc = m_ptr->level / 2;
-
- if (!inc) inc = 1;
- PRAY_GOD(GOD_MANWE) inc_piety(GOD_MANWE, inc);
-
- if (inc < 2) inc = 2;
- inc_piety(GOD_TULKAS, inc / 2);
- PRAY_GOD(GOD_TULKAS)
- {
- inc_piety(GOD_TULKAS, inc / 2);
- if (r_ptr->flags3 & RF3_DEMON) inc_piety(GOD_TULKAS, inc);
- }
- }
-
- /* Yavanna likes when corruption is destroyed */
- if ((r_ptr->flags3 & RF3_NONLIVING) || (r_ptr->flags3 & RF3_DEMON) || (r_ptr->flags3 & RF3_UNDEAD))
- {
- int inc = m_ptr->level / 2;
-
- if (!inc) inc = 1;
- inc_piety(GOD_YAVANNA, inc);
- }
-
- /* Yavanna doesnt like any killing in her name */
- PRAY_GOD(GOD_YAVANNA)
- {
- int inc = m_ptr->level / 2;
-
- if (!inc) inc = 1;
- inc_piety(GOD_YAVANNA, -inc);
-
- /* Killing animals in her name is a VERY bad idea */
- if (r_ptr->flags3 & RF3_ANIMAL)
- inc_piety(GOD_YAVANNA, -(inc * 3));
- }
-
- /* SHould we absorb its soul? */
- if (p_ptr->absorb_soul && (!(r_ptr->flags3 & RF3_UNDEAD)) && (!(r_ptr->flags3 & RF3_NONLIVING)))
- {
- msg_print("You absorb the life of the dying soul.");
- hp_player(1 + (m_ptr->level / 2) + get_skill_scale(SKILL_NECROMANCY, 40));
- }
-
- /*
- * XXX XXX XXX Mega-Hack -- Remove random quest rendered
- * impossible
- */
- if (r_ptr->flags1 & (RF1_UNIQUE))
- {
- int i;
-
- /* Search for all the random quests */
- for (i = 0; i < MAX_RANDOM_QUEST; i++)
- {
- random_quest *q_ptr = &random_quests[i];
-
- /* Ignore invalid entries */
- if (q_ptr->type == 0) continue;
-
- /* It's done */
- if (q_ptr->done) continue;
-
- /*
- * XXX XXX XXX Not yet completed quest is
- * to kill a unique you've just killed
- */
- if (r_ptr == &r_info[q_ptr->r_idx])
- {
- /* Invalidate it */
- q_ptr->type = 0;
- }
- }
- }
-
- /* If the player kills a Unique, and the notes options are on, write a note */
- if ((r_ptr->flags1 & RF1_UNIQUE) && take_notes && auto_notes)
- {
- char note[80];
-
- /* Get true name even if blinded/hallucinating */
- cptr monst = (r_name + r_ptr->name);
-
- /* Write note */
- sprintf(note, "Killed %s", monst);
-
- add_note(note, 'U');
- }
-
- /* Recall even invisible uniques or winners */
- if (m_ptr->ml || (r_ptr->flags1 & (RF1_UNIQUE)))
- {
- /* Count kills this life */
- if (r_ptr->r_pkills < MAX_SHORT) r_ptr->r_pkills++;
-
- /* Count kills in all lives */
- if (r_ptr->r_tkills < MAX_SHORT) r_ptr->r_tkills++;
-
- /* Hack -- Auto-recall */
- monster_race_track(m_ptr->r_idx, m_ptr->ego);
- }
-
- /* Delete the monster */
- delete_monster_idx(m_idx);
-
- /* Not afraid */
- (*fear) = FALSE;
-
- /* Monster is dead */
- return (TRUE);
- }
-
-
-#ifdef ALLOW_FEAR
-
- /* Mega-Hack -- Pain cancels fear */
- if (m_ptr->monfear && (dam > 0))
- {
- int tmp = randint(dam);
-
- /* Cure a little fear */
- if (tmp < m_ptr->monfear)
- {
- /* Reduce fear */
- m_ptr->monfear -= tmp;
- }
-
- /* Cure all the fear */
- else
- {
- /* Cure fear */
- m_ptr->monfear = 0;
-
- /* No more fear */
- (*fear) = FALSE;
- }
- }
-
- /* Sometimes a monster gets scared by damage */
- if (!m_ptr->monfear && !(r_ptr->flags3 & (RF3_NO_FEAR)))
- {
- int percentage;
-
- /* Percentage of fully healthy */
- percentage = (100L * m_ptr->hp) / m_ptr->maxhp;
-
- /*
- * Run (sometimes) if at 10% or less of max hit points,
- * or (usually) when hit for half its current hit points
- */
- if (((percentage <= 10) && (rand_int(10) < percentage)) ||
- ((dam >= m_ptr->hp) && (rand_int(100) < 80)))
- {
- /* Hack -- note fear */
- (*fear) = TRUE;
-
- /* XXX XXX XXX Hack -- Add some timed fear */
- m_ptr->monfear = (randint(10) +
- (((dam >= m_ptr->hp) && (percentage > 7)) ?
- 20 : ((11 - percentage) * 5)));
- }
- }
-
-#endif
-
-
- /* Not dead yet */
- return (FALSE);
-}
-
-
-/*
- * Get term size and calculate screen size
- */
-void get_screen_size(int *wid_p, int *hgt_p)
-{
- Term_get_size(wid_p, hgt_p);
- *hgt_p -= ROW_MAP + 1;
- *wid_p -= COL_MAP + 1;
- if (use_bigtile) *wid_p /= 2;
-}
-
-/*
- * Calculates current boundaries
- * Called below.
- */
-static void panel_bounds(void)
-{
- int wid, hgt;
-
- /* Retrieve current screen size */
- get_screen_size(&wid, &hgt);
-
- /* + 24 - 1 - 2 = + 21 */
- panel_row_max = panel_row_min + hgt - 1;
- panel_row_prt = panel_row_min - ROW_MAP;
-
- /* Paranoia -- Boundary check */
- if (panel_row_max > cur_hgt - 1) panel_row_max = cur_hgt - 1;
-
- panel_col_max = panel_col_min + wid - 1;
- panel_col_prt = panel_col_min - COL_MAP;
-
- /* Paranoia -- Boundary check */
- if (panel_col_max > cur_wid - 1) panel_col_max = cur_wid - 1;
-}
-
-
-/*
- * Handle a request to change the current panel
- *
- * Return TRUE if the panel was changed.
- *
- * Also used in do_cmd_locate()
- */
-bool_ change_panel(int dy, int dx)
-{
- int y, x;
- int wid, hgt;
-
- /* Get size */
- get_screen_size(&wid, &hgt);
-
- /* Apply the motion */
- y = panel_row_min + dy * (hgt / 2);
- x = panel_col_min + dx * (wid / 2);
-
- /* Calculate bounds */
- if (y > cur_hgt - hgt) y = cur_hgt - hgt;
- if (y < 0) y = 0;
- if (x > cur_wid - wid) x = cur_wid - wid;
- if (x < 0) x = 0;
-
- /* Handle changes */
- if ((y != panel_row_min) || (x != panel_col_min))
- {
- /* Save the new panel info */
- panel_row_min = y;
- panel_col_min = x;
-
- /* Recalculate the boundaries */
- panel_bounds();
-
- /* Update stuff */
- p_ptr->update |= (PU_MONSTERS);
-
- /* Redraw map */
- p_ptr->redraw |= (PR_MAP);
-
- /* Handle stuff */
- handle_stuff();
-
- /* Success */
- return (TRUE);
- }
-
- /* No changes */
- return (FALSE);
-}
-
-
-/*
- * Given an row (y) and col (x), this routine detects when a move
- * off the screen has occurred and figures new borders. -RAK-
- *
- * "Update" forces a "full update" to take place.
- *
- * The map is reprinted if necessary, and "TRUE" is returned.
- */
-void verify_panel(void)
-{
- int y = p_ptr->py;
- int x = p_ptr->px;
-
- int wid, hgt;
-
- int prow_min;
- int pcol_min;
-
- int panel_hgt, panel_wid;
-
- int max_prow_min;
- int max_pcol_min;
-
-
- /*
- * Make sure panel_row/col_max have correct values -- now taken care of
- * by the hook function below, which eliminates glitches, but does it
- * in a very hackish way XXX XXX XXX
- */
- /* panel_bounds(); */
-
- /* Get size */
- get_screen_size(&wid, &hgt);
-
- /* Calculate scroll amount */
- panel_hgt = hgt / 2;
- panel_wid = wid / 2;
-
- /* Upper boundary of panel_row/col_min */
- max_prow_min = cur_hgt - hgt;
- max_pcol_min = cur_wid - wid;
-
- /* Boundary check */
- if (max_prow_min < 0) max_prow_min = 0;
- if (max_pcol_min < 0) max_pcol_min = 0;
-
- /* An option: center on player */
- if (center_player)
- {
- /* Center vertically */
- prow_min = y - panel_hgt;
-
- /* Boundary check */
- if (prow_min < 0) prow_min = 0;
- else if (prow_min > max_prow_min) prow_min = max_prow_min;
-
- /* Center horizontally */
- pcol_min = x - panel_wid;
-
- /* Boundary check */
- if (pcol_min < 0) pcol_min = 0;
- else if (pcol_min > max_pcol_min) pcol_min = max_pcol_min;
- }
-
- /* No centering */
- else
- {
- prow_min = panel_row_min;
- pcol_min = panel_col_min;
-
- /* Scroll screen when 2 grids from top/bottom edge */
- if (y > panel_row_max - 2)
- {
- while (y > prow_min + hgt - 2)
- {
- prow_min += panel_hgt;
- }
-
- if (prow_min > max_prow_min) prow_min = max_prow_min;
- }
-
- if (y < panel_row_min + 2)
- {
- while (y < prow_min + 2)
- {
- prow_min -= panel_hgt;
- }
-
- if (prow_min < 0) prow_min = 0;
- }
-
- /* Scroll screen when 4 grids from left/right edge */
- if (x > panel_col_max - 4)
- {
- while (x > pcol_min + wid - 4)
- {
- pcol_min += panel_wid;
- }
-
- if (pcol_min > max_pcol_min) pcol_min = max_pcol_min;
- }
-
- if (x < panel_col_min + 4)
- {
- while (x < pcol_min + 4)
- {
- pcol_min -= panel_wid;
- }
-
- if (pcol_min < 0) pcol_min = 0;
- }
- }
-
- /* Check for "no change" */
- if ((prow_min == panel_row_min) && (pcol_min == panel_col_min)) return;
-
- /* Save the new panel info */
- panel_row_min = prow_min;
- panel_col_min = pcol_min;
-
- /* Hack -- optional disturb on "panel change" */
- if (disturb_panel && !center_player) disturb(0, 0);
-
- /* Recalculate the boundaries */
- panel_bounds();
-
- /* Update stuff */
- p_ptr->update |= (PU_MONSTERS);
-
- /* Redraw map */
- p_ptr->redraw |= (PR_MAP);
-
- /* Window stuff */
- p_ptr->window |= (PW_OVERHEAD);
-}
-
-
-/*
- * Map resizing whenever the main term changes size
- */
-void resize_map(void)
-{
- /* Only if the dungeon exists */
- if (!character_dungeon) return;
-
- /* Mega-Hack -- No panel yet, assume illegal panel */
- panel_row_min = cur_hgt;
- panel_row_max = 0;
- panel_col_min = cur_wid;
- panel_col_max = 0;
-
- /* Select player panel */
- verify_panel();
-
- /*
- * The following should be the same as the main window code
- * in the do_cmd_redraw()
- */
-
- /* Combine and reorder the pack (later) */
- p_ptr->notice |= (PN_COMBINE | PN_REORDER);
-
- /* Update torch */
- p_ptr->update |= (PU_TORCH);
-
- /* Update stuff */
- p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS | PU_POWERS |
- PU_SANITY | PU_BODY);
-
- /* Forget and update view */
- p_ptr->update |= (PU_UN_VIEW | PU_VIEW | PU_MONSTERS | PU_MON_LITE);
-
- /* Redraw everything */
- p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP);
-
- /* Hack -- update */
- handle_stuff();
-
- /* Redraw */
- Term_redraw();
-
- /* Refresh */
- Term_fresh();
-}
-
-
-/*
- * Redraw a term when it is resized
- */
-void resize_window(void)
-{
- /* Only if the dungeon exists */
- if (!character_dungeon) return;
-
- /* Hack -- Activate the Angband window for the redraw */
- Term_activate(&term_screen[0]);
-
- /* Hack -- react to changes */
- Term_xtra(TERM_XTRA_REACT, 0);
-
- /* Window stuff */
- p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
-
- /* Window stuff */
- p_ptr->window |= (PW_M_LIST | PW_MESSAGE | PW_OVERHEAD |
- PW_MONSTER | PW_OBJECT);
-
-
- /* Hack -- update */
- handle_stuff();
-
- /* Refresh */
- Term_fresh();
-}
-
-
-
-
-/*
- * Monster health description
- */
-cptr look_mon_desc(int m_idx)
-{
- monster_type *m_ptr = &m_list[m_idx];
- monster_race *r_ptr = race_inf(m_ptr);
-
- bool_ living = TRUE;
- int perc;
-
-
- /* Determine if the monster is "living" (vs "undead") */
- if (r_ptr->flags3 & (RF3_UNDEAD)) living = FALSE;
- if (r_ptr->flags3 & (RF3_DEMON)) living = FALSE;
- if (r_ptr->flags3 & (RF3_NONLIVING)) living = FALSE;
- if (strchr("Egv", r_ptr->d_char)) living = FALSE;
-
-
- /* Healthy monsters */
- if (m_ptr->hp >= m_ptr->maxhp)
- {
- /* No damage */
- return (living ? "unhurt" : "undamaged");
- }
-
-
- /* Calculate a health "percentage" */
- perc = 100L * m_ptr->hp / m_ptr->maxhp;
-
- if (perc >= 60)
- {
- return (living ? "somewhat wounded" : "somewhat damaged");
- }
-
- if (perc >= 25)
- {
- return (living ? "wounded" : "damaged");
- }
-
- if (perc >= 10)
- {
- return (living ? "badly wounded" : "badly damaged");
- }
-
- return (living ? "almost dead" : "almost destroyed");
-}
-
-
-
-/*
- * Angband sorting algorithm -- quick sort in place
- *
- * Note that the details of the data we are sorting is hidden,
- * and we rely on the "ang_sort_comp()" and "ang_sort_swap()"
- * function hooks to interact with the data, which is given as
- * two pointers, and which may have any user-defined form.
- */
-void ang_sort_aux(vptr u, vptr v, int p, int q)
-{
- int z, a, b;
-
- /* Done sort */
- if (p >= q) return;
-
- /* Pivot */
- z = p;
-
- /* Begin */
- a = p;
- b = q;
-
- /* Partition */
- while (TRUE)
- {
- /* Slide i2 */
- while (!(*ang_sort_comp)(u, v, b, z)) b--;
-
- /* Slide i1 */
- while (!(*ang_sort_comp)(u, v, z, a)) a++;
-
- /* Done partition */
- if (a >= b) break;
-
- /* Swap */
- (*ang_sort_swap)(u, v, a, b);
-
- /* Advance */
- a++, b--;
- }
-
- /* Recurse left side */
- ang_sort_aux(u, v, p, b);
-
- /* Recurse right side */
- ang_sort_aux(u, v, b + 1, q);
-}
-
-
-/*
- * Angband sorting algorithm -- quick sort in place
- *
- * Note that the details of the data we are sorting is hidden,
- * and we rely on the "ang_sort_comp()" and "ang_sort_swap()"
- * function hooks to interact with the data, which is given as
- * two pointers, and which may have any user-defined form.
- */
-void ang_sort(vptr u, vptr v, int n)
-{
- /* Sort the array */
- ang_sort_aux(u, v, 0, n - 1);
-}
-
-
-
-/*** Targetting Code ***/
-
-
-/*
- * Determine is a monster makes a reasonable target
- *
- * The concept of "targetting" was stolen from "Morgul" (?)
- *
- * The player can target any location, or any "target-able" monster.
- *
- * Currently, a monster is "target_able" if it is visible, and if
- * the player can hit it with a projection, and the player is not
- * hallucinating. This allows use of "use closest target" macros.
- *
- * Future versions may restrict the ability to target "trappers"
- * and "mimics", but the semantics is a little bit weird.
- */
-bool_ target_able(int m_idx)
-{
- monster_type *m_ptr = &m_list[m_idx];
-
- /* Monster must be alive */
- if (!m_ptr->r_idx) return (FALSE);
-
- /* Monster must be visible */
- if (!m_ptr->ml) return (FALSE);
-
- /* Monster must be projectable */
- if (!projectable(p_ptr->py, p_ptr->px, m_ptr->fy, m_ptr->fx)) return (FALSE);
-
- /* Hack -- no targeting hallucinations */
- if (p_ptr->image) return (FALSE);
-
- /* Dont target pets */
- if (is_friend(m_ptr) > 0) return (FALSE);
-
- /* Honor flag */
- if (r_info[m_ptr->r_idx].flags7 & RF7_NO_TARGET) return (FALSE);
-
- /* XXX XXX XXX Hack -- Never target trappers */
- /* if (CLEAR_ATTR && (CLEAR_CHAR)) return (FALSE); */
-
- /* Assume okay */
- return (TRUE);
-}
-
-
-
-
-/*
- * Update (if necessary) and verify (if possible) the target.
- *
- * We return TRUE if the target is "okay" and FALSE otherwise.
- */
-bool_ target_okay(void)
-{
- /* Accept stationary targets */
- if (target_who < 0) return (TRUE);
-
- /* Check moving targets */
- if (target_who > 0)
- {
- /* Accept reasonable targets */
- if (target_able(target_who))
- {
- monster_type *m_ptr = &m_list[target_who];
-
- /* Acquire monster location */
- target_row = m_ptr->fy;
- target_col = m_ptr->fx;
-
- /* Good target */
- return (TRUE);
- }
- }
-
- /* Assume no target */
- return (FALSE);
-}
-
-
-
-/*
- * Sorting hook -- comp function -- by "distance to player"
- *
- * We use "u" and "v" to point to arrays of "x" and "y" positions,
- * and sort the arrays by double-distance to the player.
- */
-static bool_ ang_sort_comp_distance(vptr u, vptr v, int a, int b)
-{
- byte *x = (byte*)(u);
- byte *y = (byte*)(v);
-
- int da, db, kx, ky;
-
- /* Absolute distance components */
- kx = x[a];
- kx -= p_ptr->px;
- kx = ABS(kx);
- ky = y[a];
- ky -= p_ptr->py;
- ky = ABS(ky);
-
- /* Approximate Double Distance to the first point */
- da = ((kx > ky) ? (kx + kx + ky) : (ky + ky + kx));
-
- /* Absolute distance components */
- kx = x[b];
- kx -= p_ptr->px;
- kx = ABS(kx);
- ky = y[b];
- ky -= p_ptr->py;
- ky = ABS(ky);
-
- /* Approximate Double Distance to the first point */
- db = ((kx > ky) ? (kx + kx + ky) : (ky + ky + kx));
-
- /* Compare the distances */
- return (da <= db);
-}
-
-
-/*
- * Sorting hook -- swap function -- by "distance to player"
- *
- * We use "u" and "v" to point to arrays of "x" and "y" positions,
- * and sort the arrays by distance to the player.
- */
-static void ang_sort_swap_distance(vptr u, vptr v, int a, int b)
-{
- byte *x = (byte*)(u);
- byte *y = (byte*)(v);
-
- byte temp;
-
- /* Swap "x" */
- temp = x[a];
- x[a] = x[b];
- x[b] = temp;
-
- /* Swap "y" */
- temp = y[a];
- y[a] = y[b];
- y[b] = temp;
-}
-
-
-
-/*
- * Hack -- help "select" a location (see below)
- */
-static s16b target_pick(int y1, int x1, int dy, int dx)
-{
- int i, v;
-
- int x2, y2, x3, y3, x4, y4;
-
- int b_i = -1, b_v = 9999;
-
-
- /* Scan the locations */
- for (i = 0; i < temp_n; i++)
- {
- /* Point 2 */
- x2 = temp_x[i];
- y2 = temp_y[i];
-
- /* Directed distance */
- x3 = (x2 - x1);
- y3 = (y2 - y1);
-
- /* Verify quadrant */
- if (dx && (x3 * dx <= 0)) continue;
- if (dy && (y3 * dy <= 0)) continue;
-
- /* Absolute distance */
- x4 = ABS(x3);
- y4 = ABS(y3);
-
- /* Verify quadrant */
- if (dy && !dx && (x4 > y4)) continue;
- if (dx && !dy && (y4 > x4)) continue;
-
- /* Approximate Double Distance */
- v = ((x4 > y4) ? (x4 + x4 + y4) : (y4 + y4 + x4));
-
- /* XXX XXX XXX Penalize location */
-
- /* Track best */
- if ((b_i >= 0) && (v >= b_v)) continue;
-
- /* Track best */
- b_i = i;
- b_v = v;
- }
-
- /* Result */
- return (b_i);
-}
-
-
-/*
- * Hack -- determine if a given location is "interesting"
- */
-static bool_ target_set_accept(int y, int x)
-{
- cave_type *c_ptr;
-
- s16b this_o_idx, next_o_idx = 0;
-
-
- /* Player grid is always interesting */
- if ((y == p_ptr->py) && (x == p_ptr->px)) return (TRUE);
-
-
- /* Handle hallucination */
- if (p_ptr->image) return (FALSE);
-
-
- /* Examine the grid */
- c_ptr = &cave[y][x];
-
- /* Visible monsters */
- if (c_ptr->m_idx && c_ptr->m_idx < max_r_idx)
- {
-
- monster_type *m_ptr = &m_list[c_ptr->m_idx];
- /* Visible monsters */
- if (m_ptr->ml) return (TRUE);
- }
-
- /* Scan all objects in the grid */
- for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
- {
- object_type * o_ptr;
-
- /* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
-
- /* Memorized object */
- if (o_ptr->marked) return (TRUE);
- }
-
- /* Interesting memorized features */
- if (c_ptr->info & (CAVE_MARK))
- {
- /* Traps are interesting */
- if (c_ptr->info & (CAVE_TRDT)) return (TRUE);
-
- /* Hack -- Doors are boring */
- if (c_ptr->feat == FEAT_OPEN) return (FALSE);
- if (c_ptr->feat == FEAT_BROKEN) return (FALSE);
- if ((c_ptr->feat >= FEAT_DOOR_HEAD) &&
- (c_ptr->feat <= FEAT_DOOR_TAIL)) return (FALSE);
-
- /* Accept 'naturally' interesting features */
- if (f_info[c_ptr->feat].flags1 & FF1_NOTICE) return (TRUE);
- }
-
- /* Nope */
- return (FALSE);
-}
-
-
-/*
- * Prepare the "temp" array for "target_set"
- *
- * Return the number of target_able monsters in the set.
- */
-static void target_set_prepare(int mode)
-{
- int y, x;
-
- /* Reset "temp" array */
- temp_n = 0;
-
- /* Scan the current panel */
- for (y = panel_row_min; y <= panel_row_max; y++)
- {
- for (x = panel_col_min; x <= panel_col_max; x++)
- {
- cave_type *c_ptr = &cave[y][x];
-
- /* Require line of sight, unless "look" is "expanded" */
- if (!expand_look && !player_has_los_bold(y, x)) continue;
-
- /* Require "interesting" contents */
- if (!target_set_accept(y, x)) continue;
-
- /* Require target_able monsters for "TARGET_KILL" */
- if ((mode & (TARGET_KILL)) && !target_able(c_ptr->m_idx)) continue;
-
- /* Save the location */
- temp_x[temp_n] = x;
- temp_y[temp_n] = y;
- temp_n++;
- }
- }
-
- /* Set the sort hooks */
- ang_sort_comp = ang_sort_comp_distance;
- ang_sort_swap = ang_sort_swap_distance;
-
- /* Sort the positions */
- ang_sort(temp_x, temp_y, temp_n);
-}
-
-
-bool_ target_object(int y, int x, int mode, cptr info, bool_ *boring,
- object_type *o_ptr, char *out_val, cptr *s1, cptr *s2, cptr *s3,
- int *query)
-{
- char o_name[80];
-
- /* Not boring */
- *boring = FALSE;
-
- /* Obtain an object description */
- object_desc(o_name, o_ptr, TRUE, 3);
-
- /* Describe the object */
- sprintf(out_val, "%s%s%s%s [%s]", *s1, *s2, *s3, o_name, info);
- prt(out_val, 0, 0);
- move_cursor_relative(y, x);
- *query = inkey();
-
- /* Always stop at "normal" keys */
- if ((*query != '\r') && (*query != '\n') && (*query != ' ')) return (TRUE);
-
- /* Sometimes stop at "space" key */
- if ((*query == ' ') && !(mode & (TARGET_LOOK))) return (TRUE);
-
- /* Change the intro */
- *s1 = "It is ";
-
- /* Plurals */
- if (o_ptr->number != 1) *s1 = "They are ";
-
- /* Preposition */
- *s2 = "on ";
- return (FALSE);
-}
-
-/*
- * Examine a grid, return a keypress.
- *
- * The "mode" argument contains the "TARGET_LOOK" bit flag, which
- * indicates that the "space" key should scan through the contents
- * of the grid, instead of simply returning immediately. This lets
- * the "look" command get complete information, without making the
- * "target" command annoying.
- *
- * The "info" argument contains the "commands" which should be shown
- * inside the "[xxx]" text. This string must never be empty, or grids
- * containing monsters will be displayed with an extra comma.
- *
- * Note that if a monster is in the grid, we update both the monster
- * recall info and the health bar info to track that monster.
- *
- * Eventually, we may allow multiple objects per grid, or objects
- * and terrain features in the same grid. XXX XXX XXX
- *
- * This function must handle blindness/hallucination.
- */
-static int target_set_aux(int y, int x, int mode, cptr info)
-{
- cave_type *c_ptr = &cave[y][x];
-
- s16b this_o_idx, next_o_idx = 0;
-
- cptr s1, s2, s3;
-
- bool_ boring;
-
- int feat;
-
- int query;
-
- char out_val[160];
-
-
- /* Repeat forever */
- while (1)
- {
- /* Paranoia */
- query = ' ';
-
- /* Assume boring */
- boring = TRUE;
-
- /* Default */
- s1 = "You see ";
- s2 = "";
- s3 = "";
-
- /* Hack -- under the player */
- if ((y == p_ptr->py) && (x == p_ptr->px))
- {
- /* Description */
- s1 = "You are ";
-
- /* Preposition */
- s2 = "on ";
- }
-
-
- /* Hack -- hallucination */
- if (p_ptr->image)
- {
- cptr name = "something strange";
-
- /* Display a message */
- sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, name, info);
- prt(out_val, 0, 0);
- move_cursor_relative(y, x);
- query = inkey();
-
- /* Stop on everything but "return" */
- if ((query != '\r') && (query != '\n')) break;
-
- /* Repeat forever */
- continue;
- }
-
-
- /* Actual monsters */
- if (c_ptr->m_idx)
- {
- monster_type *m_ptr = &m_list[c_ptr->m_idx];
- monster_race *r_ptr = race_inf(m_ptr);
-
- /* Mimics special treatment -- looks like an object */
- if ((r_ptr->flags9 & RF9_MIMIC) && (m_ptr->csleep))
- {
- object_type *o_ptr;
-
- /* Acquire object */
- o_ptr = &o_list[m_ptr->hold_o_idx];
-
- if (o_ptr->marked)
- {
- if (target_object(y, x, mode, info, &boring, o_ptr, out_val, &s1, &s2, &s3, &query)) break;
- }
- }
- else
- {
- /* Visible */
- if (m_ptr->ml)
- {
- bool_ recall = FALSE;
-
- char m_name[80];
-
- /* Not boring */
- boring = FALSE;
-
- /* Get the monster name ("a kobold") */
- monster_desc(m_name, m_ptr, 0x08);
-
- /* Hack -- track this monster race */
- monster_race_track(m_ptr->r_idx, m_ptr->ego);
-
- /* Hack -- health bar for this monster */
- health_track(c_ptr->m_idx);
-
- /* Hack -- handle stuff */
- handle_stuff();
-
- /* Interact */
- while (1)
- {
- /* Recall */
- if (recall)
- {
- /* Save */
- character_icky = TRUE;
- Term_save();
-
- /* Recall on screen */
- screen_roff(m_ptr->r_idx, m_ptr->ego, 0);
-
- /* Hack -- Complete the prompt (again) */
- Term_addstr( -1, TERM_WHITE, format(" [r,%s]", info));
-
- /* Command */
- query = inkey();
-
- /* Restore */
- Term_load();
- character_icky = FALSE;
- }
-
- /* Normal */
- else
- {
- cptr mstat;
-
- switch (m_ptr->status)
- {
- case MSTATUS_NEUTRAL:
- case MSTATUS_NEUTRAL_M:
- case MSTATUS_NEUTRAL_P:
- mstat = " (neutral) ";
- break;
- case MSTATUS_PET:
- mstat = " (pet) ";
- break;
- case MSTATUS_FRIEND:
- mstat = " (coaligned) ";
- break;
- case MSTATUS_COMPANION:
- mstat = " (companion) ";
- break;
- default:
- mstat = " ";
- break;
- }
- if (m_ptr->mflag & MFLAG_PARTIAL) mstat = " (partial) ";
-
- /* Describe, and prompt for recall */
- sprintf(out_val, "%s%s%s%s (level %d, %s%s)%s%s[r,%s]",
- s1, s2, s3, m_name,
- m_ptr->level, look_mon_desc(c_ptr->m_idx),
- (m_ptr->mflag & MFLAG_QUEST) ? ", quest" : "",
- (m_ptr->smart & SM_CLONED ? " (clone)" : ""),
- (mstat), info);
-
- prt(out_val, 0, 0);
-
- /* Place cursor */
- move_cursor_relative(y, x);
-
- /* Command */
- query = inkey();
- }
-
- /* Normal commands */
- if (query != 'r') break;
-
- /* Toggle recall */
- recall = !recall;
- }
-
- /* Always stop at "normal" keys */
- if ((query != '\r') && (query != '\n') && (query != ' ')) break;
-
- /* Sometimes stop at "space" key */
- if ((query == ' ') && !(mode & (TARGET_LOOK))) break;
-
- /* Change the intro */
- s1 = "It is ";
-
- /* Hack -- take account of gender */
- if (r_ptr->flags1 & (RF1_FEMALE)) s1 = "She is ";
- else if (r_ptr->flags1 & (RF1_MALE)) s1 = "He is ";
-
- /* Use a preposition */
- s2 = "carrying ";
-
- /* Scan all objects being carried */
- for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
- {
- char o_name[80];
-
- object_type *o_ptr;
-
- /* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
-
- /* Obtain an object description */
- object_desc(o_name, o_ptr, TRUE, 3);
-
- /* Describe the object */
- sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, o_name, info);
- prt(out_val, 0, 0);
- move_cursor_relative(y, x);
- query = inkey();
-
- /* Always stop at "normal" keys */
- if ((query != '\r') && (query != '\n') && (query != ' ')) break;
-
- /* Sometimes stop at "space" key */
- if ((query == ' ') && !(mode & (TARGET_LOOK))) break;
-
- /* Change the intro */
- s2 = "also carrying ";
- }
-
- /* Double break */
- if (this_o_idx) break;
-
- /* Use a preposition */
- s2 = "on ";
- }
- }
- }
-
-
-
- /* Scan all objects in the grid */
- for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
- {
- object_type * o_ptr;
-
- /* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
-
- /* Describe it */
- if (o_ptr->marked)
- {
- if (target_object(y, x, mode, info, &boring, o_ptr, out_val, &s1, &s2, &s3, &query)) break;
- }
- }
-
- /* Double break */
- if (this_o_idx) break;
-
- /* Actual traps */
- if ((c_ptr->info & (CAVE_TRDT)) && c_ptr->t_idx)
- {
- cptr name = "a trap", s4;
-
- /* Name trap */
- if (t_info[c_ptr->t_idx].ident)
- {
- s4 = format("(%s)", t_name + t_info[c_ptr->t_idx].name);
- }
- else
- {
- s4 = "an unknown trap";
- }
-
- /* Display a message */
- sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, name, s4);
- prt(out_val, 0, 0);
- move_cursor_relative(y, x);
- query = inkey();
-
- /* Stop on everything but "return" */
- if ((query != '\r') && (query != '\n')) break;
-
- /* Repeat forever */
- continue;
- }
-
- /* Feature (apply "mimic") */
- if (c_ptr->mimic)
- {
- feat = c_ptr->mimic;
- }
- else
- {
- feat = f_info[c_ptr->feat].mimic;
- }
-
- /* Require knowledge about grid, or ability to see grid */
- if (!(c_ptr->info & (CAVE_MARK)) && !player_can_see_bold(y, x))
- {
- /* Forget feature */
- feat = FEAT_NONE;
- }
-
- /* Terrain feature if needed */
- if (boring || (feat >= FEAT_GLYPH))
- {
- cptr name;
-
- /* Hack -- special handling for building doors */
- if (feat == FEAT_SHOP)
- {
- name = st_name + st_info[c_ptr->special].name;
- }
- else
- {
- name = f_name + f_info[feat].name;
- }
-
- /* Hack -- handle unknown grids */
- if (feat == FEAT_NONE) name = "unknown grid";
-
- /* Pick a prefix */
- if (*s2 &&
- (((feat >= FEAT_MINOR_GLYPH) &&
- (feat <= FEAT_PATTERN_XTRA2)) ||
- (feat == FEAT_DIRT) ||
- (feat == FEAT_GRASS) ||
- (feat == FEAT_FLOWER))) s2 = "on ";
- else if (*s2 && (feat == FEAT_SMALL_TREES)) s2 = "by ";
- else if (*s2 && (feat >= FEAT_DOOR_HEAD)) s2 = "in ";
-
- /* Pick proper indefinite article */
- s3 = (is_a_vowel(name[0])) ? "an " : "a ";
-
- /* Hack -- special introduction for store & building doors */
- if (feat == FEAT_SHOP)
- {
- s3 = "the entrance to the ";
- }
-
- if ((feat == FEAT_MORE) && c_ptr->special)
- {
- s3 = "";
- name = d_text + d_info[c_ptr->special].text;
- }
-
- if (p_ptr->wild_mode && (feat == FEAT_TOWN))
- {
- s3 = "";
- name = format("%s(%s)",
- wf_name + wf_info[wild_map[y][x].feat].name,
- wf_text + wf_info[wild_map[y][x].feat].text);
- }
-
- if ((feat == FEAT_FOUNTAIN) && (c_ptr->info & CAVE_IDNT))
- {
- object_kind *k_ptr;
- int tv, sv;
-
- if (c_ptr->special <= SV_POTION_LAST)
- {
- tv = TV_POTION;
- sv = c_ptr->special;
- }
- else
- {
- tv = TV_POTION2;
- sv = c_ptr->special - SV_POTION_LAST;
- }
-
- k_ptr = &k_info[lookup_kind(tv, sv)];
- info = k_name + k_ptr->name;
- }
-
- /* Display a message */
- if (!wizard)
- {
- sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, name, info);
- }
- else
- {
- sprintf(out_val, "%s%s%s%s [%s] (%d:%d:%d)",
- s1, s2, s3, name, info,
- c_ptr->feat, c_ptr->mimic, c_ptr->special);
- }
- prt(out_val, 0, 0);
- move_cursor_relative(y, x);
- query = inkey();
-
- /* Always stop at "normal" keys */
- if ((query != '\r') && (query != '\n') && (query != ' ')) break;
- }
-
- /* Stop on everything but "return" */
- if ((query != '\r') && (query != '\n')) break;
- }
-
- /* Keep going */
- return (query);
-}
-
-
-
-
-/*
- * Handle "target" and "look".
- *
- * Note that this code can be called from "get_aim_dir()".
- *
- * All locations must be on the current panel. Consider the use of
- * "panel_bounds()" to allow "off-panel" targets, perhaps by using
- * some form of "scrolling" the map around the cursor. XXX XXX XXX
- * That is, consider the possibility of "auto-scrolling" the screen
- * while the cursor moves around. This may require changes in the
- * "update_mon()" code to allow "visibility" even if off panel, and
- * may require dynamic recalculation of the "temp" grid set.
- *
- * Hack -- targetting/observing an "outer border grid" may induce
- * problems, so this is not currently allowed.
- *
- * The player can use the direction keys to move among "interesting"
- * grids in a heuristic manner, or the "space", "+", and "-" keys to
- * move through the "interesting" grids in a sequential manner, or
- * can enter "location" mode, and use the direction keys to move one
- * grid at a time in any direction. The "t" (set target) command will
- * only target a monster (as opposed to a location) if the monster is
- * target_able and the "interesting" mode is being used.
- *
- * The current grid is described using the "look" method above, and
- * a new command may be entered at any time, but note that if the
- * "TARGET_LOOK" bit flag is set (or if we are in "location" mode,
- * where "space" has no obvious meaning) then "space" will scan
- * through the description of the current grid until done, instead
- * of immediately jumping to the next "interesting" grid. This
- * allows the "target" command to retain its old semantics.
- *
- * The "*", "+", and "-" keys may always be used to jump immediately
- * to the next (or previous) interesting grid, in the proper mode.
- *
- * The "return" key may always be used to scan through a complete
- * grid description (forever).
- *
- * This command will cancel any old target, even if used from
- * inside the "look" command.
- */
-bool_ target_set(int mode)
-{
- int i, d, m;
- int y = p_ptr->py;
- int x = p_ptr->px;
-
- bool_ done = FALSE;
-
- bool_ flag = TRUE;
-
- char query;
-
- char info[80];
-
- cave_type *c_ptr;
-
- int screen_wid, screen_hgt;
- int panel_wid, panel_hgt;
-
- /* Get size */
- get_screen_size(&screen_wid, &screen_hgt);
-
- /* Calculate the amount of panel movement */
- panel_hgt = screen_hgt / 2;
- panel_wid = screen_wid / 2;
-
- /* Cancel target */
- target_who = 0;
-
-
- /* Cancel tracking */
- /* health_track(0); */
-
-
- /* Prepare the "temp" array */
- target_set_prepare(mode);
-
- /* Start near the player */
- m = 0;
-
- /* Interact */
- while (!done)
- {
- /* Interesting grids */
- if (flag && temp_n)
- {
- y = temp_y[m];
- x = temp_x[m];
-
- /* Access */
- c_ptr = &cave[y][x];
-
- /* Allow target */
- if (target_able(c_ptr->m_idx))
- {
- strcpy(info, "q,t,p,o,+,-,'dir'");
- }
-
- /* Dis-allow target */
- else
- {
- strcpy(info, "q,p,o,+,-,'dir'");
- }
-
- /* Describe and Prompt */
- query = target_set_aux(y, x, mode, info);
-
- /* Cancel tracking */
- /* health_track(0); */
-
- /* Assume no "direction" */
- d = 0;
-
- /* Analyze */
- switch (query)
- {
- case ESCAPE:
- case 'q':
- {
- done = TRUE;
- break;
- }
-
- case 't':
- case '.':
- case '5':
- case '0':
- {
- if (target_able(c_ptr->m_idx))
- {
- health_track(c_ptr->m_idx);
- target_who = c_ptr->m_idx;
- target_row = y;
- target_col = x;
- done = TRUE;
- }
- else
- {
- bell();
- }
- break;
- }
-
- case ' ':
- case '*':
- case '+':
- {
- if (++m == temp_n)
- {
- m = 0;
- if (!expand_list) done = TRUE;
- }
- break;
- }
-
- case '-':
- {
- if (m-- == 0)
- {
- m = temp_n - 1;
- if (!expand_list) done = TRUE;
- }
- break;
- }
-
- case 'p':
- {
- /* Recenter the map around the player */
- verify_panel();
-
- /* Update stuff */
- p_ptr->update |= (PU_MONSTERS);
-
- /* Redraw map */
- p_ptr->redraw |= (PR_MAP);
-
- /* Window stuff */
- p_ptr->window |= (PW_OVERHEAD);
-
- /* Handle stuff */
- handle_stuff();
-
- /* Recalculate interesting grids */
- target_set_prepare(mode);
-
- y = p_ptr->py;
- x = p_ptr->px;
-
- /* Fall through... */
- }
-
- case 'o':
- {
- flag = FALSE;
- break;
- }
-
- case 'm':
- {
- break;
- }
-
- default:
- {
- /* Extract the action (if any) */
- d = get_keymap_dir(query);
-
- if (!d) bell();
- break;
- }
- }
-
- /* Hack -- move around */
- if (d)
- {
- /* Find a new monster */
- i = target_pick(temp_y[m], temp_x[m], ddy[d], ddx[d]);
-
- /* Scroll to find interesting grid */
- if (i < 0)
- {
- int dy;
- int dx;
-
- dy = ddy[d];
- dx = ddx[d];
-
- /* Note panel change */
- if (change_panel(dy, dx))
- {
- int ty = temp_y[m];
- int tx = temp_x[m];
-
- /* Recalculate interesting grids */
- target_set_prepare(mode);
-
- /* Find a new monster */
- i = target_pick(ty, tx, dy, dx);
-
- /* Restore panel if needed */
- if (i < 0)
- {
- /* Restore panel */
- change_panel( -dy, -dx);
-
- /* Recalculate interesting grids */
- target_set_prepare(mode);
- }
- }
- }
-
- /* Use that grids */
- if (i >= 0) m = i;
- }
- }
-
- /* Arbitrary grids */
- else
- {
- /* Access */
- c_ptr = &cave[y][x];
-
- /* Default prompt */
- strcpy(info, "q,t,p,m,+,-,'dir'");
-
- /* Describe and Prompt (enable "TARGET_LOOK") */
- query = target_set_aux(y, x, mode | TARGET_LOOK, info);
-
- /* Cancel tracking */
- /* health_track(0); */
-
- /* Assume no direction */
- d = 0;
-
- /* Analyze the keypress */
- switch (query)
- {
- case ESCAPE:
- case 'q':
- {
- done = TRUE;
- break;
- }
-
- case 't':
- case '.':
- case '5':
- case '0':
- {
- target_who = -1;
- target_row = y;
- target_col = x;
- done = TRUE;
- break;
- }
-
- case ' ':
- case '*':
- case '+':
- case '-':
- {
- break;
- }
-
- case 'p':
- {
- y = p_ptr->py;
- x = p_ptr->px;
- }
-
- case 'o':
- {
- break;
- }
-
- case 'm':
- {
- flag = TRUE;
- break;
- }
-
- default:
- {
- /* Extract the action (if any) */
- d = get_keymap_dir(query);
-
- if (!d) bell();
- break;
- }
- }
-
- /* Handle "direction" */
- if (d)
- {
- int dy = ddy[d];
- int dx = ddx[d];
-
- /* Move */
- y += dy;
- x += dx;
-
- /* Do not move horizontally if unnecessary */
- if (((x < panel_col_min + panel_wid) && (dx > 0)) ||
- ((x > panel_col_min + panel_wid) && (dx < 0)))
- {
- dx = 0;
- }
-
- /* Do not move vertically if unnecessary */
- if (((y < panel_row_min + panel_hgt) && (dy > 0)) ||
- ((y > panel_row_min + panel_hgt) && (dy < 0)))
- {
- dy = 0;
- }
- /* Apply the motion */
- if ((y >= panel_row_min + screen_hgt) ||
- (y < panel_row_min) ||
- (x > panel_col_min + screen_wid) ||
- (x < panel_col_min))
- {
- /* Change panel and recalculate interesting grids */
- if (change_panel(dy, dx)) target_set_prepare(mode);
- }
-
- /* Boundary checks */
- if (!wizard)
- {
- /* Hack -- Verify y */
- if (y <= 0) y = 1;
- else if (y >= cur_hgt - 1) y = cur_hgt - 2;
-
- /* Hack -- Verify x */
- if (x <= 0) x = 1;
- else if (x >= cur_wid - 1) x = cur_wid - 2;
- }
- else
- {
- /* Hack -- Verify y */
- if (y < 0) y = 0;
- else if (y > cur_hgt - 1) y = cur_hgt - 1;
-
- /* Hack -- Verify x */
- if (x < 0) x = 0;
- else if (x > cur_wid - 1) x = cur_wid - 1;
- }
- }
- }
- }
-
- /* Forget */
- temp_n = 0;
-
- /* Clear the top line */
- prt("", 0, 0);
-
- /* Recenter the map around the player */
- verify_panel();
-
- /* Update stuff */
- p_ptr->update |= (PU_MONSTERS);
-
- /* Redraw map */
- p_ptr->redraw |= (PR_MAP);
-
- /* Window stuff */
- p_ptr->window |= (PW_OVERHEAD);
-
- /* Handle stuff */
- handle_stuff();
-
- /* Failure to set target */
- if (!target_who) return (FALSE);
-
- /* Success */
- return (TRUE);
-}
-
-
-
-/*
- * Get an "aiming direction" from the user.
- *
- * The "dir" is loaded with 1,2,3,4,6,7,8,9 for "actual direction", and
- * "0" for "current target", and "-1" for "entry aborted".
- *
- * Note that "Force Target", if set, will pre-empt user interaction,
- * if there is a usable target already set.
- *
- * Note that confusion over-rides any (explicit?) user choice.
- */
-bool_ get_aim_dir(int *dp)
-{
- int dir;
-
- char command;
-
- cptr p;
-
- if (repeat_pull(dp))
- {
- /* Confusion? */
-
- /* Verify */
- if (!(*dp == 5 && !target_okay()))
- {
- return (TRUE);
- }
- }
-
- /* Initialize */
- (*dp) = 0;
-
- /* Global direction */
- dir = command_dir;
-
- /* Hack -- auto-target if requested */
- if (use_old_target && target_okay()) dir = 5;
-
- /* Ask until satisfied */
- while (!dir)
- {
- /* Choose a prompt */
- if (!target_okay())
- {
- p = "Direction ('*' to choose a target, Escape to cancel)? ";
- }
- else
- {
- p = "Direction ('5' for target, '*' to re-target, Escape to cancel)? ";
- }
-
- /* Get a command (or Cancel) */
- if (!get_com(p, &command)) break;
-
- /* Convert various keys to "standard" keys */
- switch (command)
- {
- /* Use current target */
- case 'T':
- case 't':
- case '.':
- case '5':
- case '0':
- {
- dir = 5;
- break;
- }
-
- /* Set new target */
- case '*':
- {
- if (target_set(TARGET_KILL)) dir = 5;
- break;
- }
-
- default:
- {
- /* Extract the action (if any) */
- dir = get_keymap_dir(command);
-
- break;
- }
- }
-
- /* Verify requested targets */
- if ((dir == 5) && !target_okay()) dir = 0;
-
- /* Error */
- if (!dir) bell();
- }
-
- /* No direction */
- if (!dir) return (FALSE);
-
- /* Save the direction */
- command_dir = dir;
-
- /* Check for confusion */
- if (p_ptr->confused)
- {
- /* XXX XXX XXX */
- /* Random direction */
- dir = ddd[rand_int(8)];
- }
-
- /* Notice confusion */
- if (command_dir != dir)
- {
- /* Warn the user */
- msg_print("You are confused.");
- }
-
- /* Save direction */
- (*dp) = dir;
-
-
- repeat_push(dir);
-
- /* A "valid" direction was entered */
- return (TRUE);
-}
-
-
-
-/*
- * Request a "movement" direction (1,2,3,4,6,7,8,9) from the user,
- * and place it into "command_dir", unless we already have one.
- *
- * This function should be used for all "repeatable" commands, such as
- * run, walk, open, close, bash, disarm, spike, tunnel, etc, as well
- * as all commands which must reference a grid adjacent to the player,
- * and which may not reference the grid under the player. Note that,
- * for example, it is no longer possible to "disarm" or "open" chests
- * in the same grid as the player.
- *
- * Direction "5" is illegal and will (cleanly) abort the command.
- *
- * This function tracks and uses the "global direction", and uses
- * that as the "desired direction", to which "confusion" is applied.
- */
-bool_ get_rep_dir(int *dp)
-{
- int dir;
-
- if (repeat_pull(dp))
- {
- return (TRUE);
- }
-
- /* Initialize */
- (*dp) = 0;
-
- /* Global direction */
- dir = command_dir;
-
- /* Get a direction */
- while (!dir)
- {
- char ch;
-
- /* Get a command (or Cancel) */
- if (!get_com("Direction (Escape to cancel)? ", &ch)) break;
-
- /* Look up the direction */
- dir = get_keymap_dir(ch);
-
- /* Oops */
- if (!dir) bell();
- }
-
- /* Prevent weirdness */
- if (dir == 5) dir = 0;
-
- /* Aborted */
- if (!dir) return (FALSE);
-
- /* Save desired direction */
- command_dir = dir;
-
- /* Apply "confusion" */
- if (p_ptr->confused)
- {
- /* Standard confusion */
- if (rand_int(100) < 75)
- {
- /* Random direction */
- dir = ddd[rand_int(8)];
- }
- }
-
- /* Notice confusion */
- if (command_dir != dir)
- {
- /* Warn the user */
- msg_print("You are confused.");
- }
-
- /* Save direction */
- (*dp) = dir;
-
-
- repeat_push(dir);
-
- /* Success */
- return (TRUE);
-}
-
-
-int get_chaos_patron(void)
-{
- return (((p_ptr->age) + (p_ptr->sc)) % MAX_PATRON);
-}
-
-
-void gain_level_reward(int chosen_reward)
-{
- object_type *q_ptr;
- object_type forge;
- char wrath_reason[32] = "";
- int nasty_chance = 6;
- int dummy = 0, dummy2 = 0;
- int type, effect;
-
-
- if (p_ptr->lev == 13) nasty_chance = 2;
- else if (!(p_ptr->lev % 13)) nasty_chance = 3;
- else if (!(p_ptr->lev % 14)) nasty_chance = 12;
-
- if (randint(nasty_chance) == 1)
- type = randint(20); /* Allow the 'nasty' effects */
- else
- type = randint(15) + 5; /* Or disallow them */
-
- if (type < 1) type = 1;
- if (type > 20) type = 20;
- type--;
-
-
- sprintf(wrath_reason, "the Wrath of %s",
- chaos_patrons[p_ptr->chaos_patron]);
-
- effect = chaos_rewards[p_ptr->chaos_patron][type];
-
- if ((randint(6) == 1) && !chosen_reward)
- {
- msg_format("%^s rewards you with a corruption!",
- chaos_patrons[p_ptr->chaos_patron]);
- (void)gain_random_corruption(0);
- return;
- }
-
- switch (chosen_reward ? chosen_reward : effect)
- {
- case REW_POLY_SLF :
- msg_format("The voice of %s booms out:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Thou needst a new form, mortal!'");
- do_poly_self();
- break;
-
- case REW_GAIN_EXP:
- msg_format("The voice of %s booms out:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Well done, mortal! Lead on!'");
- if (p_ptr->exp < PY_MAX_EXP)
- {
- s32b ee = (p_ptr->exp / 2) + 10;
- if (ee > 100000L) ee = 100000L;
- msg_print("You feel more experienced.");
- gain_exp(ee);
- }
- break;
-
- case REW_LOSE_EXP:
- msg_format("The voice of %s booms out:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Thou didst not deserve that, slave.'");
- lose_exp(p_ptr->exp / 6);
- break;
-
- case REW_GOOD_OBJ:
- msg_format("The voice of %s whispers:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Use my gift wisely.'");
- acquirement(p_ptr->py, p_ptr->px, 1, FALSE, FALSE);
- break;
-
- case REW_GREA_OBJ:
- msg_format("The voice of %s booms out:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Use my gift wisely.'");
- acquirement(p_ptr->py, p_ptr->px, 1, TRUE, FALSE);
- break;
-
- case REW_CHAOS_WP:
- msg_format("The voice of %s booms out:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Thy deed hath earned thee a worthy blade.'");
- /* Get local object */
- q_ptr = &forge;
- dummy = TV_SWORD;
- switch (randint(p_ptr->lev))
- {
- case 0:
- case 1:
- dummy2 = SV_DAGGER;
- break;
- case 2:
- case 3:
- dummy2 = SV_MAIN_GAUCHE;
- break;
- case 4:
- case 5:
- case 6:
- dummy2 = SV_RAPIER;
- break;
- case 7:
- case 8:
- dummy2 = SV_SMALL_SWORD;
- break;
- case 9:
- case 10:
- dummy2 = SV_BASILLARD;
- break;
- case 11:
- case 12:
- case 13:
- dummy2 = SV_SHORT_SWORD;
- break;
- case 14:
- case 15:
- dummy2 = SV_SABRE;
- break;
- case 16:
- case 17:
- dummy2 = SV_CUTLASS;
- break;
- case 18:
- case 19:
- dummy2 = SV_KHOPESH;
- break;
- case 20:
- dummy2 = SV_TULWAR;
- break;
- case 21:
- dummy2 = SV_BROAD_SWORD;
- break;
- case 22:
- case 23:
- dummy2 = SV_LONG_SWORD;
- break;
- case 24:
- case 25:
- dummy2 = SV_SCIMITAR;
- break;
- case 26:
- case 27:
- dummy2 = SV_KATANA;
- break;
- case 28:
- case 29:
- dummy2 = SV_BASTARD_SWORD;
- break;
- case 30:
- dummy2 = SV_GREAT_SCIMITAR;
- break;
- case 31:
- dummy2 = SV_CLAYMORE;
- break;
- case 32:
- dummy2 = SV_ESPADON;
- break;
- case 33:
- dummy2 = SV_TWO_HANDED_SWORD;
- break;
- case 34:
- dummy2 = SV_FLAMBERGE;
- break;
- case 35:
- case 36:
- dummy2 = SV_EXECUTIONERS_SWORD;
- break;
- case 37:
- dummy2 = SV_ZWEIHANDER;
- break;
- default:
- dummy2 = SV_BLADE_OF_CHAOS;
- }
-
- object_prep(q_ptr, lookup_kind(dummy, dummy2));
- q_ptr->to_h = 3 + (randint(dun_level)) % 10;
- q_ptr->to_d = 3 + (randint(dun_level)) % 10;
- random_resistance(q_ptr, FALSE, (randint(34) + 4));
- q_ptr->name2 = EGO_CHAOTIC;
-
- /* Apply the ego */
- apply_magic(q_ptr, dun_level, FALSE, FALSE, FALSE);
-
- /* Drop it in the dungeon */
- drop_near(q_ptr, -1, p_ptr->py, p_ptr->px);
- break;
-
- case REW_GOOD_OBS:
- msg_format("The voice of %s booms out:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Thy deed hath earned thee a worthy reward.'");
- acquirement(p_ptr->py, p_ptr->px, randint(2) + 1, FALSE, FALSE);
- break;
-
- case REW_GREA_OBS:
- msg_format("The voice of %s booms out:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Behold, mortal, how generously I reward thy loyalty.'");
- acquirement(p_ptr->py, p_ptr->px, randint(2) + 1, TRUE, FALSE);
- break;
-
- case REW_TY_CURSE:
- msg_format("The voice of %s thunders:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Thou art growing arrogant, mortal.'");
- activate_ty_curse();
- break;
-
- case REW_SUMMON_M:
- msg_format("The voice of %s booms out:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'My pets, destroy the arrogant mortal!'");
- for (dummy = 0; dummy < randint(5) + 1; dummy++)
- {
- (void)summon_specific(p_ptr->py, p_ptr->px, dun_level, 0);
- }
- break;
-
- case REW_H_SUMMON:
- msg_format("The voice of %s booms out:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Thou needst worthier opponents!'");
- activate_hi_summon();
- break;
-
- case REW_DO_HAVOC:
- msg_format("The voice of %s booms out:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Death and destruction! This pleaseth me!'");
- call_chaos();
- break;
-
- case REW_GAIN_ABL:
- msg_format("The voice of %s rings out:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Stay, mortal, and let me mold thee.'");
- if ((randint(3) == 1) &&
- !(chaos_stats[p_ptr->chaos_patron] < 0))
- do_inc_stat(chaos_stats[p_ptr->chaos_patron]);
- else
- do_inc_stat(randint(6) - 1);
- break;
-
- case REW_LOSE_ABL:
- msg_format("The voice of %s booms out:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'I grow tired of thee, mortal.'");
- if ((randint(3) == 1) &&
- !(chaos_stats[p_ptr->chaos_patron] < 0))
- do_dec_stat(chaos_stats[p_ptr->chaos_patron], STAT_DEC_NORMAL);
- else
- (void)do_dec_stat(randint(6) - 1, STAT_DEC_NORMAL);
- break;
-
- case REW_RUIN_ABL:
- msg_format("The voice of %s thunders:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Thou needst a lesson in humility, mortal!'");
- msg_print("You feel less powerful!");
- for (dummy = 0; dummy < 6; dummy++)
- {
- (void)dec_stat(dummy, 10 + randint(15), TRUE);
- }
- break;
-
- case REW_POLY_WND:
- msg_format("You feel the power of %s touch you.",
- chaos_patrons[p_ptr->chaos_patron]);
- do_poly_wounds();
- break;
-
- case REW_AUGM_ABL:
- msg_format("The voice of %s booms out:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Receive this modest gift from me!'");
- for (dummy = 0; dummy < 6; dummy++)
- {
- (void) do_inc_stat(dummy);
- }
- break;
-
- case REW_HURT_LOT:
- msg_format("The voice of %s booms out:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Suffer, pathetic fool!'");
- fire_ball(GF_DISINTEGRATE, 0, (p_ptr->lev * 4), 4);
- take_hit(p_ptr->lev * 4, wrath_reason);
- break;
-
- case REW_HEAL_FUL:
- msg_format("The voice of %s booms out:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Rise, my servant!'");
- restore_level();
- (void)set_poisoned(0);
- (void)set_blind(0);
- (void)set_confused(0);
- (void)set_image(0);
- (void)set_stun(0);
- (void)set_cut(0);
- hp_player(5000);
- for (dummy = 0; dummy < 6; dummy++)
- {
- (void) do_res_stat(dummy, TRUE);
- }
- break;
-
- case REW_CURSE_WP:
- msg_format("The voice of %s booms out:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Thou reliest too much on thy weapon.'");
- (void)curse_weapon();
- break;
-
- case REW_CURSE_AR:
- msg_format("The voice of %s booms out:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Thou reliest too much on thine equipment.'");
- (void)curse_armor();
- break;
-
- case REW_PISS_OFF:
- msg_format("The voice of %s whispers:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Now thou shalt pay for annoying me.'");
- switch (randint(4))
- {
- case 1:
- activate_ty_curse();
- break;
- case 2:
- activate_hi_summon();
- break;
- case 3:
- if (randint(2) == 1) (void)curse_weapon();
- else (void)curse_armor();
- break;
- default:
- for (dummy = 0; dummy < 6; dummy++)
- {
- (void) dec_stat(dummy, 10 + randint(15), TRUE);
- }
- break;
- }
- break;
-
- case REW_WRATH:
- msg_format("The voice of %s thunders:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Die, mortal!'");
- take_hit(p_ptr->lev * 4, wrath_reason);
- for (dummy = 0; dummy < 6; dummy++)
- {
- (void) dec_stat(dummy, 10 + randint(15), FALSE);
- }
- activate_hi_summon();
- activate_ty_curse();
- if (randint(2) == 1) (void)curse_weapon();
- if (randint(2) == 1) (void)curse_armor();
- break;
-
- case REW_DESTRUCT:
- /* Prevent destruction of quest levels and town */
- if (!is_quest(dun_level) && dun_level)
- {
- msg_format("The voice of %s booms out:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Death and destruction! This pleaseth me!'");
- destroy_area(p_ptr->py, p_ptr->px, 25, TRUE, FALSE);
- }
- break;
-
- case REW_GENOCIDE:
- msg_format("The voice of %s booms out:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Let me relieve thee of thine oppressors!'");
- (void) genocide(FALSE);
- break;
-
- case REW_MASS_GEN:
- msg_format("The voice of %s booms out:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_print("'Let me relieve thee of thine oppressors!'");
- (void) mass_genocide(FALSE);
- break;
-
- case REW_DISPEL_C:
- msg_format("You can feel the power of %s assault your enemies!",
- chaos_patrons[p_ptr->chaos_patron]);
- (void) dispel_monsters(p_ptr->lev * 4);
- break;
-
- case REW_IGNORE:
- msg_format("%s ignores you.",
- chaos_patrons[p_ptr->chaos_patron]);
- break;
-
- case REW_SER_DEMO:
- msg_format("%s rewards you with a demonic servant!", chaos_patrons[p_ptr->chaos_patron]);
- if (!(summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_DEMON, FALSE)))
- msg_print("Nobody ever turns up...");
- break;
-
- case REW_SER_MONS:
- msg_format("%s rewards you with a servant!", chaos_patrons[p_ptr->chaos_patron]);
- if (!(summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_NO_UNIQUES, FALSE)))
- msg_print("Nobody ever turns up...");
- break;
-
- case REW_SER_UNDE:
- msg_format("%s rewards you with an undead servant!", chaos_patrons[p_ptr->chaos_patron]);
- if (!(summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNDEAD, FALSE)))
- msg_print("Nobody ever turns up...");
- break;
-
- default:
- msg_format("The voice of %s stammers:",
- chaos_patrons[p_ptr->chaos_patron]);
- msg_format("'Uh... uh... the answer's %d/%d, what's the question?'", type,
- effect );
- break;
- }
-}
-
-
-/*
- * old -- from PsiAngband.
- */
-bool_ tgt_pt(int *x, int *y)
-{
- char ch = 0;
- int d, cu, cv;
- int screen_wid, screen_hgt;
- bool_ success = FALSE;
-
- *x = p_ptr->px;
- *y = p_ptr->py;
-
- /* Get size */
- get_screen_size(&screen_wid, &screen_hgt);
-
- cu = Term->scr->cu;
- cv = Term->scr->cv;
- Term->scr->cu = 0;
- Term->scr->cv = 1;
- msg_print("Select a point and press space.");
-
- while ((ch != 27) && (ch != ' '))
- {
- move_cursor_relative(*y, *x);
- ch = inkey();
- switch (ch)
- {
- case 27:
- break;
- case ' ':
- success = TRUE;
- break;
- default:
- /* Look up the direction */
- d = get_keymap_dir(ch);
-
- if (!d) break;
-
- *x += ddx[d];
- *y += ddy[d];
-
- /* Hack -- Verify x */
- if ((*x >= cur_wid - 1) || (*x >= panel_col_min + screen_wid)) (*x)--;
- else if ((*x <= 0) || (*x <= panel_col_min)) (*x)++;
-
- /* Hack -- Verify y */
- if ((*y >= cur_hgt - 1) || (*y >= panel_row_min + screen_hgt)) (*y)--;
- else if ((*y <= 0) || (*y <= panel_row_min)) (*y)++;
-
- break;
- }
- }
-
- Term->scr->cu = cu;
- Term->scr->cv = cv;
- Term_fresh();
- return success;
-}
-
-
-bool_ gain_random_corruption(int choose_mut)
-{
- exec_lua("gain_corruption()");
- return (FALSE);
-}
-
-bool_ lose_corruption(int choose_mut)
-{
- exec_lua("lose_corruption()");
- return (FALSE);
-}
-
-bool_ lose_all_corruptions(void)
-{
- exec_lua("lose_all_corruptions()");
- return (FALSE);
-}
-
-bool_ get_hack_dir(int *dp)
-{
- int dir;
- cptr p;
- char command;
-
-
- /* Initialize */
- (*dp) = 0;
-
- /* Global direction */
- dir = 0;
-
- /* (No auto-targetting */
-
- /* Ask until satisfied */
- while (!dir)
- {
- /* Choose a prompt */
- if (!target_okay())
- {
- p = "Direction ('*' to choose a target, Escape to cancel)? ";
- }
- else
- {
- p = "Direction ('5' for target, '*' to re-target, Escape to cancel)? ";
- }
-
- /* Get a command (or Cancel) */
- if (!get_com(p, &command)) break;
-
- /* Convert various keys to "standard" keys */
- switch (command)
- {
- /* Use current target */
- case 'T':
- case 't':
- case '.':
- case '5':
- case '0':
- {
- dir = 5;
- break;
- }
-
- /* Set new target */
- case '*':
- {
- if (target_set(TARGET_KILL)) dir = 5;
- break;
- }
-
- default:
- {
- /* Look up the direction */
- dir = get_keymap_dir(command);
-
- break;
- }
- }
-
- /* Verify requested targets */
- if ((dir == 5) && !target_okay()) dir = 0;
-
- /* Error */
- if (!dir) bell();
- }
-
- /* No direction */
- if (!dir) return (FALSE);
-
- /* Save the direction */
- command_dir = dir;
-
- /* Check for confusion */
- if (p_ptr->confused)
- {
- /* XXX XXX XXX */
- /* Random direction */
- dir = ddd[rand_int(8)];
- }
-
- /* Notice confusion */
- if (command_dir != dir)
- {
- /* Warn the user */
- msg_print("You are confused.");
- }
-
- /* Save direction */
- (*dp) = dir;
-
- /* A "valid" direction was entered */
- return (TRUE);
-}
-
-/*
- * Do we have at least one corruption?
- */
-bool_ got_corruptions()
-{
- int i, max;
-
- max = exec_lua("return __corruptions_max");
-
- for (i = 0; i < max; i++)
- {
- if (exec_lua(format("if test_depend_corrupt(%d) == TRUE then return TRUE else return FALSE end", i)))
- {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-/*
- * Dump the corruption list
- */
-void dump_corruptions(FILE *fff, bool_ color)
-{
- int i, max;
-
- if (!fff) return;
-
- max = exec_lua("return __corruptions_max");
-
- for (i = 0; i < max; i++)
- {
- if (exec_lua(format("if test_depend_corrupt(%d) == TRUE then return TRUE else return FALSE end", i)))
- {
- int c = exec_lua(format("return __corruptions[%d].color", i));
-
- if (color)
- fprintf(fff, "#####%c%s:\n", conv_color[c], string_exec_lua(format("return __corruptions[%d].name", i)));
- else
- fprintf(fff, "%s:\n", string_exec_lua(format("return __corruptions[%d].name", i)));
- fprintf(fff, "%s\n", string_exec_lua(format("return __corruptions[%d].desc", i)));
- }
- }
-}
-
-/*
- * Set "p_ptr->grace", notice observable changes
- */
-void set_grace(s32b v)
-{
- if (v < -300000) v = -300000;
- if (v > 300000) v = 300000;
- p_ptr->grace = v;
- p_ptr->update |= PU_BONUS;
- p_ptr->redraw |= (PR_PIETY);
- handle_stuff();
-}
-
-bool_ test_object_wish(char *name, object_type *o_ptr, object_type *forge, char *what)
-{
- int i, j, jb, save_aware;
- char buf[200];
-
- /* try all objects, this *IS* a very ugly and slow method :( */
- for (i = 0; i < max_k_idx; i++)
- {
- object_kind *k_ptr = &k_info[i];
-
- o_ptr = forge;
-
- if (!k_ptr->name) continue;
- if (k_ptr->flags3 & TR3_NORM_ART) continue;
- if (k_ptr->flags3 & TR3_INSTA_ART) continue;
- if (k_ptr->tval == TV_GOLD) continue;
-
- object_prep(o_ptr, i);
- o_ptr->name1 = 0;
- o_ptr->name2 = 0;
- apply_magic(o_ptr, dun_level, FALSE, FALSE, FALSE);
- /* Hack : aware status must be restored after describing the item name */
- save_aware = k_ptr->aware;
- object_aware(o_ptr);
- object_known(o_ptr);
- object_desc(buf, o_ptr, FALSE, 0);
- strlower(buf);
- k_ptr->aware = save_aware;
-
- if (strstr(name, buf) ||
- /* Hack hack hackery */
- (o_ptr->tval == TV_ROD_MAIN && strstr(name, "rod of")))
- {
- /* try all ego */
- for (j = max_e_idx - 1; j >= 0; j--)
- {
- ego_item_type *e_ptr = &e_info[j];
- bool_ ok = FALSE;
-
- if (j && !e_ptr->name) continue;
-
- /* Must have the correct fields */
- if (j)
- {
- int z;
-
- for (z = 0; z < 6; z++)
- {
- if (e_ptr->tval[z] == k_ptr->tval)
- {
- if ((e_ptr->min_sval[z] <= k_ptr->sval) &&
- (e_ptr->max_sval[z] >= k_ptr->sval)) ok = TRUE;
- }
- if (ok) break;
- }
- if (!ok)
- {
- continue;
- }
- }
-
- /* try all ego */
- for (jb = max_e_idx - 1; jb >= 0; jb--)
- {
- ego_item_type *eb_ptr = &e_info[jb];
- bool_ ok = FALSE;
-
- if (jb && !eb_ptr->name) continue;
-
- if (j && jb && (e_ptr->before == eb_ptr->before)) continue;
-
- /* Must have the correct fields */
- if (jb)
- {
- int z;
-
- for (z = 0; z < 6; z++)
- {
- if (eb_ptr->tval[z] == k_ptr->tval)
- {
- if ((eb_ptr->min_sval[z] <= k_ptr->sval) &&
- (eb_ptr->max_sval[z] >= k_ptr->sval)) ok = TRUE;
- }
- if (ok) break;
- }
- if (!ok)
- {
- continue;
- }
- }
-
- object_prep(o_ptr, i);
- o_ptr->name1 = 0;
- o_ptr->name2 = j;
- o_ptr->name2b = jb;
- apply_magic(o_ptr, dun_level, FALSE, FALSE, FALSE);
- object_aware(o_ptr);
- object_known(o_ptr);
- object_desc(buf, o_ptr, FALSE, 0);
- strlower(buf);
-
- if (!stricmp(buf, name))
- {
- /* Don't search any more */
- return TRUE;
- }
- else
- {
- /* Restore again the aware status */
- k_ptr->aware = save_aware;
- }
- }
- }
- }
- }
- return FALSE;
-}
-
-void clean_wish_name(char *buf, char *name)
-{
- char *p;
- int i, j;
-
- /* Lowercase the wish */
- strlower(buf);
-
- /* Nuke uneccesary spaces */
- p = buf;
- while (*p == ' ') p++;
- i = 0;
- j = 0;
- while (p[i])
- {
- if ((p[i] == ' ') && (p[i + 1] == ' '))
- {
- i++;
- continue;
- }
- name[j++] = p[i++];
- }
- name[j++] = '\0';
- if (j)
- {
- j--;
- while (j && (name[j] == ' '))
- {
- name[j] = '\0';
- j--;
- }
- }
-}
-
-/*
- * Allow the player to make a wish
- */
-void make_wish(void)
-{
- char buf[200], name[200], *mname;
- int i, j, mstatus = MSTATUS_ENEMY;
- object_type forge, *o_ptr = &forge;
-
- /* Make an empty string */
- buf[0] = 0;
-
- /* Ask for the wish */
- if (!get_string("Wish for what? ", buf, 80)) return;
-
- clean_wish_name(buf, name);
-
- /* You can't wish for a wish! */
- if (strstr(name, "wish"))
- {
- msg_print("You can't wish for a wish!");
- return;
- }
-
- if (test_object_wish(name, o_ptr, &forge, "wish"))
- {
- msg_print("Your wish becomes truth!");
-
- /* Give it to the player */
- drop_near(o_ptr, -1, p_ptr->py, p_ptr->px);
-
- return;
- }
-
- /* try monsters */
- if (prefix(name, "enemy "))
- {
- mstatus = MSTATUS_ENEMY;
- mname = name + 6;
- }
- else if (prefix(name, "neutral "))
- {
- mstatus = MSTATUS_NEUTRAL;
- mname = name + 8;
- }
- else if (prefix(name, "friendly "))
- {
- mstatus = MSTATUS_FRIEND;
- mname = name + 9;
- }
- else if (prefix(name, "pet "))
- {
- mstatus = MSTATUS_PET;
- mname = name + 4;
- }
- else if (prefix(name, "companion "))
- {
- if (can_create_companion()) mstatus = MSTATUS_COMPANION;
- else mstatus = MSTATUS_PET;
- mname = name + 10;
- }
- else mname = name;
- for (i = 1; i < max_r_idx; i++)
- {
- monster_race *r_ptr = &r_info[i];
-
- if (!r_ptr->name) continue;
-
- if (r_ptr->flags9 & RF9_SPECIAL_GENE) continue;
- if (r_ptr->flags9 & RF9_NEVER_GENE) continue;
- if (r_ptr->flags1 & RF1_UNIQUE) continue;
-
- sprintf(buf, "%s", r_ptr->name + r_name);
- strlower(buf);
-
- if (strstr(mname, buf))
- {
- /* try all ego */
- for (j = max_re_idx - 1; j >= 0; j--)
- {
- monster_ego *re_ptr = &re_info[j];
-
- if (j && !re_ptr->name) continue;
-
- if (!mego_ok(i, j)) continue;
-
- if (j)
- {
- if (re_ptr->before) sprintf(buf, "%s %s", re_name + re_ptr->name, r_ptr->name + r_name);
- else sprintf(buf, "%s %s", r_ptr->name + r_name, re_name + re_ptr->name);
- }
- else
- {
- sprintf(buf, "%s", r_ptr->name + r_name);
- }
- strlower(buf);
-
- if (!stricmp(mname, buf))
- {
- int wy = p_ptr->py, wx = p_ptr->px;
- int attempts = 100;
-
- do
- {
- scatter(&wy, &wx, p_ptr->py, p_ptr->px, 5);
- }
- while (!(in_bounds(wy, wx) && cave_floor_bold(wy, wx)) && --attempts);
-
- /* Create the monster */
- if (place_monster_one(wy, wx, i, j, FALSE, mstatus))
- msg_print("Your wish becomes truth!");
-
- /* Don't search any more */
- return;
- }
- }
- }
- }
-}
-
-
-/*
- * Corrupted have a 1/3 chance of losing a mutation each time this is called,
- * assuming they have any in the first place
- */
-void corrupt_corrupted(void)
-{
- if (magik(45))
- {
- lose_corruption(0);
- }
- else
- {
- gain_random_corruption(0);
- }
-
- /* We are done. */
- return;
-}
-
-/*
- * Change to an other class
- */
-void switch_class(int sclass)
-{
- p_ptr->pclass = sclass;
- cp_ptr = &class_info[p_ptr->pclass];
-}
-
-/*
- * Change to an other subclass
- */
-void switch_subclass(int sclass)
-{
- p_ptr->pspec = sclass;
- spp_ptr = &class_info[p_ptr->pclass].spec[p_ptr->pspec];
-}
-
-/*
- * Change to an other subrace
- */
-void switch_subrace(int racem, bool_ copy_old)
-{
- if ((racem < 0) && (racem >= max_rmp_idx)) return;
-
- /* If we switch to the saved subrace, we copy over the old subrace data */
- if (copy_old && (racem == SUBRACE_SAVE))
- {
- s32b old_title = race_mod_info[SUBRACE_SAVE].title;
- s32b old_desc = race_mod_info[SUBRACE_SAVE].desc;
-
- COPY(&race_mod_info[SUBRACE_SAVE], &race_mod_info[p_ptr->pracem], player_race_mod);
-
- race_mod_info[SUBRACE_SAVE].title = old_title;
- race_mod_info[SUBRACE_SAVE].desc = old_desc;
- strcpy(race_mod_info[SUBRACE_SAVE].title + rmp_name, race_mod_info[p_ptr->pracem].title + rmp_name);
- }
-
- p_ptr->pracem = racem;
- rmp_ptr = &race_mod_info[p_ptr->pracem];
-}
-
-cptr get_subrace_title(int racem)
-{
- return race_mod_info[racem].title + rmp_name;
-}
-
-void set_subrace_title(int racem, cptr name)
-{
- strcpy(race_mod_info[racem].title + rmp_name, name);
-}
-
-/*
- * Rebirth, recalc hp & exp/level
- */
-void do_rebirth()
-{
- /* Experience factor */
- p_ptr->expfact = rp_ptr->r_exp + rmp_ptr->r_exp + cp_ptr->c_exp;
-
- /* Hitdice */
- p_ptr->hitdie = rp_ptr->r_mhp + rmp_ptr->r_mhp + cp_ptr->c_mhp;
-
- /* Recalc HP */
- do_cmd_rerate();
-
- /* Change the level if needed */
- check_experience();
- p_ptr->max_plv = p_ptr->lev;
-
- /* Redraw/calc stuff */
- p_ptr->redraw |= (PR_BASIC);
- p_ptr->update |= (PU_BONUS);
- handle_stuff();
-
- lite_spot(p_ptr->py, p_ptr->px);
-}
-
-/*
- * Quick mimic name to index function
- */
-int resolve_mimic_name(cptr name)
-{
- s32b idx;
-
- call_lua("resolve_mimic_name", "(s)", "d", name, &idx);
- return idx;
-}