summaryrefslogtreecommitdiff
path: root/src/dungeon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dungeon.c')
-rw-r--r--src/dungeon.c5664
1 files changed, 0 insertions, 5664 deletions
diff --git a/src/dungeon.c b/src/dungeon.c
deleted file mode 100644
index 6d732f00..00000000
--- a/src/dungeon.c
+++ /dev/null
@@ -1,5664 +0,0 @@
-/* File: dungeon.c */
-
-/* Purpose: Angband game engine */
-
-/*
- * 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"
-#include "lua/lua.h"
-#include "tolua.h"
-extern lua_State* L;
-
-#define TY_CURSE_CHANCE 100
-#define DG_CURSE_CHANCE 50
-#define AUTO_CURSE_CHANCE 15
-#define CHAINSWORD_NOISE 100
-
-
-/*
- * Return a "feeling" (or NULL) about an item. Method 1 (Heavy).
- */
-byte value_check_aux1(object_type *o_ptr)
-{
- /* Artifacts */
- if (artifact_p(o_ptr))
- {
- /* Cursed/Broken */
- if (cursed_p(o_ptr)) return (SENSE_TERRIBLE);
-
- /* Normal */
- return (SENSE_SPECIAL);
- }
-
- /* Ego-Items */
- if (ego_item_p(o_ptr))
- {
- /* Cursed/Broken */
- if (cursed_p(o_ptr)) return (SENSE_WORTHLESS);
-
- /* Normal */
- return (SENSE_EXCELLENT);
- }
-
- /* Cursed items */
- if (cursed_p(o_ptr)) return (SENSE_CURSED);
-
- /* Good "armor" bonus */
- if (o_ptr->to_a > 0) return (SENSE_GOOD_HEAVY);
-
- /* Good "weapon" bonus */
- if (o_ptr->to_h + o_ptr->to_d > 0) return (SENSE_GOOD_HEAVY);
-
- /* Default to "average" */
- return (SENSE_AVERAGE);
-}
-
-byte value_check_aux1_magic(object_type *o_ptr)
-{
- object_kind *k_ptr = &k_info[o_ptr->k_idx];
-
-
- switch (o_ptr->tval)
- {
- /* Scrolls, Potions, Wands, Staves and Rods */
- case TV_SCROLL:
- case TV_POTION:
- case TV_POTION2:
- case TV_WAND:
- case TV_STAFF:
- case TV_ROD:
- case TV_ROD_MAIN:
- {
- /* "Cursed" scrolls/potions have a cost of 0 */
- if (k_ptr->cost == 0) return (SENSE_TERRIBLE);
-
- /* Artifacts */
- if (artifact_p(o_ptr)) return (SENSE_SPECIAL);
-
- /* Scroll of Nothing, Apple Juice, etc. */
- if (k_ptr->cost < 3) return (SENSE_WORTHLESS);
-
- /*
- * Identify, Phase Door, Cure Light Wounds, etc. are
- * just average
- */
- if (k_ptr->cost < 100) return (SENSE_AVERAGE);
-
- /* Enchant Armor, *Identify*, Restore Stat, etc. */
- if (k_ptr->cost < 10000) return (SENSE_GOOD_HEAVY);
-
- /* Acquirement, Deincarnation, Strength, Blood of Life, ... */
- if (k_ptr->cost >= 10000) return (SENSE_EXCELLENT);
-
- break;
- }
-
- /* Food */
- case TV_FOOD:
- {
- /* "Cursed" food */
- if (k_ptr->cost == 0) return (SENSE_TERRIBLE);
-
- /* Artifacts */
- if (artifact_p(o_ptr)) return (SENSE_SPECIAL);
-
- /* Normal food (no magical properties) */
- if (k_ptr->cost <= 10) return (SENSE_AVERAGE);
-
- /* Everything else is good */
- if (k_ptr->cost > 10) return (SENSE_GOOD_HEAVY);
-
- break;
- }
- }
-
- /* No feeling */
- return (SENSE_NONE);
-}
-
-
-/*
- * Return a "feeling" (or NULL) about an item. Method 2 (Light).
- */
-byte value_check_aux2(object_type *o_ptr)
-{
- /* Cursed items (all of them) */
- if (cursed_p(o_ptr)) return (SENSE_CURSED);
-
- /* Artifacts -- except cursed/broken ones */
- if (artifact_p(o_ptr)) return (SENSE_GOOD_LIGHT);
-
- /* Ego-Items -- except cursed/broken ones */
- if (ego_item_p(o_ptr)) return (SENSE_GOOD_LIGHT);
-
- /* Good armor bonus */
- if (o_ptr->to_a > 0) return (SENSE_GOOD_LIGHT);
-
- /* Good weapon bonuses */
- if (o_ptr->to_h + o_ptr->to_d > 0) return (SENSE_GOOD_LIGHT);
-
- /* Default to "average" */
- return (SENSE_AVERAGE);
-}
-
-
-byte value_check_aux2_magic(object_type *o_ptr)
-{
- object_kind *k_ptr = &k_info[o_ptr->k_idx];
-
-
- switch (o_ptr->tval)
- {
- /* Scrolls, Potions, Wands, Staves and Rods */
- case TV_SCROLL:
- case TV_POTION:
- case TV_POTION2:
- case TV_WAND:
- case TV_STAFF:
- case TV_ROD:
- case TV_ROD_MAIN:
- {
- /* "Cursed" scrolls/potions have a cost of 0 */
- if (k_ptr->cost == 0) return (SENSE_CURSED);
-
- /* Artifacts */
- if (artifact_p(o_ptr)) return (SENSE_GOOD_LIGHT);
-
- /* Scroll of Nothing, Apple Juice, etc. */
- if (k_ptr->cost < 3) return (SENSE_AVERAGE);
-
- /*
- * Identify, Phase Door, Cure Light Wounds, etc. are
- * just average
- */
- if (k_ptr->cost < 100) return (SENSE_AVERAGE);
-
- /* Enchant Armor, *Identify*, Restore Stat, etc. */
- if (k_ptr->cost < 10000) return (SENSE_GOOD_LIGHT);
-
- /* Acquirement, Deincarnation, Strength, Blood of Life, ... */
- if (k_ptr->cost >= 10000) return (SENSE_GOOD_LIGHT);
-
- break;
- }
-
- /* Food */
- case TV_FOOD:
- {
- /* "Cursed" food */
- if (k_ptr->cost == 0) return (SENSE_CURSED);
-
- /* Artifacts */
- if (artifact_p(o_ptr)) return (SENSE_GOOD_LIGHT);
-
- /* Normal food (no magical properties) */
- if (k_ptr->cost <= 10) return (SENSE_AVERAGE);
-
- /* Everything else is good */
- if (k_ptr->cost > 10) return (SENSE_GOOD_LIGHT);
-
- break;
- }
- }
-
- /* No feeling */
- return (SENSE_NONE);
-}
-
-
-/*
- * Can a player be resurrected?
- */
-static bool_ granted_resurrection(void)
-{
- PRAY_GOD(GOD_ERU)
- {
- if (p_ptr->grace > 100000)
- {
- if (magik(70)) return (TRUE);
- else return (FALSE);
- }
- }
- return (FALSE);
-}
-
-static byte select_sense(object_type *o_ptr)
-{
- /* Valid "tval" codes */
- switch (o_ptr->tval)
- {
- case TV_SHOT:
- case TV_ARROW:
- case TV_BOLT:
- case TV_BOW:
- case TV_DIGGING:
- case TV_HAFTED:
- case TV_POLEARM:
- case TV_SWORD:
- case TV_MSTAFF:
- case TV_AXE:
- case TV_BOOTS:
- case TV_GLOVES:
- case TV_HELM:
- case TV_CROWN:
- case TV_SHIELD:
- case TV_CLOAK:
- case TV_SOFT_ARMOR:
- case TV_HARD_ARMOR:
- case TV_DRAG_ARMOR:
- case TV_BOOMERANG:
- case TV_TRAPKIT:
- {
- return 1;
- break;
- }
-
- case TV_POTION:
- case TV_POTION2:
- case TV_SCROLL:
- case TV_WAND:
- case TV_STAFF:
- case TV_ROD:
- case TV_ROD_MAIN:
- {
- return 2;
- break;
- }
-
- /* Dual use? */
- case TV_DAEMON_BOOK:
- {
- return 1;
- break;
- }
- }
- return 0;
-}
-
-/*
- * Sense the inventory
- *
- * Combat items (weapons and armour) - Fast, weak if combat skill < 10, strong
- * otherwise.
- *
- * Magic items (scrolls, staffs, wands, potions etc) - Slow, weak if
- * magic skill < 10, strong otherwise.
- *
- * It shouldn't matter a lot to discriminate against magic users, because
- * they learn one form of ID or another, and because most magic items are
- * easy_know.
- */
-void sense_inventory(void)
-{
- int i, combat_lev, magic_lev;
-
- bool_ heavy_combat, heavy_magic;
-
- byte feel;
-
- object_type *o_ptr;
-
- char o_name[80];
-
-
- /*** Check for "sensing" ***/
-
- /* No sensing when confused */
- if (p_ptr->confused) return;
-
- /*
- * In Angband, the chance of pseudo-id uses two different formulae:
- *
- * (1) Fast. 0 == rand_int(BASE / (plev * plev + 40)
- * (2) Slow. 0 == rand_int(BASE / (plev + 5)
- *
- * Warriors: Fase with BASE == 9000
- * Magi: Slow with BASE == 240000
- * Priests: Fast with BASE == 10000
- * Rogues: Fase with BASE == 20000
- * Rangers: Slow with BASE == 120000
- * Paladins: Fast with BASE == 80000
- *
- * In other words, those who have identify spells are penalised.
- * The problems with Pern/Tome since it externalised player classes
- * is that it uses the same and slow formula for spellcasters and
- * fighters.
- *
- * In the following code, combat item pseudo-ID improves exponentially,
- * (fast with BASE 9000) and magic one linear (slow with base 60000 --
- * twice faster than V rangers).
- *
- * I hope this makes it closer to the original model -- pelpel
- */
-
- /* The combat skill affects weapon/armour pseudo-ID */
- combat_lev = get_skill(SKILL_COMBAT);
-
- /* The magic skill affects magic item pseudo-ID */
- magic_lev = get_skill(SKILL_MAGIC);
-
- /* Higher skill levels give the player better sense of items */
- heavy_combat = (combat_lev > 10) ? TRUE : FALSE;
- heavy_magic = (magic_lev > 10) ? TRUE : FALSE;
-
-
- /*** Sense everything ***/
-
- /* Check everything */
- for (i = 0; i < INVEN_TOTAL; i++)
- {
- byte okay = 0;
-
- o_ptr = &p_ptr->inventory[i];
-
- /* Skip empty slots */
- if (!o_ptr->k_idx) continue;
-
- /* We know about it already, do not tell us again */
- if (o_ptr->ident & (IDENT_SENSE)) continue;
-
- /* It is fully known, no information needed */
- if (object_known_p(o_ptr)) continue;
-
- /* Valid "tval" codes */
- okay = select_sense(o_ptr);
-
- /* Skip non-sense machines */
- if (!okay) continue;
-
- /* Check for a feeling */
- if (okay == 1)
- {
- feel = (heavy_combat ? value_check_aux1(o_ptr) : value_check_aux2(o_ptr));
- }
- else
- {
- feel = (heavy_magic ? value_check_aux1_magic(o_ptr) : value_check_aux2_magic(o_ptr));
- }
-
- /* Skip non-feelings */
- if (feel == SENSE_NONE) continue;
-
- /* Get an object description */
- object_desc(o_name, o_ptr, FALSE, 0);
-
- /* Message (equipment) */
- if (i >= INVEN_WIELD)
- {
- msg_format("You feel the %s (%c) you are %s %s %s...",
- o_name, index_to_label(i), describe_use(i),
- ((o_ptr->number == 1) ? "is" : "are"), sense_desc[feel]);
- }
-
- /* Message (inventory) */
- else
- {
- msg_format("You feel the %s (%c) in your pack %s %s...",
- o_name, index_to_label(i),
- ((o_ptr->number == 1) ? "is" : "are"), sense_desc[feel]);
- }
-
- /* We have "felt" it */
- o_ptr->ident |= (IDENT_SENSE);
-
- /* Set sense property */
- o_ptr->sense = feel;
-
- /* Combine / Reorder the pack (later) */
- p_ptr->notice |= (PN_COMBINE | PN_REORDER);
-
- /* Window stuff */
- p_ptr->window |= (PW_INVEN | PW_EQUIP);
- }
-
- /* Squelch ! */
- squeltch_inventory();
-}
-
-
-/*
- * Go to any level (ripped off from wiz_jump)
- */
-static void pattern_teleport(void)
-{
- /* Ask for level */
- if (get_check("Teleport level? "))
- {
- char ppp[80];
-
- char tmp_val[160];
-
- /* Prompt */
- sprintf(ppp, "Teleport to level (0-%d): ", 99);
-
- /* Default */
- sprintf(tmp_val, "%d", dun_level);
-
- /* Ask for a level */
- if (!get_string(ppp, tmp_val, 10)) return;
-
- /* Extract request */
- command_arg = atoi(tmp_val);
- }
- else if (get_check("Normal teleport? "))
- {
- teleport_player(200);
- return;
- }
- else
- {
- return;
- }
-
- /* Paranoia */
- if (command_arg < 0) command_arg = 0;
-
- /* Paranoia */
- if (command_arg > 99) command_arg = 99;
-
- /* Accept request */
- msg_format("You teleport to dungeon level %d.", command_arg);
-
- autosave_checkpoint();
-
- /* Change level */
- dun_level = command_arg;
-
- /* Leaving */
- p_ptr->leaving = TRUE;
-}
-
-
-/*
- * Returns TRUE if we are on the Straight Road...
- */
-static bool_ pattern_effect(void)
-{
- if ((cave[p_ptr->py][p_ptr->px].feat < FEAT_PATTERN_START) ||
- (cave[p_ptr->py][p_ptr->px].feat > FEAT_PATTERN_XTRA2)) return (FALSE);
-
- if (cave[p_ptr->py][p_ptr->px].feat == FEAT_PATTERN_END)
- {
- (void)set_poisoned(0);
- (void)set_image(0);
- (void)set_stun(0);
- (void)set_cut(0);
- (void)set_blind(0);
- (void)set_afraid(0);
- (void)do_res_stat(A_STR, TRUE);
- (void)do_res_stat(A_INT, TRUE);
- (void)do_res_stat(A_WIS, TRUE);
- (void)do_res_stat(A_DEX, TRUE);
- (void)do_res_stat(A_CON, TRUE);
- (void)do_res_stat(A_CHR, TRUE);
- (void)restore_level();
- (void)hp_player(1000);
- cave_set_feat(p_ptr->py, p_ptr->px, FEAT_PATTERN_OLD);
- msg_print("This section of the Straight Road looks less powerful.");
- }
-
-
- /*
- * We could make the healing effect of the
- * Pattern center one-time only to avoid various kinds
- * of abuse, like luring the win monster into fighting you
- * in the middle of the pattern...
- */
- else if (cave[p_ptr->py][p_ptr->px].feat == FEAT_PATTERN_OLD)
- {
- /* No effect */
- }
- else if (cave[p_ptr->py][p_ptr->px].feat == FEAT_PATTERN_XTRA1)
- {
- pattern_teleport();
- }
- else if (cave[p_ptr->py][p_ptr->px].feat == FEAT_PATTERN_XTRA2)
- {
- if (!(p_ptr->invuln))
- take_hit(200, "walking the corrupted Straight Road");
- }
-
- else
- {
- if (!(p_ptr->invuln))
- take_hit(damroll(1, 3), "walking the Straight Road");
- }
-
- return (TRUE);
-}
-
-
-/*
- * If player has inscribed the object with "!!", let him know when it's
- * recharged. -LM-
- */
-static void recharged_notice(object_type *o_ptr)
-{
- char o_name[80];
-
- cptr s;
-
-
- /* No inscription */
- if (!o_ptr->note) return;
-
- /* Find a '!' */
- s = strchr(quark_str(o_ptr->note), '!');
-
- /* Process notification request. */
- while (s)
- {
- /* Find another '!' */
- if (s[1] == '!')
- {
- /* Describe (briefly) */
- object_desc(o_name, o_ptr, FALSE, 0);
-
- /* Notify the player */
- if (o_ptr->number > 1)
- {
- msg_format("Your %s are recharged.", o_name);
- }
- else
- {
- msg_format("Your %s is recharged.", o_name);
- }
-
- /* Done. */
- return;
- }
-
- /* Keep looking for '!'s */
- s = strchr(s + 1, '!');
- }
-}
-
-
-
-/*
- * Regenerate hit points -RAK-
- */
-static void regenhp(int percent)
-{
- s32b new_chp, new_chp_frac;
-
- int old_chp;
-
-
- /* Only if alive */
- if (!(p_ptr->necro_extra & CLASS_UNDEAD))
- {
- /* Save the old hitpoints */
- old_chp = p_ptr->chp;
-
- /* Extract the new hitpoints */
- new_chp = ((long)p_ptr->mhp) * percent + PY_REGEN_HPBASE;
-
- /* div 65536 */
- p_ptr->chp += new_chp >> 16;
-
- /* check for overflow */
- if ((p_ptr->chp < 0) && (old_chp > 0)) p_ptr->chp = MAX_SHORT;
-
- /* mod 65536 */
- new_chp_frac = (new_chp & 0xFFFF) + p_ptr->chp_frac;
-
- if (new_chp_frac >= 0x10000L)
- {
- p_ptr->chp_frac = new_chp_frac - 0x10000L;
- p_ptr->chp++;
- }
- else
- {
- p_ptr->chp_frac = new_chp_frac;
- }
-
- /* Fully healed */
- if (p_ptr->chp >= p_ptr->mhp)
- {
- p_ptr->chp = p_ptr->mhp;
- p_ptr->chp_frac = 0;
- }
-
- /* Notice changes */
- if (old_chp != p_ptr->chp)
- {
- /* Redraw */
- p_ptr->redraw |= (PR_HP);
-
- /* Window stuff */
- p_ptr->window |= (PW_PLAYER);
- }
- }
-}
-
-
-/*
- * Regenerate mana points -RAK-
- */
-static void regenmana(int percent)
-{
- s32b new_mana, new_mana_frac;
-
- int old_csp;
-
- /* Incraese regen with int */
- percent += adj_str_blow[p_ptr->stat_ind[A_INT]] * 3;
-
- old_csp = p_ptr->csp;
- new_mana = ((long)p_ptr->msp) * percent + PY_REGEN_MNBASE;
-
- /* div 65536 */
- p_ptr->csp += new_mana >> 16;
-
- /* check for overflow */
- if ((p_ptr->csp < 0) && (old_csp > 0))
- {
- p_ptr->csp = MAX_SHORT;
- }
-
- /* mod 65536 */
- new_mana_frac = (new_mana & 0xFFFF) + p_ptr->csp_frac;
-
- if (new_mana_frac >= 0x10000L)
- {
- p_ptr->csp_frac = new_mana_frac - 0x10000L;
- p_ptr->csp++;
- }
- else
- {
- p_ptr->csp_frac = new_mana_frac;
- }
-
- /* Must set frac to zero even if equal */
- if (p_ptr->csp >= p_ptr->msp)
- {
- p_ptr->csp = p_ptr->msp;
- p_ptr->csp_frac = 0;
- }
-
- /* Redraw mana */
- if (old_csp != p_ptr->csp)
- {
- /* Redraw */
- p_ptr->redraw |= (PR_MANA);
-
- /* Window stuff */
- p_ptr->window |= (PW_PLAYER);
- }
-}
-
-
-
-
-
-
-/*
- * Regenerate the monsters (once per 100 game turns)
- *
- * XXX XXX XXX Should probably be done during monster turns.
- */
-static void regen_monsters(void)
-{
- int i, frac;
-
- object_type *o_ptr = &p_ptr->inventory[INVEN_CARRY];
-
-
- if (o_ptr->k_idx)
- {
- monster_race *r_ptr = &r_info[o_ptr->pval];
-
- /* Allow regeneration (if needed) */
- if (o_ptr->pval2 < o_ptr->pval3)
- {
- /* Hack -- Base regeneration */
- frac = o_ptr->pval3 / 100;
-
- /* Hack -- Minimal regeneration rate */
- if (!frac) frac = 1;
-
- /* Hack -- Some monsters regenerate quickly */
- if (r_ptr->flags2 & (RF2_REGENERATE)) frac *= 2;
-
-
- /* Hack -- Regenerate */
- o_ptr->pval2 += frac;
-
- /* Do not over-regenerate */
- if (o_ptr->pval2 > o_ptr->pval3) o_ptr->pval2 = o_ptr->pval3;
-
- /* Redraw (later) */
- p_ptr->redraw |= (PR_MH);
- }
- }
-
- /* Regenerate everyone */
- for (i = 1; i < m_max; i++)
- {
- /* Check the i'th monster */
- monster_type *m_ptr = &m_list[i];
- monster_race *r_ptr = race_inf(m_ptr);
-
- /* Skip dead monsters */
- if (!m_ptr->r_idx) continue;
-
- /* Dont regen bleeding/poisonned monsters */
- if (m_ptr->bleeding || m_ptr->poisoned) continue;
-
- /* Allow regeneration (if needed) */
- if (m_ptr->hp < m_ptr->maxhp)
- {
- /* Hack -- Base regeneration */
- frac = m_ptr->maxhp / 100;
-
- /* Hack -- Minimal regeneration rate */
- if (!frac) frac = 1;
-
- /* Hack -- Some monsters regenerate quickly */
- if (r_ptr->flags2 & (RF2_REGENERATE)) frac *= 2;
-
-
- /* Hack -- Regenerate */
- m_ptr->hp += frac;
-
- /* Do not over-regenerate */
- if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp;
-
- /* Redraw (later) if needed */
- if (health_who == i) p_ptr->redraw |= (PR_HEALTH);
- }
- }
-}
-
-
-/*
- * Does an object decay?
- *
- * Should belong to object1.c, renamed to object_decays() -- pelpel
- */
-bool_ decays(object_type *o_ptr)
-{
- u32b f1, f2, f3, f4, f5, esp;
-
-
- /* Extract some flags */
- object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
-
- if (f3 & TR3_DECAY) return (TRUE);
-
- return (FALSE);
-}
-
-
-static int process_lasting_spell(s16b music)
-{
- int oldtop, use_mana;
-
- if (music > 0) return FALSE;
-
- oldtop = lua_gettop(L);
-
- music = -music;
-
- /* Push the function */
- lua_getglobal(L, "exec_lasting_spell");
-
- /* Push the spell */
- tolua_pushnumber(L, music);
-
- /* Call the function */
- if (lua_call(L, 1, 1))
- {
- cmsg_format(TERM_VIOLET, "ERROR in lua_call while calling lasting spell");
- return 0;
- }
-
- use_mana = tolua_getnumber(L, -(lua_gettop(L) - oldtop), 0);
- lua_settop(L, oldtop);
- return use_mana;
-}
-
-static void gere_class_special()
-{
- switch (p_ptr->druid_extra2)
- {
- /* Lay a path of mana on the floor */
- case CLASS_MANA_PATH:
- {
- /* Does the player have enought mana ? */
- if (p_ptr->csp < (s32b)(p_ptr->druid_extra & 255))
- {
- p_ptr->druid_extra = 0;
- p_ptr->druid_extra2 = CLASS_NONE;
- msg_print("You stop laying a mana path.");
- }
- else
- {
- /* Use some mana */
- p_ptr->csp -= (p_ptr->druid_extra & 255);
-
- if ((p_ptr->druid_extra >> 8) & CLASS_MANA_PATH_ERASE)
- {
- /* Absorb some of the mana of the grid */
- p_ptr->csp += cave[p_ptr->py][p_ptr->px].mana / 50;
- if (p_ptr->csp > p_ptr->msp) p_ptr->csp = p_ptr->msp;
-
- /* Set the new grid mana */
- cave[p_ptr->py][p_ptr->px].mana = p_ptr->druid_extra & 255;
- }
- else
- {
- int m = cave[p_ptr->py][p_ptr->px].mana;
-
- if (m + (p_ptr->druid_extra & 255) > 255)
- {
- cave[p_ptr->py][p_ptr->px].mana = 255;
- }
- else
- {
- cave[p_ptr->py][p_ptr->px].mana += p_ptr->druid_extra & 255;
- }
- }
- }
-
- break;
- }
-
- /* Lay a path of mana on the floor */
- case CLASS_WINDS_MANA:
- {
- /* Does the player have enought mana ? */
- if (p_ptr->csp < (s32b)(p_ptr->druid_extra & 255))
- {
- p_ptr->druid_extra = CLASS_NONE;
- msg_print("You stop expulsing mana winds.");
- }
- else
- {
- int dam = 0;
-
- /* Use some mana */
- p_ptr->csp -= (p_ptr->druid_extra & 255);
-
- if ((p_ptr->druid_extra >> 8) & CLASS_MANA_PATH_ERASE)
- {
- dam = (p_ptr->druid_extra & 255) + 256;
- }
- else
- {
- dam = (p_ptr->druid_extra & 255);
- }
-
- fire_explosion(p_ptr->py, p_ptr->px, GF_WINDS_MANA, 2, dam);
- }
-
- break;
- }
-
- case CLASS_CANALIZE_MANA:
- {
- if (p_ptr->druid_extra & CLASS_CANALIZE_MANA_EXTRA)
- {
- p_ptr->csp += cave[p_ptr->py][p_ptr->px].mana / 10;
- }
- else
- {
- p_ptr->csp += cave[p_ptr->py][p_ptr->px].mana / 20;
- }
-
- if (p_ptr->csp > p_ptr->msp) p_ptr->csp = p_ptr->msp;
-
- cave[p_ptr->py][p_ptr->px].mana = 0;
-
- break;
- }
-
- /* CLASS_NONE, possibly others? */
- default:
- {
- /* No mana update */
- return;
- }
- }
-
- /* Redraw mana */
- p_ptr->update |= (PU_BONUS);
-
- /* Window stuff */
- p_ptr->window |= (PW_PLAYER);
-}
-
-
-static void check_music()
-{
- int use_mana;
-
- /* Music sung by player */
- if (!p_ptr->music_extra) return;
-
- use_mana = process_lasting_spell(p_ptr->music_extra);
-
- if (p_ptr->csp < use_mana)
- {
- msg_print("You stop your spell.");
- p_ptr->music_extra = MUSIC_NONE;
- p_ptr->music_extra2 = MUSIC_NONE;
- }
- else
- {
- p_ptr->csp -= use_mana;
-
- /* Redraw mana */
- p_ptr->redraw |= (PR_MANA);
-
- /* Window stuff */
- p_ptr->window |= (PW_PLAYER);
- }
-}
-
-
-/*
- * Generate the feature effect
- */
-void apply_effect(int y, int x)
-{
- cave_type *c_ptr = &cave[y][x];
-
- feature_type *f_ptr = &f_info[c_ptr->feat];
-
-
- if (f_ptr->d_frequency[0] != 0)
- {
- int i;
-
- for (i = 0; i < 4; i++)
- {
- /* Check the frequency */
- if (f_ptr->d_frequency[i] == 0) continue;
-
- if (((turn % f_ptr->d_frequency[i]) == 0) &&
- ((f_ptr->d_side[i] != 0) || (f_ptr->d_dice[i] != 0)))
- {
- int l, dam = 0;
- int d = f_ptr->d_dice[i], s = f_ptr->d_side[i];
-
- if (d == -1) d = p_ptr->lev;
- if (s == -1) s = p_ptr->lev;
-
- /* Roll damage */
- for (l = 0; l < d; l++)
- {
- dam += randint(s);
- }
-
- /* Apply damage */
- project( -100, 0, y, x, dam, f_ptr->d_type[i],
- PROJECT_KILL | PROJECT_HIDE);
-
- /* Hack -- notice death */
- if (!alive || death) return;
- }
- }
- }
-}
-
-
-
-/* XXX XXX XXX */
-bool_ is_recall = FALSE;
-
-
-/*
- * Handle certain things once every 10 game turns
- *
- * Note that a single movement in the overhead wilderness mode
- * consumes 132 times as much energy as a normal one...
- */
-static void process_world(void)
-{
- timer_type *t_ptr;
-
- int x, y, i, j;
-
- int regen_amount;
- bool_ cave_no_regen = FALSE;
- int upkeep_factor = 0;
-
- dungeon_info_type *d_ptr = &d_info[dungeon_type];
-
- cave_type *c_ptr;
-
- object_type *o_ptr;
- u32b f1 = 0 , f2 = 0 , f3 = 0, f4 = 0, f5 = 0, esp = 0;
-
-
- /*
- * Every 10 game turns -- which means this section is invoked once
- * in a player turn under the normal speed, and 132 times in a move
- * in the reduced map mode.
- */
- if (turn % 10) return;
-
- /*
- * I don't know if this is the right thing to do because I'm totally
- * ignorant (yes, I must admit that...) about the scripting part of
- * the game, but since there have been complaints telling us it
- * runs terribly slow in the reduced map mode... -- pelpel
- *
- * Note to coders: if it is desirable to make this active in the
- * reduced map mode, remove the if condition surrounding the line
- * and move the code inside into every 1000 game turns section.
- */
- if (dun_level || (!p_ptr->wild_mode))
- {
- /* Let the script live! */
- process_hooks(HOOK_PROCESS_WORLD, "()");
-
- /* Handle the player song */
- check_music();
- }
-
- /* Handle the timers */
- for (t_ptr = gl_timers; t_ptr != NULL; t_ptr = t_ptr->next)
- {
- if (!t_ptr->enabled) continue;
-
- t_ptr->countdown--;
- if (!t_ptr->countdown)
- {
- t_ptr->countdown = t_ptr->delay;
- call_lua(t_ptr->callback, "()", "");
- }
- }
-
- /* Handle class special actions */
- gere_class_special();
-
- /* Check the fate */
- if (fate_option && (p_ptr->lev > 10))
- {
- /*
- * WAS: == 666 against randint(50000).
- * Since CPU's don't know Judeo-Christian / Cabalistic traditions,
- * and since comparisons with zero is more efficient in many
- * architectures...
- */
- if (rand_int(50000) == 0) gain_fate(0);
- }
-
- /*** Is the wielded monsters still hypnotised ***/
- o_ptr = &p_ptr->inventory[INVEN_CARRY];
-
- if (o_ptr->k_idx)
- {
- monster_race *r_ptr = &r_info[o_ptr->pval];
-
- if ((randint(1000) < r_ptr->level - ((p_ptr->lev * 2) + get_skill(SKILL_SYMBIOTIC))))
- {
- msg_format("%s breaks free from hypnosis!",
- symbiote_name(TRUE));
- carried_make_attack_normal(o_ptr->pval);
- }
- }
-
- /*** Attempt timed autosave ***/
- if (autosave_t && autosave_freq)
- {
- if ((turn % ((s32b)autosave_freq * 10)) == 0)
- {
- is_autosave = TRUE;
- msg_print("Autosaving the game...");
- do_cmd_save_game();
- is_autosave = FALSE;
- }
- }
-
-
- /*** Handle the wilderness/town (sunshine) ***/
-
- /* While in town/wilderness and not in the overworld mode */
- if (!dun_level && !p_ptr->wild_mode)
- {
- /* Hack -- Daybreak/Nighfall in town */
- if ((turn % ((10L * DAY) / 2)) == 0)
- {
- bool_ dawn;
-
- /* Check for dawn */
- dawn = ((turn % (10L * DAY)) == 0);
-
- /* Day breaks */
- if (dawn)
- {
- /* Message */
- msg_print("The sun has risen.");
-
- /* Hack -- Scan the town */
- for (y = 0; y < cur_hgt; y++)
- {
- for (x = 0; x < cur_wid; x++)
- {
- /* Get the cave grid */
- c_ptr = &cave[y][x];
-
- /* Assume lit */
- c_ptr->info |= (CAVE_GLOW);
-
- /* Hack -- Memorize lit grids if allowed */
- if (view_perma_grids) c_ptr->info |= (CAVE_MARK);
-
- /* Hack -- Notice spot */
- note_spot(y, x);
- }
- }
- }
-
- /* Night falls */
- else
- {
- /* Message */
- msg_print("The sun has set.");
-
- /* Hack -- Scan the town */
- for (y = 0; y < cur_hgt; y++)
- {
- for (x = 0; x < cur_wid; x++)
- {
- /* Get the cave grid */
- c_ptr = &cave[y][x];
-
- /* Darken "boring" features */
- if (cave_plain_floor_grid(c_ptr))
- {
- /* Forget the grid */
- c_ptr->info &= ~(CAVE_GLOW | CAVE_MARK);
-
- /* Hack -- Notice spot */
- note_spot(y, x);
- }
- }
- }
- }
-
- /* Update the monsters */
- p_ptr->update |= (PU_MONSTERS);
-
- /* Redraw map */
- p_ptr->redraw |= (PR_MAP);
-
- /* Window stuff */
- p_ptr->window |= (PW_OVERHEAD);
- }
- }
-
- /* Tell a day passed */
- if (((turn + (DAY_START * 10L)) % (10L * DAY)) == 0)
- {
- char buf[20];
-
- sprintf(buf, "%s", get_day(bst(YEAR, turn) + START_YEAR));
- cmsg_format(TERM_L_GREEN,
- "Today it is %s of the %s year of the third age.",
- get_month_name(bst(DAY, turn), wizard, FALSE), buf);
- }
-
- /* Set back the rewards once a day */
- if ((turn % (10L * STORE_TURNS)) == 0)
- {
- /* Select new bounties. */
- if (magik(20)) select_bounties();
- }
-
- /* Modify loan */
- if (p_ptr->loan)
- {
- if (p_ptr->loan_time) p_ptr->loan_time--;
-
- if (((turn % 5000) == 0) && !p_ptr->loan_time)
- {
- cmsg_print(TERM_RED, "You should pay your loan...");
-
- p_ptr->loan += p_ptr->loan / 12;
-
- if (p_ptr->loan > PY_MAX_GOLD) p_ptr->loan = PY_MAX_GOLD;
-
- /* Do a nasty stuff */
- if (p_ptr->wild_mode && rand_int(2))
- {
- /* Discount player items */
- int z = 0, tries = 200;
- object_type *o_ptr = NULL;
-
- while (tries--)
- {
- z = rand_int(INVEN_TOTAL);
- o_ptr = &p_ptr->inventory[z];
-
- if (!o_ptr->k_idx) continue;
-
- if (o_ptr->discount >= 100) continue;
-
- break;
- }
-
- if (tries)
- {
- o_ptr->discount += 70;
- if (o_ptr->discount >= 100) o_ptr->discount = 100;
-
- inven_item_optimize(z);
- inven_item_describe(z);
-
- p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
- }
- }
-
- else
- {
- int merc = test_monster_name("Mean-looking mercenary");
- int agent = test_monster_name("Agent of the black market");
- int num = 5 + (p_ptr->lev / 3), z;
-
- for (z = 0; z < num; z++)
- {
- int yy, xx, attempts = 200, m_idx;
-
- /* Summon */
- while (1)
- {
- scatter(&yy, &xx, p_ptr->py, p_ptr->px, 6);
-
- /* Accept an empty grid within the boundary */
- if (in_bounds(yy, xx) && cave_floor_bold(yy, xx)) break;
-
- /* Max number of retries reached */
- if (--attempts == 0) break;
- }
-
- /* All the attempts failed */
- if (attempts == 0) continue;
-
- /* Summon a monster */
- m_idx = place_monster_one(yy, xx, magik(80) ? merc : agent,
- 0, FALSE, MSTATUS_ENEMY);
-
- /* Level it */
- if (m_idx)
- {
- monster_type *m_ptr = &m_list[m_idx];
-
- m_ptr->exp = MONSTER_EXP(p_ptr->lev * 2);
- monster_check_experience(m_idx, TRUE);
- }
- }
- }
- }
- }
-
- /*** Process the monsters ***/
-
- /* Check for creature generation. */
- if (!p_ptr->wild_mode &&
- !p_ptr->inside_arena &&
- !p_ptr->inside_quest &&
- (rand_int(d_info[(dun_level) ? dungeon_type : DUNGEON_WILDERNESS].max_m_alloc_chance) == 0))
- {
- /* Make a new monster */
- if (!(dungeon_flags2 & DF2_NO_NEW_MONSTER))
- {
- (void)alloc_monster(MAX_SIGHT + 5, FALSE);
- }
- }
-
- /* Hack -- Check for creature regeneration */
- if (!p_ptr->wild_mode && ((turn % 100) == 0)) regen_monsters();
-
-
- /*** Damage over Time ***/
-
- /* Take damage from poison */
- if (p_ptr->poisoned && !p_ptr->invuln)
- {
- /* Take damage */
- take_hit(1, "poison");
- }
-
-
- /* Vampires take damage from sunlight */
- if (p_ptr->sensible_lite)
- {
- if ((!dun_level) && (((turn / ((10L * DAY) / 2)) % 2) == 0))
- {
- if (cave[p_ptr->py][p_ptr->px].info & (CAVE_GLOW))
- {
- /* Take damage */
- msg_print("The sun's rays scorch your undead flesh!");
- take_hit(1, "sunlight");
- cave_no_regen = TRUE;
- drop_from_wild();
- }
- }
-
- if ((p_ptr->inventory[INVEN_LITE].tval != 0) &&
- (p_ptr->inventory[INVEN_LITE].sval >= SV_LITE_GALADRIEL) &&
- (p_ptr->inventory[INVEN_LITE].sval <= SV_STONE_LORE) &&
- (p_ptr->inventory[INVEN_LITE].sval != SV_LITE_UNDEATH))
- {
- object_type * o_ptr = &p_ptr->inventory[INVEN_LITE];
- char o_name [80];
- char ouch [80];
-
- /* Get an object description */
- object_desc(o_name, o_ptr, FALSE, 0);
-
- msg_format("The %s scorches your undead flesh!", o_name);
-
- cave_no_regen = TRUE;
-
- /* Get an object description */
- object_desc(o_name, o_ptr, TRUE, 0);
-
- sprintf(ouch, "wielding %s", o_name);
- take_hit(1, ouch);
- }
- }
-
- /* Drown in deep water unless the player have levitation, water walking
- water breathing, or magic breathing.*/
- if (!p_ptr->ffall && !p_ptr->walk_water && !p_ptr->magical_breath &&
- !p_ptr->water_breath &&
- (cave[p_ptr->py][p_ptr->px].feat == FEAT_DEEP_WATER))
- {
- if (calc_total_weight() > ((weight_limit()) / 2))
- {
- /* Take damage */
- msg_print("You are drowning!");
- take_hit(randint(p_ptr->lev), "drowning");
- cave_no_regen = TRUE;
- }
- }
-
-
- /* Spectres -- take damage when moving through walls */
-
- /*
- * Added: ANYBODY takes damage if inside through walls
- * without wraith form -- NOTE: Spectres will never be
- * reduced below 0 hp by being inside a stone wall; others
- * WILL BE!
- */
- if (!cave_floor_bold(p_ptr->py, p_ptr->px))
- {
- int feature = cave[p_ptr->py][p_ptr->px].feat;
-
- /* Player can walk through or fly over trees */
- if ((has_ability(AB_TREE_WALK) || p_ptr->fly) && (feature == FEAT_TREES))
- {
- /* Do nothing */
- }
- /* Player can climb over mountains */
- else if ((p_ptr->climb) && (f_info[feature].flags1 & FF1_CAN_CLIMB))
- {
- /* Do nothing */
- }
- else if (PRACE_FLAG(PR1_SEMI_WRAITH) && (!p_ptr->wraith_form) && (f_info[cave[p_ptr->py][p_ptr->px].feat].flags1 & FF1_CAN_PASS))
- {
- int amt = 1 + ((p_ptr->lev) / 5);
-
- cave_no_regen = TRUE;
- if (amt > p_ptr->chp - 1) amt = p_ptr->chp - 1;
- take_hit(amt, " walls ...");
- }
- }
-
-
- /* Take damage from cuts */
- if ((p_ptr->cut) && !(p_ptr->invuln))
- {
- /* Mortal wound or Deep Gash */
- if (p_ptr->cut > 200)
- {
- i = 3;
- }
-
- /* Severe cut */
- else if (p_ptr->cut > 100)
- {
- i = 2;
- }
-
- /* Other cuts */
- else
- {
- i = 1;
- }
-
- /* Take damage */
- take_hit(i, "a fatal wound");
- }
-
-
- /*** Check the Food, and Regenerate ***/
-
- /* Digest normally */
- if (p_ptr->food < PY_FOOD_MAX)
- {
- /* Every 100 game turns */
- if ((turn % 100) == 0)
- {
- int speed_use = p_ptr->pspeed;
-
- /* Maximum */
- if (speed_use > 199)
- {
- speed_use = 199;
- }
-
- /* Minimum */
- else if (speed_use < 0)
- {
- speed_use = 0;
- }
-
- /* Basic digestion rate based on speed */
- i = extract_energy[speed_use] * 2;
-
- /* Regeneration takes more food */
- if (p_ptr->regenerate) i += 30;
-
- /* Regeneration takes more food */
- if (p_ptr->tim_regen) i += p_ptr->tim_regen_pow / 10;
-
- /* Invisibility consume a lot of food */
- i += p_ptr->invis / 2;
-
- /* Invulnerability consume a lot of food */
- if (p_ptr->invuln) i += 40;
-
- /* Wraith Form consume a lot of food */
- if (p_ptr->wraith_form) i += 30;
-
- /* Get the weapon */
- o_ptr = &p_ptr->inventory[INVEN_WIELD];
-
- /* Examine the sword */
- object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
-
- /* Hitpoints multiplier consume a lot of food */
- if (o_ptr->k_idx && (f2 & (TR2_LIFE))) i += o_ptr->pval * 5;
-
- /* Slow digestion takes less food */
- if (p_ptr->slow_digest) i -= 10;
-
- /* Minimal digestion */
- if (i < 1) i = 1;
-
- /* Digest some food */
- (void)set_food(p_ptr->food - i);
- }
- }
-
- /* Digest quickly when gorged */
- else
- {
- /* Digest a lot of food */
- (void)set_food(p_ptr->food - 100);
- }
-
- /* Starve to death (slowly) */
- if (p_ptr->food < PY_FOOD_STARVE)
- {
- /* Calculate damage */
- i = (PY_FOOD_STARVE - p_ptr->food) / 10;
-
- /* Take damage */
- if (!(p_ptr->invuln)) take_hit(i, "starvation");
- }
-
- /* Default regeneration */
- regen_amount = PY_REGEN_NORMAL;
-
- /* Getting Weak */
- if (p_ptr->food < PY_FOOD_WEAK)
- {
- /* Lower regeneration */
- if (p_ptr->food < PY_FOOD_STARVE)
- {
- regen_amount = 0;
- }
- else if (p_ptr->food < PY_FOOD_FAINT)
- {
- regen_amount = PY_REGEN_FAINT;
- }
- else
- {
- regen_amount = PY_REGEN_WEAK;
- }
-
- /* Getting Faint */
- if (p_ptr->food < PY_FOOD_FAINT)
- {
- /* Faint occasionally */
- if (!p_ptr->paralyzed && (rand_int(100) < 10))
- {
- /* Message */
- msg_print("You faint from the lack of food.");
- disturb(1, 0);
-
- /* Hack -- faint (bypass free action) */
- (void)set_paralyzed(p_ptr->paralyzed + 1 + rand_int(5));
- }
- }
- }
-
- /* Are we walking the pattern? */
- if (!p_ptr->wild_mode && pattern_effect())
- {
- cave_no_regen = TRUE;
- }
- else
- {
- /* Regeneration ability */
- if (p_ptr->regenerate)
- {
- regen_amount = regen_amount * 2;
- }
- }
-
-
- /* Searching or Resting */
- if (p_ptr->searching || resting)
- {
- regen_amount = regen_amount * 2;
- }
-
- if (total_friends)
- {
- int upkeep_divider = 20;
-
- if (has_ability(AB_PERFECT_CASTING))
- upkeep_divider = 15;
-
-#ifdef TRACK_FRIENDS
-
- if (wizard) msg_format("Total friends: %d.", total_friends);
-
-#endif /* TRACK_FRIENDS */
-
- if (total_friends > 1 + (p_ptr->lev / (upkeep_divider)))
- {
- upkeep_factor = (total_friend_levels);
-
- if (upkeep_factor > 100) upkeep_factor = 100;
- else if (upkeep_factor < 10) upkeep_factor = 10;
-
-#ifdef TRACK_FRIENDS
-
- if (wizard) msg_format("Levels %d, upkeep %d", total_friend_levels,
- upkeep_factor);
-
-#endif /* TRACK_FRIENDS */
- }
- }
-
- /* Regenerate the mana */
- if (p_ptr->csp < p_ptr->msp)
- {
- if (upkeep_factor)
- {
- s16b upkeep_regen = (((100 - upkeep_factor) * regen_amount) / 100);
- regenmana(upkeep_regen);
-
-#ifdef TRACK_FRIENDS
-
- if (wizard)
- {
- msg_format("Regen: %d/%d", upkeep_regen, regen_amount);
- }
-
-#endif /* TRACK_FRIENDS */
- }
- else
- {
- regenmana(regen_amount);
- }
- }
-
- /* Eru piety incraese with time */
- if (((turn % 100) == 0) && (!p_ptr->did_nothing) && (!p_ptr->wild_mode))
- {
- NOT_PRAY_GOD(GOD_ERU)
- {
- int inc = wisdom_scale(10);
-
- /* Increase by wisdom/4 */
- if (!inc) inc = 1;
- inc_piety(GOD_ERU, inc);
- }
- }
- /* Most gods piety decrease with time */
- if (((turn % 300) == 0) && (!p_ptr->did_nothing) && (!p_ptr->wild_mode) && (dun_level))
- {
- GOD(GOD_MANWE)
- {
- int dec = 4 - wisdom_scale(3);
-
- PRAY_GOD(GOD_MANWE)
- dec++;
- if (PRACE_FLAG(PR1_ELF))
- dec -= wisdom_scale(2);
- if (dec < 1) dec = 1;
- inc_piety(GOD_MANWE, -dec);
- }
- GOD(GOD_MELKOR)
- {
- int dec = 8 - wisdom_scale(6);
-
- PRAY_GOD(GOD_MELKOR)
- dec++;
- if (PRACE_FLAG(PR1_ELF))
- dec += 5 - wisdom_scale(4);
- if (dec < 1) dec = 1;
- inc_piety(GOD_MELKOR, -dec);
- }
- PRAY_GOD(GOD_TULKAS)
- {
- int dec = 4 - wisdom_scale(3);
-
- if (dec < 1) dec = 1;
- inc_piety(GOD_TULKAS, -dec);
- }
- }
- /* Yavanna piety decrease with time */
- if (((turn % 400) == 0) && (!p_ptr->did_nothing) && (!p_ptr->wild_mode) && (dun_level))
- {
- GOD(GOD_YAVANNA)
- {
- int dec = 5 - wisdom_scale(3);
-
- /* Blech what an hideous hack */
- if (!strcmp(rp_ptr->title + rp_name, "Ent"))
- dec -= wisdom_scale(2);
- if (dec < 1) dec = 1;
- inc_piety(GOD_YAVANNA, -dec);
- }
- }
- p_ptr->did_nothing = FALSE;
-
- /* Increase regen by tim regen */
- if (p_ptr->tim_regen) regen_amount += p_ptr->tim_regen_pow;
-
- /* Poisoned or cut yields no healing */
- if (p_ptr->poisoned) regen_amount = 0;
- if (p_ptr->cut) regen_amount = 0;
-
- /* Special floor -- Pattern, in a wall -- yields no healing */
- if (cave_no_regen) regen_amount = 0;
-
- /* Being over grass allows Yavanna to regen you */
- PRAY_GOD(GOD_YAVANNA)
- {
- if (cave[p_ptr->py][p_ptr->px].feat == FEAT_GRASS)
- {
- regen_amount += 200 + wisdom_scale(800);
- }
- }
-
- /* Regenerate Hit Points if needed */
- if ((p_ptr->chp < p_ptr->mhp) && !cave_no_regen)
- {
- if ((cave[p_ptr->py][p_ptr->px].feat < FEAT_PATTERN_END) &&
- (cave[p_ptr->py][p_ptr->px].feat >= FEAT_PATTERN_START))
- {
- /* Hmmm. this should never happen? */
- regenhp(regen_amount / 5);
- }
- else
- {
- regenhp(regen_amount);
- }
- }
-
-
- /*** Timeout Various Things ***/
-
- /* Handle temporary stat drains */
- for (i = 0; i < 6; i++)
- {
- if (p_ptr->stat_cnt[i] > 0)
- {
- p_ptr->stat_cnt[i]--;
- if (p_ptr->stat_cnt[i] == 0)
- {
- do_res_stat(i, FALSE);
- }
- }
- }
-
- /* Hack -- Hallucinating */
- if (p_ptr->image)
- {
- (void)set_image(p_ptr->image - 1);
- }
-
- /* Holy Aura */
- if (p_ptr->holy)
- {
- (void)set_holy(p_ptr->holy - 1);
- }
-
- /* Soul absorbtion */
- if (p_ptr->absorb_soul)
- {
- (void)set_absorb_soul(p_ptr->absorb_soul - 1);
- }
-
- /* Undead loose Death Points */
- if (p_ptr->necro_extra & CLASS_UNDEAD)
- {
- int old_chp = p_ptr->chp;
- int warning = (p_ptr->mhp * hitpoint_warn / 10);
-
- /* Bypass invulnerability and wraithform */
- p_ptr->chp--;
-
- /* Display the hitpoints */
- p_ptr->redraw |= (PR_HP);
-
- /* Window stuff */
- p_ptr->window |= (PW_PLAYER);
-
- /* Dead player */
- if (p_ptr->chp < 0)
- {
- bool_ old_quick = quick_messages;
-
- /* Sound */
- sound(SOUND_DEATH);
-
- /* Hack -- Note death */
- if (!last_words)
- {
- msg_print("You die.");
- msg_print(NULL);
- }
- else
- {
- char death_message[80];
-
- (void)get_rnd_line("death.txt", death_message);
- msg_print(death_message);
- }
-
- /* Note cause of death */
- (void)strcpy(died_from, "being undead too long");
-
- if (p_ptr->image) strcat(died_from, "(?)");
-
- /* No longer a winner */
- total_winner = FALSE;
-
- /* Leaving */
- p_ptr->leaving = TRUE;
-
- /* Note death */
- death = TRUE;
-
- quick_messages = FALSE;
- if (get_check("Make a last screenshot? "))
- {
- do_cmd_html_dump();
- }
- quick_messages = old_quick;
-
- /* Dead */
- return;
- }
-
- /* Hitpoint warning */
- if (p_ptr->chp < warning)
- {
- /* Hack -- bell on first notice */
- if (alert_hitpoint && (old_chp > warning)) bell();
-
- sound(SOUND_WARN);
-
- /* Message */
- msg_print("*** LOW DEATHPOINT WARNING! ***");
- msg_print(NULL);
- }
- }
-
- /* Walk water */
- if (p_ptr->walk_water)
- {
- (void)set_walk_water(p_ptr->walk_water - 1);
- }
-
- /* True Strike */
- if (p_ptr->strike)
- {
- (void)set_strike(p_ptr->strike - 1);
- }
-
- /* Meditation */
- if (p_ptr->meditation)
- {
- (void)set_meditation(p_ptr->meditation - 1);
- }
-
- /* Timed project */
- if (p_ptr->tim_project)
- {
- (void)set_project(p_ptr->tim_project - 1, p_ptr->tim_project_gf, p_ptr->tim_project_dam, p_ptr->tim_project_rad, p_ptr->tim_project_flag);
- }
-
- /* Timed roots */
- if (p_ptr->tim_roots)
- {
- (void)set_roots(p_ptr->tim_roots - 1, p_ptr->tim_roots_ac, p_ptr->tim_roots_dam);
- }
-
- /* Timed breath */
- if (p_ptr->tim_water_breath)
- {
- (void)set_tim_breath(p_ptr->tim_water_breath - 1, FALSE);
- }
- if (p_ptr->tim_magic_breath)
- {
- (void)set_tim_breath(p_ptr->tim_magic_breath - 1, TRUE);
- }
-
- /* Timed regen */
- if (p_ptr->tim_regen)
- {
- (void)set_tim_regen(p_ptr->tim_regen - 1, p_ptr->tim_regen_pow);
- }
-
- /* Timed Disrupt shield */
- if (p_ptr->disrupt_shield)
- {
- (void)set_disrupt_shield(p_ptr->disrupt_shield - 1);
- }
-
- /* Timed Parasite */
- if (p_ptr->parasite)
- {
- (void)set_parasite(p_ptr->parasite - 1, p_ptr->parasite_r_idx);
- }
-
- /* Timed Reflection */
- if (p_ptr->tim_reflect)
- {
- (void)set_tim_reflect(p_ptr->tim_reflect - 1);
- }
-
- /* Timed Prob Travel */
- if (p_ptr->prob_travel)
- {
- (void)set_prob_travel(p_ptr->prob_travel - 1);
- }
-
- /* Timed Time Resistance */
- if (p_ptr->tim_res_time)
- {
- (void)set_tim_res_time(p_ptr->tim_res_time - 1);
- }
-
- /* Timed Levitation */
- if (p_ptr->tim_ffall)
- {
- (void)set_tim_ffall(p_ptr->tim_ffall - 1);
- }
- if (p_ptr->tim_fly)
- {
- (void)set_tim_fly(p_ptr->tim_fly - 1);
- }
-
- /* Thunderstorm */
- if (p_ptr->tim_thunder)
- {
- int dam = damroll(p_ptr->tim_thunder_p1, p_ptr->tim_thunder_p2);
- int i, tries = 600;
- monster_type *m_ptr = NULL;
-
- while (tries)
- {
- /* Access the monster */
- m_ptr = &m_list[i = rand_range(1, m_max - 1)];
-
- tries--;
-
- /* Ignore "dead" monsters */
- if (!m_ptr->r_idx) continue;
-
- /* Cant see ? cant hit */
- if (!los(p_ptr->py, p_ptr->px, m_ptr->fy, m_ptr->fx)) continue;
-
- /* Do not hurt friends! */
- if (is_friend(m_ptr) >= 0) continue;
- break;
- }
-
- if (tries)
- {
- char m_name[80];
-
- monster_desc(m_name, m_ptr, 0);
- msg_format("Lightning strikes %s.", m_name);
- project(0, 0, m_ptr->fy, m_ptr->fx, dam / 3, GF_ELEC,
- PROJECT_KILL | PROJECT_ITEM | PROJECT_HIDE);
- project(0, 0, m_ptr->fy, m_ptr->fx, dam / 3, GF_LITE,
- PROJECT_KILL | PROJECT_ITEM | PROJECT_HIDE);
- project(0, 0, m_ptr->fy, m_ptr->fx, dam / 3, GF_SOUND,
- PROJECT_KILL | PROJECT_ITEM | PROJECT_HIDE);
- }
-
- (void)set_tim_thunder(p_ptr->tim_thunder - 1, p_ptr->tim_thunder_p1, p_ptr->tim_thunder_p2);
- }
-
- /* Poisonned hands */
- if (p_ptr->tim_poison)
- {
- (void)set_poison(p_ptr->tim_poison - 1);
- }
-
- /* Timed Fire Aura */
- if (p_ptr->tim_fire_aura)
- {
- (void)set_tim_fire_aura(p_ptr->tim_fire_aura - 1);
- }
-
- /* Brightness */
- if (p_ptr->tim_lite)
- {
- (void)set_lite(p_ptr->tim_lite - 1);
- }
-
- /* Blindness */
- if (p_ptr->blind)
- {
- (void)set_blind(p_ptr->blind - 1);
- }
-
- /* Timed no_breeds */
- if (no_breeds)
- {
- (void)set_no_breeders(no_breeds - 1);
- }
-
- /* Timed mimic */
- if (p_ptr->tim_mimic)
- {
- (void)set_mimic(p_ptr->tim_mimic - 1, p_ptr->mimic_form, p_ptr->mimic_level);
- }
-
- /* Timed special move commands */
- if (p_ptr->immov_cntr)
- {
- p_ptr->immov_cntr--;
- }
-
- /* Timed invisibility */
- if (p_ptr->tim_invisible)
- {
- (void)set_invis(p_ptr->tim_invisible - 1, p_ptr->tim_inv_pow);
- }
-
- /* Times see-invisible */
- if (p_ptr->tim_invis)
- {
- (void)set_tim_invis(p_ptr->tim_invis - 1);
- }
-
- if (multi_rew)
- {
- multi_rew = FALSE;
- }
-
- /* Timed esp */
- if (p_ptr->tim_esp)
- {
- (void)set_tim_esp(p_ptr->tim_esp - 1);
- }
-
- /* Timed infra-vision */
- if (p_ptr->tim_infra)
- {
- (void)set_tim_infra(p_ptr->tim_infra - 1);
- }
-
- /* Paralysis */
- if (p_ptr->paralyzed)
- {
- (void)set_paralyzed(p_ptr->paralyzed - 1);
- }
-
- /* Confusion */
- if (p_ptr->confused)
- {
- (void)set_confused(p_ptr->confused - 1);
- }
-
- /* Afraid */
- if (p_ptr->afraid)
- {
- (void)set_afraid(p_ptr->afraid - 1);
- }
-
- /* Fast */
- if (p_ptr->fast)
- {
- (void)set_fast(p_ptr->fast - 1, p_ptr->speed_factor);
- }
-
- /* Light speed */
- if (p_ptr->lightspeed)
- {
- (void)set_light_speed(p_ptr->lightspeed - 1);
- }
-
- /* Slow */
- if (p_ptr->slow)
- {
- (void)set_slow(p_ptr->slow - 1);
- }
-
- /* Protection from evil */
- if (p_ptr->protevil)
- {
- (void)set_protevil(p_ptr->protevil - 1);
- }
-
- /* Protection from good */
- if (p_ptr->protgood)
- {
- (void)set_protgood(p_ptr->protgood - 1);
- }
-
- /* Protection from undead */
- if (p_ptr->protundead)
- {
- (void)set_protundead(p_ptr->protundead - 1);
- }
-
- /* Invulnerability */
- if (p_ptr->invuln)
- {
- (void)set_invuln(p_ptr->invuln - 1);
- }
-
- /* Wraith form */
- if (p_ptr->tim_wraith)
- {
- (void)set_shadow(p_ptr->tim_wraith - 1);
- }
-
- /* Heroism */
- if (p_ptr->hero)
- {
- (void)set_hero(p_ptr->hero - 1);
- }
-
- /* Super Heroism */
- if (p_ptr->shero)
- {
- (void)set_shero(p_ptr->shero - 1);
- }
-
- /* Blessed */
- if (p_ptr->blessed)
- {
- (void)set_blessed(p_ptr->blessed - 1);
- }
-
- /* Shield */
- if (p_ptr->shield)
- {
- (void)set_shield(p_ptr->shield - 1, p_ptr->shield_power, p_ptr->shield_opt, p_ptr->shield_power_opt, p_ptr->shield_power_opt2);
- }
-
- /* Oppose Acid */
- if (p_ptr->oppose_acid)
- {
- (void)set_oppose_acid(p_ptr->oppose_acid - 1);
- }
-
- /* Oppose Lightning */
- if (p_ptr->oppose_elec)
- {
- (void)set_oppose_elec(p_ptr->oppose_elec - 1);
- }
-
- /* Oppose Fire */
- if (p_ptr->oppose_fire)
- {
- (void)set_oppose_fire(p_ptr->oppose_fire - 1);
- }
-
- /* Oppose Cold */
- if (p_ptr->oppose_cold)
- {
- (void)set_oppose_cold(p_ptr->oppose_cold - 1);
- }
-
- /* Oppose Poison */
- if (p_ptr->oppose_pois)
- {
- (void)set_oppose_pois(p_ptr->oppose_pois - 1);
- }
-
- /* Oppose Light & Dark */
- if (p_ptr->oppose_ld)
- {
- (void)set_oppose_ld(p_ptr->oppose_ld - 1);
- }
-
- /* Oppose Chaos & Confusion */
- if (p_ptr->oppose_cc)
- {
- (void)set_oppose_cc(p_ptr->oppose_cc - 1);
- }
-
- /* Oppose Sound & Shards */
- if (p_ptr->oppose_ss)
- {
- (void)set_oppose_ss(p_ptr->oppose_ss - 1);
- }
-
- /* Oppose Nexus */
- if (p_ptr->oppose_nex)
- {
- (void)set_oppose_nex(p_ptr->oppose_nex - 1);
- }
-
- /* Mental Barrier */
- if (p_ptr->tim_mental_barrier)
- {
- (void)set_mental_barrier(p_ptr->tim_mental_barrier - 1);
- }
-
- /* The rush */
- if (p_ptr->rush)
- {
- (void)set_rush(p_ptr->rush - 1);
- }
-
-
- /* Timed mimicry */
- if (get_skill(SKILL_MIMICRY))
- {
- /* Extract the value and the flags */
- u32b value = p_ptr->mimic_extra >> 16;
-
- u32b att = p_ptr->mimic_extra & 0xFFFF;
-
- if ((att & CLASS_LEGS) || (att & CLASS_WALL) || (att & CLASS_ARMS))
- {
- value--;
-
- if (!value)
- {
- if (att & CLASS_LEGS) msg_print("You lose your extra pair of legs.");
- if (att & CLASS_ARMS) msg_print("You lose your extra pair of arms.");
- if (att & CLASS_WALL) msg_print("You lose your affinity for walls.");
-
- att &= ~(CLASS_ARMS);
- att &= ~(CLASS_LEGS);
- att &= ~(CLASS_WALL);
-
- if (disturb_state) disturb(0, 0);
- }
-
- p_ptr->update |= (PU_BODY);
- p_ptr->mimic_extra = att + (value << 16);
- }
- }
-
-
- /*** Poison and Stun and Cut ***/
-
- /* Poison */
- if (p_ptr->poisoned)
- {
- int adjust = (adj_con_fix[p_ptr->stat_ind[A_CON]] + 1);
-
- /* Apply some healing */
- (void)set_poisoned(p_ptr->poisoned - adjust);
- }
-
- /* Stun */
- if (p_ptr->stun)
- {
- int adjust = (adj_con_fix[p_ptr->stat_ind[A_CON]] + 1);
-
- /* Apply some healing */
- (void)set_stun(p_ptr->stun - adjust);
- }
-
- /* Cut */
- if (p_ptr->cut)
- {
- int adjust = (adj_con_fix[p_ptr->stat_ind[A_CON]] + 1);
-
- /* Hack -- Truly "mortal" wound */
- if (p_ptr->cut > 1000) adjust = 0;
-
- /* Apply some healing */
- (void)set_cut(p_ptr->cut - adjust);
- }
-
- /* Hack - damage done by the dungeon -SC- */
- if ((dun_level != 0) && (d_ptr->d_frequency[0] != 0))
- {
- int i, j, k;
-
- /* Apply damage to every grid in the dungeon */
- for (i = 0; i < 4; i++)
- {
- /* Check the frequency */
- if (d_ptr->d_frequency[i] == 0) continue;
-
- if (((turn % d_ptr->d_frequency[i]) == 0) &&
- ((d_ptr->d_side[i] != 0) || (d_ptr->d_dice[i] != 0)))
- {
- for (j = 0; j < cur_hgt - 1; j++)
- {
- for (k = 0; k < cur_wid - 1; k++)
- {
- int l, dam = 0;
-
- if (!(dungeon_flags1 & DF1_DAMAGE_FEAT))
- {
- /* If the grid is empty, skip it */
- if ((cave[j][k].o_idx == 0) &&
- ((j != p_ptr->py) && (i != p_ptr->px))) continue;
- }
-
- /* Let's not hurt poor monsters */
- if (cave[j][k].m_idx) continue;
-
- /* Roll damage */
- for (l = 0; l < d_ptr->d_dice[i]; l++)
- {
- dam += randint(d_ptr->d_side[i]);
- }
-
- /* Apply damage */
- project( -100, 0, j, k, dam, d_ptr->d_type[i],
- PROJECT_KILL | PROJECT_ITEM | PROJECT_HIDE);
- }
- }
- }
- }
- }
-
- /* handle spell effects */
- if (!p_ptr->wild_mode)
- {
- /*
- * I noticed significant performance degrade after the introduction
- * of staying spell effects. I believe serious optimisation effort
- * is required before another release.
- *
- * More important is to fix that display weirdness...
- *
- * It seems that the game never expects that monster deaths and
- * terrain feature changes should happen here... Moving these
- * to process_player() [before resting code, with "every 10 game turn"
- * 'if'] may or may not fix the problem... -- pelpel to DG
- */
- for (j = 0; j < cur_hgt - 1; j++)
- {
- for (i = 0; i < cur_wid - 1; i++)
- {
- int e = cave[j][i].effect;
-
- if (e)
- {
- effect_type *e_ptr = &effects[e];
-
- if (e_ptr->time)
- {
- /* Apply damage */
- project(0, 0, j, i, e_ptr->dam, e_ptr->type,
- PROJECT_KILL | PROJECT_ITEM | PROJECT_HIDE);
- }
- else
- {
- cave[j][i].effect = 0;
- }
-
- if ((e_ptr->flags & EFF_WAVE) && !(e_ptr->flags & EFF_LAST))
- {
- if (distance(e_ptr->cy, e_ptr->cx, j, i) < e_ptr->rad - 1)
- cave[j][i].effect = 0;
- }
- else if ((e_ptr->flags & EFF_STORM) && !(e_ptr->flags & EFF_LAST))
- {
- cave[j][i].effect = 0;
- }
-
- lite_spot(j, i);
- }
- }
- }
-
- /* Reduce & handle effects */
- for (i = 0; i < MAX_EFFECTS; i++)
- {
- /* Skip empty slots */
- if (effects[i].time == 0) continue;
-
- /* Reduce duration */
- effects[i].time--;
-
- /* Creates a "wave" effect*/
- if (effects[i].flags & EFF_WAVE)
- {
- effect_type *e_ptr = &effects[i];
- int x, y, z;
-
- e_ptr->rad++;
-
- /* What a frelling ugly line of ifs ... */
- if (effects[i].flags & EFF_DIR8)
- for (y = e_ptr->cy - e_ptr->rad, z = 0; y <= e_ptr->cy; y++, z++)
- {
- for (x = e_ptr->cx - (e_ptr->rad - z); x <= e_ptr->cx + (e_ptr->rad - z); x++)
- {
- if (!in_bounds(y, x)) continue;
-
- if (los(e_ptr->cy, e_ptr->cx, y, x) &&
- (distance(e_ptr->cy, e_ptr->cx, y, x) == e_ptr->rad))
- cave[y][x].effect = i;
- }
- }
- else if (effects[i].flags & EFF_DIR2)
- for (y = e_ptr->cy, z = e_ptr->rad; y <= e_ptr->cy + e_ptr->rad; y++, z--)
- {
- for (x = e_ptr->cx - (e_ptr->rad - z); x <= e_ptr->cx + (e_ptr->rad - z); x++)
- {
- if (!in_bounds(y, x)) continue;
-
- if (los(e_ptr->cy, e_ptr->cx, y, x) &&
- (distance(e_ptr->cy, e_ptr->cx, y, x) == e_ptr->rad))
- cave[y][x].effect = i;
- }
- }
- else if (effects[i].flags & EFF_DIR6)
- for (x = e_ptr->cx, z = e_ptr->rad; x <= e_ptr->cx + e_ptr->rad; x++, z--)
- {
- for (y = e_ptr->cy - (e_ptr->rad - z); y <= e_ptr->cy + (e_ptr->rad - z); y++)
- {
- if (!in_bounds(y, x)) continue;
-
- if (los(e_ptr->cy, e_ptr->cx, y, x) &&
- (distance(e_ptr->cy, e_ptr->cx, y, x) == e_ptr->rad))
- cave[y][x].effect = i;
- }
- }
- else if (effects[i].flags & EFF_DIR4)
- for (x = e_ptr->cx - e_ptr->rad, z = 0; x <= e_ptr->cx; x++, z++)
- {
- for (y = e_ptr->cy - (e_ptr->rad - z); y <= e_ptr->cy + (e_ptr->rad - z); y++)
- {
- if (!in_bounds(y, x)) continue;
-
- if (los(e_ptr->cy, e_ptr->cx, y, x) &&
- (distance(e_ptr->cy, e_ptr->cx, y, x) == e_ptr->rad))
- cave[y][x].effect = i;
- }
- }
- else if (effects[i].flags & EFF_DIR9)
- for (y = e_ptr->cy - e_ptr->rad; y <= e_ptr->cy; y++)
- {
- for (x = e_ptr->cx; x <= e_ptr->cx + e_ptr->rad; x++)
- {
- if (!in_bounds(y, x)) continue;
-
- if (los(e_ptr->cy, e_ptr->cx, y, x) &&
- (distance(e_ptr->cy, e_ptr->cx, y, x) == e_ptr->rad))
- cave[y][x].effect = i;
- }
- }
- else if (effects[i].flags & EFF_DIR1)
- for (y = e_ptr->cy; y <= e_ptr->cy + e_ptr->rad; y++)
- {
- for (x = e_ptr->cx - e_ptr->rad; x <= e_ptr->cx; x++)
- {
- if (!in_bounds(y, x)) continue;
-
- if (los(e_ptr->cy, e_ptr->cx, y, x) &&
- (distance(e_ptr->cy, e_ptr->cx, y, x) == e_ptr->rad))
- cave[y][x].effect = i;
- }
- }
- else if (effects[i].flags & EFF_DIR7)
- for (y = e_ptr->cy - e_ptr->rad; y <= e_ptr->cy; y++)
- {
- for (x = e_ptr->cx - e_ptr->rad; x <= e_ptr->cx; x++)
- {
- if (!in_bounds(y, x)) continue;
-
- if (los(e_ptr->cy, e_ptr->cx, y, x) &&
- (distance(e_ptr->cy, e_ptr->cx, y, x) == e_ptr->rad))
- cave[y][x].effect = i;
- }
- }
- else if (effects[i].flags & EFF_DIR3)
- for (y = e_ptr->cy; y <= e_ptr->cy + e_ptr->rad; y++)
- {
- for (x = e_ptr->cx; x <= e_ptr->cx + e_ptr->rad; x++)
- {
- if (!in_bounds(y, x)) continue;
-
- if (los(e_ptr->cy, e_ptr->cx, y, x) &&
- (distance(e_ptr->cy, e_ptr->cx, y, x) == e_ptr->rad))
- cave[y][x].effect = i;
- }
- }
- else
- for (y = e_ptr->cy - e_ptr->rad; y <= e_ptr->cy + e_ptr->rad; y++)
- {
- for (x = e_ptr->cx - e_ptr->rad; x <= e_ptr->cx + e_ptr->rad; x++)
- {
- if (!in_bounds(y, x)) continue;
-
- /* This is *slow* -- pelpel */
- if (los(e_ptr->cy, e_ptr->cx, y, x) &&
- (distance(e_ptr->cy, e_ptr->cx, y, x) == e_ptr->rad))
- cave[y][x].effect = i;
- }
- }
- }
- /* Creates a "storm" effect*/
- else if (effects[i].flags & EFF_STORM)
- {
- effect_type *e_ptr = &effects[i];
- int x, y;
-
- e_ptr->cy = p_ptr->py;
- e_ptr->cx = p_ptr->px;
- for (y = e_ptr->cy - e_ptr->rad; y <= e_ptr->cy + e_ptr->rad; y++)
- {
- for (x = e_ptr->cx - e_ptr->rad; x <= e_ptr->cx + e_ptr->rad; x++)
- {
- if (!in_bounds(y, x)) continue;
-
- if (los(e_ptr->cy, e_ptr->cx, y, x) &&
- (distance(e_ptr->cy, e_ptr->cx, y, x) <= e_ptr->rad))
- {
- cave[y][x].effect = i;
- lite_spot(y, x);
- }
- }
- }
- }
- }
-
- apply_effect(p_ptr->py, p_ptr->px);
- }
-
- /* Arg cannot breath? */
- if ((dungeon_flags2 & DF2_WATER_BREATH) && (!p_ptr->water_breath))
- {
- cmsg_print(TERM_L_RED, "You cannot breathe water! You suffocate!");
- take_hit(damroll(3, p_ptr->lev), "suffocating");
- }
- if ((dungeon_flags2 & DF2_NO_BREATH) && (!p_ptr->magical_breath))
- {
- cmsg_print(TERM_L_RED, "There is no air there! You suffocate!");
- take_hit(damroll(3, p_ptr->lev), "suffocating");
- }
-
- /*
- * Every 1500 turns, warn about any Black Breath not gotten from
- * an equipped object, and stop any resting. -LM-
- *
- * It's apparent that someone has halved the frequency... -- pelpel
- */
- if (((turn % 3000) == 0) && p_ptr->black_breath)
- {
- u32b f1, f2, f3, f4, f5;
-
- bool_ be_silent = FALSE;
-
- /* check all equipment for the Black Breath flag. */
- for (i = INVEN_WIELD; i < INVEN_TOTAL; i++)
- {
- o_ptr = &p_ptr->inventory[i];
-
- /* Skip non-objects */
- if (!o_ptr->k_idx) continue;
-
- /* Extract the item flags */
- object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
-
- /* No messages if object has the flag, to avoid annoyance. */
- if (f4 & (TR4_BLACK_BREATH)) be_silent = TRUE;
-
- }
- /* If we are allowed to speak, warn and disturb. */
-
- if (!be_silent)
- {
- cmsg_print(TERM_L_DARK, "The Black Breath saps your soul!");
- disturb(0, 0);
- }
- }
-
-
- /*** Process Light ***/
-
- /* Check for light being wielded */
- o_ptr = &p_ptr->inventory[INVEN_LITE];
-
- /* Burn some fuel in the current lite */
- if (o_ptr->tval == TV_LITE)
- {
- /* Extract the item flags */
- object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
-
- /* Hack -- Use some fuel */
- if ((f4 & TR4_FUEL_LITE) && (o_ptr->timeout > 0))
- {
- /* Decrease life-span */
- o_ptr->timeout--;
-
- /* Hack -- notice interesting fuel steps */
- if ((o_ptr->timeout < 100) || ((o_ptr->timeout % 100) == 0))
- {
- /* Window stuff */
- p_ptr->window |= (PW_EQUIP);
- }
-
- /* Hack -- Special treatment when blind */
- if (p_ptr->blind)
- {
- /* Hack -- save some light for later */
- if (o_ptr->timeout == 0) o_ptr->timeout++;
- }
-
- /* The light is now out */
- else if (o_ptr->timeout < 1)
- {
- disturb(0, 0);
- cmsg_print(TERM_YELLOW, "Your light has gone out!");
- }
-
- /* The light is getting dim */
- else if ((o_ptr->timeout < 100) && (o_ptr->timeout % 10 == 0))
- {
- if (disturb_minor) disturb(0, 0);
- cmsg_print(TERM_YELLOW, "Your light is growing faint.");
- }
- }
- }
-
- /* Calculate torch radius */
- p_ptr->update |= (PU_TORCH);
-
-
- /*** Process Inventory ***/
-
- /*
- * Handle experience draining. In Oangband, the effect is worse,
- * especially for high-level characters. As per Tolkien, hobbits
- * are resistant.
- */
- if (p_ptr->black_breath)
- {
- byte chance = 0;
- int plev = p_ptr->lev;
-
- if (PRACE_FLAG(PR1_RESIST_BLACK_BREATH)) chance = 2;
- else chance = 5;
-
- if ((rand_int(100) < chance) && (p_ptr->exp > 0))
- {
- p_ptr->exp -= 1 + plev / 5;
- p_ptr->max_exp -= 1 + plev / 5;
- (void)do_dec_stat(rand_int(6), STAT_DEC_NORMAL);
- check_experience();
- }
- }
-
- /* Drain Mana */
- if (p_ptr->drain_mana && p_ptr->csp)
- {
- p_ptr->csp -= p_ptr->drain_mana;
- if (magik(30)) p_ptr->csp -= p_ptr->drain_mana;
-
- if (p_ptr->csp < 0)
- {
- p_ptr->csp = 0;
- disturb(0, 0);
- }
-
- /* Redraw */
- p_ptr->redraw |= (PR_MANA);
-
- /* Window stuff */
- p_ptr->window |= (PW_PLAYER);
- }
-
- /* Partial summons drain mana */
- if (p_ptr->maintain_sum)
- {
- u32b oldcsp = p_ptr->csp;
- p_ptr->csp -= p_ptr->maintain_sum / 10000;
-
- if (p_ptr->csp < 0)
- {
- p_ptr->csp = 0;
- disturb(0, 0);
-
- p_ptr->maintain_sum = 0;
- }
- else
- {
- /* Leave behind any fractional sp */
- p_ptr->maintain_sum -= (oldcsp - p_ptr->csp) * 10000;
- }
-
- /* Redraw */
- p_ptr->redraw |= (PR_MANA);
-
- /* Window stuff */
- p_ptr->window |= (PW_PLAYER);
-
- }
-
- /* Drain Hitpoints */
- if (p_ptr->drain_life)
- {
- int drain = p_ptr->drain_life + rand_int(p_ptr->mhp / 100);
-
- p_ptr->chp -= (drain < p_ptr->chp ? drain : p_ptr->chp);
-
- if (p_ptr->chp == 0)
- {
- disturb(0, 0);
- }
-
- /* Redraw */
- p_ptr->redraw |= (PR_HP);
-
- /* Window stuff */
- p_ptr->window |= (PW_PLAYER);
-
- }
-
- /* Handle experience draining */
- if (p_ptr->exp_drain)
- {
- if ((rand_int(100) < 10) && (p_ptr->exp > 0))
- {
- p_ptr->exp--;
- p_ptr->max_exp--;
- check_experience();
- }
- }
-
- /* Process equipment */
- for (j = 0, i = INVEN_WIELD; i < INVEN_TOTAL; i++)
- {
- /* Get the object */
- o_ptr = &p_ptr->inventory[i];
-
- object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
-
-
- /* TY Curse */
- if ((f3 & TR3_TY_CURSE) && (rand_int(TY_CURSE_CHANCE) == 0))
- {
- activate_ty_curse();
- }
-
- /* DG Curse */
- if ((f4 & TR4_DG_CURSE) && (rand_int(DG_CURSE_CHANCE) == 0))
- {
- activate_dg_curse();
-
- /* The object recurse itself ! */
- o_ptr->ident |= IDENT_CURSED;
- }
-
- /* Auto Curse */
- if ((f3 & TR3_AUTO_CURSE) && (rand_int(AUTO_CURSE_CHANCE) == 0))
- {
- /* The object recurse itself ! */
- o_ptr->ident |= IDENT_CURSED;
- }
-
- /*
- * Hack: Uncursed teleporting items (e.g. Dragon Weapons)
- * can actually be useful!
- */
- if ((f3 & TR3_TELEPORT) && (rand_int(100) < 1))
- {
- if ((o_ptr->ident & IDENT_CURSED) && !p_ptr->anti_tele)
- {
- disturb(0, 0);
-
- /* Teleport player */
- teleport_player(40);
- }
- else
- {
- if (p_ptr->wild_mode ||
- (o_ptr->note && strchr(quark_str(o_ptr->note), '.')))
- {
- /* Do nothing */
- /* msg_print("Teleport aborted.") */;
- }
- else if (get_check("Teleport? "))
- {
- disturb(0, 0);
- teleport_player(50);
- }
- }
- }
-
-
- /* Skip non-objects */
- if (!o_ptr->k_idx) continue;
-
- /* Hack: Skip wielded lights that need fuel (already handled above) */
- if ((i == INVEN_LITE) && (o_ptr->tval == TV_LITE) && (f4 & TR4_FUEL_LITE)) continue;
-
- /* Recharge activatable objects */
- if (o_ptr->timeout > 0)
- {
- /* Recharge */
- o_ptr->timeout--;
-
- /* Notice changes */
- if (o_ptr->timeout == 0)
- {
- recharged_notice(o_ptr);
- j++;
- }
- }
-
- /* Recharge second spell in Mage Staffs of Spells */
- if (is_ego_p(o_ptr, EGO_MSTAFF_SPELL) && (o_ptr->xtra2 > 0))
- {
- /* Recharge */
- o_ptr->xtra2--;
-
- /* Notice changes */
- if (o_ptr->xtra2 == 0) j++;
- }
- }
-
- /* Notice changes */
- if (j)
- {
- /* Window stuff */
- p_ptr->window |= (PW_EQUIP);
- }
-
- /* Recharge rods */
- for (j = 0, i = 0; i < INVEN_TOTAL; i++)
- {
- o_ptr = &p_ptr->inventory[i];
-
- /* Skip non-objects */
- if (!o_ptr->k_idx) continue;
-
- /* Examine the rod */
- object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
-
- /* Temporary items are destroyed */
- if (f5 & TR5_TEMPORARY)
- {
- o_ptr->timeout--;
-
- if (o_ptr->timeout <= 0)
- {
- inc_stack_size(i, -99);
-
- /* Combine and Reorder pack */
- p_ptr->notice |= (PN_COMBINE | PN_REORDER);
- }
- }
-
- /* Examine all charging rods or stacks of charging rods. */
- if ((o_ptr->tval == TV_ROD_MAIN) && (o_ptr->timeout < o_ptr->pval2))
- {
- /* Increase the rod's mana. */
- o_ptr->timeout += (f4 & TR4_CHARGING) ? 2 : 1;
-
- /* Always notice */
- j++;
-
- /* Notice changes, provide message if object is inscribed. */
- if (o_ptr->timeout >= o_ptr->pval2)
- {
- o_ptr->timeout = o_ptr->pval2;
- recharged_notice(o_ptr);
- }
- }
-
- /* Examine all charging random artifacts */
- if ((f5 & TR5_ACTIVATE_NO_WIELD) && (o_ptr->timeout > 0))
- {
- /* Charge it */
- o_ptr->timeout--;
-
- /* Notice changes */
- if (o_ptr->timeout == 0)
- {
- j++;
- recharged_notice(o_ptr);
- }
- }
-
- /* Decay objects in pack */
- if (decays(o_ptr))
- {
- /* Decay it */
- if (o_ptr->pval != 0)
- {
- if (o_ptr->timeout > 0)
- {
- if (dungeon_flags1 & DF1_HOT)
- {
- o_ptr->pval -= 2;
- }
- else if ((dungeon_flags1 & DF1_COLD) && rand_int(2))
- {
- if (magik(50)) o_ptr->pval--;
- }
- else
- {
- o_ptr->pval--;
- }
- }
-
- if ((o_ptr->timeout > 0) && o_ptr->timeout < o_ptr->weight) o_ptr->timeout--;
-
- /* Notice changes */
- if (o_ptr->pval <= 0)
- {
- pack_decay(i);
- j++;
- }
- }
- }
-
- /* Hatch eggs */
- if (o_ptr->tval == TV_EGG)
- {
- int mx, my;
-
- if (o_ptr->timeout == 0)
- {
- o_ptr->pval--;
-
- /* Notice changes */
- if (o_ptr->pval <= 0)
- {
- monster_type *m_ptr;
- monster_race *r_ptr;
-
- mx = p_ptr->px;
- my = p_ptr->py + 1;
- get_pos_player(5, &my, &mx);
- msg_print("Your egg hatches!");
- place_monster_aux(my, mx, o_ptr->pval2, FALSE, FALSE, MSTATUS_PET);
-
- m_ptr = &m_list[cave[my][mx].m_idx];
- r_ptr = race_inf(m_ptr);
-
- if ((r_ptr->flags9 & RF9_IMPRESED) && can_create_companion())
- {
- msg_format("And you have given the imprint to your %s!",
- r_name + r_ptr->name);
- m_ptr->status = MSTATUS_COMPANION;
- }
-
- inc_stack_size(i, -1);
-
- j++;
- }
- }
- }
- }
-
- /* Notice changes */
- if (j)
- {
- /* Combine pack */
- p_ptr->notice |= (PN_COMBINE);
-
- /* Window stuff */
- p_ptr->window |= (PW_INVEN);
- }
-
- /*** Process Objects ***/
-
- /* Process objects */
- for (i = 1; i < o_max; i++)
- {
- /* Access object */
- o_ptr = &o_list[i];
-
- /* Skip dead objects */
- if (!o_ptr->k_idx) continue;
-
- /* Examine the rod */
- object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
-
- /* Temporary items are destroyed */
- if (f5 & TR5_TEMPORARY)
- {
- o_ptr->timeout--;
-
- if (o_ptr->timeout <= 0)
- {
- floor_item_increase(i, -99);
- floor_item_optimize(i);
-
- /* Combine and Reorder pack */
- p_ptr->notice |= (PN_COMBINE | PN_REORDER);
- }
- }
-
- /* Recharge rods on the ground. No messages. */
- if ((o_ptr->tval == TV_ROD_MAIN) && (o_ptr->timeout < o_ptr->pval2))
- {
- /* Increase the rod's mana. */
- o_ptr->timeout += (f4 & TR4_CHARGING) ? 2 : 1;
-
- /* Do not overflow */
- if (o_ptr->timeout >= o_ptr->pval2)
- {
- o_ptr->timeout = o_ptr->pval2;
- }
- }
-
- /* Decay objects on the ground*/
- if (decays(o_ptr))
- {
- /* Decay it */
- if (o_ptr->pval != 0)
- {
- if (o_ptr->timeout > 0)
- {
- if (dungeon_flags1 & DF1_HOT)
- {
- o_ptr->pval -= 2;
- }
- else if ((dungeon_flags1 & DF1_COLD) && rand_int(2))
- {
- if (magik(50)) o_ptr->pval--;
- }
- else
- {
- o_ptr->pval--;
- }
- }
-
- if ((o_ptr->timeout > 0) && o_ptr->timeout < o_ptr->weight) o_ptr->timeout--;
-
- /* Turn it into a skeleton */
- if (o_ptr->pval <= 0)
- {
- floor_decay(i);
- }
- }
- }
-
- /* Hatch eggs */
- if (o_ptr->tval == TV_EGG)
- {
- int mx, my;
- if (o_ptr->timeout > 0) o_ptr->pval--;
-
- /* Notice changes */
- if (o_ptr->pval <= 0)
- {
- mx = o_ptr->ix;
- my = o_ptr->iy;
- get_pos_player(5, &my, &mx);
- msg_print("An egg hatches!");
- place_monster_one(my, mx, o_ptr->pval2, 0, FALSE, MSTATUS_ENEMY);
- floor_item_increase(i, -1);
- floor_item_describe(i);
- floor_item_optimize(i);
- }
- }
- }
-
-
- /*** Involuntary Movement ***/
-
- /* Delayed Word-of-Recall */
- if (p_ptr->word_recall)
- {
- /* Can we ? */
- if (process_hooks(HOOK_RECALL, "()", ""))
- {
- p_ptr->word_recall = 0;
- }
-
- /* No recall. sorry */
- else if (dungeon_flags2 & DF2_NO_RECALL_OUT)
- {
- cmsg_print(TERM_L_DARK, "You cannot recall from here.");
- p_ptr->word_recall = 0;
- }
-
- /* Cannot WoR out of death fate levels */
- else if (dungeon_type == DUNGEON_DEATH)
- {
- cmsg_print(TERM_L_DARK, "You are fated to die here. FIGHT for your life!");
- p_ptr->word_recall = 0;
- }
-
- /* I think the 'inside_quest' code belongs here -- pelpel */
-
- /* They cannot use word of recall until reaching surface */
- else if (p_ptr->astral)
- {
- msg_print("As an astral being you can't recall.");
- p_ptr->word_recall = 0;
- }
-
- /* Normal WoR */
- else
- {
- /*
- * HACK: Autosave BEFORE resetting the recall counter (rr9)
- * The player is yanked up/down as soon as
- * he loads the autosaved game.
- */
- if (p_ptr->word_recall == 1)
- {
- autosave_checkpoint();
- }
-
- /* Make SURE that persistent levels are saved
- * I don't know if this is needed, but I'm getting reports,
- * so I'm adding this extra save -- Neil
- */
- save_dungeon();
-
- /* Count down towards recall */
- p_ptr->word_recall--;
-
- /* Activate the recall */
- if (p_ptr->word_recall == 0)
- {
- /* Disturbing! */
- disturb(0, 0);
-
- /* Determine the level */
- if (p_ptr->inside_quest)
- {
- msg_print("The recall is cancelled by a powerful magic force!");
- }
- else if (dun_level)
- {
- msg_print("You feel yourself yanked upwards!");
-
- p_ptr->recall_dungeon = dungeon_type;
- dungeon_type = DUNGEON_WILDERNESS;
- dun_level = 0;
-
- is_recall = TRUE;
-
- p_ptr->inside_quest = 0;
- p_ptr->leaving = TRUE;
- }
- else
- {
- msg_print("You feel yourself yanked downwards!");
-
- /* New depth */
- dungeon_type = p_ptr->recall_dungeon;
- dun_level = max_dlv[dungeon_type];
- if (dun_level < 1) dun_level = 1;
-
- /* Reset player position */
- p_ptr->oldpx = p_ptr->px;
- p_ptr->oldpy = p_ptr->py;
-
- /* Leaving */
- is_recall = TRUE;
-
- p_ptr->leaving = TRUE;
- p_ptr->wild_mode = FALSE;
- }
-
- /* Sound */
- sound(SOUND_TPLEVEL);
- }
- }
- }
-}
-
-
-/*
- * Verify use of "wizard" mode
- */
-static bool_ enter_wizard_mode(void)
-{
- /* Ask first time, but not while loading a dead char with the -w option */
- if (!noscore && !(p_ptr->chp < 0))
- {
- /* Mention effects */
- msg_print("Wizard mode is for debugging and experimenting.");
- msg_print("The game will not be scored if you enter wizard mode.");
- msg_print(NULL);
-
- /* Verify request */
- if (!get_check("Are you sure you want to enter wizard mode? "))
- {
- return (FALSE);
- }
-
- /* Mark savefile */
- noscore |= 0x0002;
- }
-
- /* Success */
- return (TRUE);
-}
-
-
-/*
- * Verify use of "debug" commands
- */
-static bool_ enter_debug_mode(void)
-{
- /* Ask first time */
- if (!noscore && !wizard)
- {
- /* Mention effects */
- msg_print("The debug commands are for debugging and experimenting.");
- msg_print("The game will not be scored if you use debug commands.");
- msg_print(NULL);
-
- /* Verify request */
- if (!get_check("Are you sure you want to use debug commands? "))
- {
- return (FALSE);
- }
-
- /* Mark savefile */
- noscore |= 0x0008;
- }
-
- /* Success */
- return (TRUE);
-}
-
-
-/*
- * Hack -- Declare the Debug Routines
- */
-extern void do_cmd_debug(void);
-
-
-/*
- * Parse and execute the current command
- * Give "Warning" on illegal commands.
- *
- * XXX XXX XXX Make some "blocks"
- */
-static void process_command(void)
-{
- char error_m[80];
-
- /* Handle repeating the last command */
- repeat_check();
-
- /* Process the appropriate hooks */
- if (process_hooks(HOOK_KEYPRESS, "(d)", command_cmd)) return;
-
- /* Parse the command */
- switch (command_cmd)
- {
- /* Ignore */
- case ESCAPE:
- case ' ':
- case 0:
- {
- break;
- }
-
- /* Ignore return */
- case '\r':
- {
- break;
- }
-
-#ifdef ALLOW_QUITTING
-
- case KTRL('L'):
- {
- quit("CHEATER");
- break;
- }
-
-#endif
-
-
- /*** Wizard Commands ***/
-
- /* Toggle Wizard Mode */
- case KTRL('W'):
- {
- if (wizard)
- {
- wizard = FALSE;
- msg_print("Wizard mode off.");
- }
- else if (enter_wizard_mode())
- {
- wizard = TRUE;
- msg_print("Wizard mode on.");
- }
-
- /* Update monsters */
- p_ptr->update |= (PU_MONSTERS);
-
- /* Redraw "title" */
- p_ptr->redraw |= (PR_TITLE);
-
- break;
- }
-
- /* Special "debug" commands */
- case KTRL('A'):
- {
- /* Enter debug mode */
- if (enter_debug_mode())
- {
- do_cmd_debug();
- }
- break;
- }
-
-
- /*** Inventory Commands ***/
-
- /* Wear/wield equipment */
- case 'w':
- {
- if (p_ptr->control) break;
- if (!p_ptr->wild_mode) do_cmd_wield();
- break;
- }
-
- /* Take off equipment */
- case 't':
- {
- if (p_ptr->control) break;
- if (!p_ptr->wild_mode) do_cmd_takeoff();
- p_ptr->redraw |= (PR_MH);
- break;
- }
-
- /* Drop an item */
- case 'd':
- {
- if (do_control_drop()) break;
- if (!p_ptr->wild_mode) do_cmd_drop();
- break;
- }
-
- /* Destroy an item */
- case 'k':
- {
- if (p_ptr->control) break;
- do_cmd_destroy();
- break;
- }
-
- /* Equipment list */
- case 'e':
- {
- if (p_ptr->control) break;
- do_cmd_equip();
- break;
- }
-
- /* Inventory list */
- case 'i':
- {
- if (do_control_inven()) break;
- do_cmd_inven();
- break;
- }
-
-
- /*** Various commands ***/
-
- /* Identify an object */
- case 'I':
- {
- do_cmd_observe();
- break;
- }
-
- /* Hack -- toggle windows */
- case KTRL('I'):
- {
- toggle_inven_equip();
- break;
- }
-
-
- /*** Standard "Movement" Commands ***/
-
- /* Alter a grid */
- case '+':
- {
- if (p_ptr->control) break;
- if (!p_ptr->wild_mode) do_cmd_alter();
- break;
- }
-
- /* Dig a tunnel */
- case 'T':
- {
- if (p_ptr->control) break;
- if (!p_ptr->wild_mode) do_cmd_tunnel();
- break;
- }
-
- /* Move (usually pick up things) */
- case ';':
- {
- if (do_control_walk()) break;
-
- do_cmd_walk(always_pickup, TRUE);
-
- break;
- }
-
- /* Move (usually do not pick up) */
- case '-':
- {
- if (do_control_walk()) break;
-
- do_cmd_walk(!always_pickup, TRUE);
-
- break;
- }
-
-
- /*** Running, Resting, Searching, Staying */
-
- /* Begin Running -- Arg is Max Distance */
- case '.':
- {
- if (p_ptr->control || p_ptr->wild_mode) break;
- do_cmd_run();
- break;
- }
-
- /* Stay still (usually pick things up) */
- case ',':
- {
- if (do_control_pickup()) break;
- do_cmd_stay(always_pickup);
- break;
- }
-
- /* Stay still (usually do not pick up) */
- case 'g':
- {
- if (p_ptr->control) break;
- do_cmd_stay(!always_pickup);
- break;
- }
-
- /* Rest -- Arg is time */
- case 'R':
- {
- if (p_ptr->control) break;
- do_cmd_rest();
- break;
- }
-
- /* Search for traps/doors */
- case 's':
- {
- if (p_ptr->control) break;
- do_cmd_search();
- break;
- }
-
- /* Toggle search mode */
- case 'S':
- {
- if (p_ptr->control) break;
- do_cmd_toggle_search();
- break;
- }
-
-
- /*** Stairs and Doors and Chests and Traps ***/
-
- /* Enter store */
- case '_':
- {
- if (p_ptr->control) break;
- if (!p_ptr->wild_mode) do_cmd_store();
- break;
- }
-
- /* Go up staircase */
- case '<':
- {
- object_type *o_ptr;
- u32b f1 = 0 , f2 = 0 , f3 = 0, f4 = 0, f5 = 0, esp = 0;
-
-
- /* Check for light being wielded */
- o_ptr = &p_ptr->inventory[INVEN_LITE];
- /* Burn some fuel in the current lite */
- if (o_ptr->tval == TV_LITE)
- /* Extract the item flags */
- object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
-
- /* Cannot move if rooted in place */
- if (p_ptr->tim_roots) break;
-
- if (p_ptr->control) break;
- /* Normal cases */
- if (p_ptr->wild_mode || dun_level || is_quest(dun_level))
- {
- do_cmd_go_up();
- }
- /* Don't let the player < when he'd just drop right back down */
- else if (p_ptr->food < PY_FOOD_ALERT)
- {
- msg_print("You are too hungry to travel.");
- }
- else if (p_ptr->sensible_lite &&
- (((turn / ((10L * DAY) / 2)) % 2) == 0))
- {
- /* Burn vampires! burn! */
- msg_print("You can't travel during the day!");
- }
- else if (p_ptr->sensible_lite &&
- (o_ptr->tval != 0) &&
- (o_ptr->sval >= SV_LITE_GALADRIEL) &&
- (o_ptr->sval <= SV_STONE_LORE) &&
- (o_ptr->sval != SV_LITE_UNDEATH))
- {
- msg_print("Travel with your present light would be unsafe.");
- }
- else if (p_ptr->cut || p_ptr->poisoned)
- {
- /* I actually died this way once -- neil */
- msg_print("You are too injured to travel.");
- }
- else if (ambush_flag)
- {
- msg_print("To flee the ambush you have to reach the edge of the map.");
- }
- /* TODO: make the above stuff use this hook */
- else if (!process_hooks(HOOK_FORBID_TRAVEL, "()"))
- {
- p_ptr->oldpx = p_ptr->px;
- p_ptr->oldpy = p_ptr->py;
- change_wild_mode();
-
- /* Update the known wilderness */
- reveal_wilderness_around_player(p_ptr->wilderness_y,
- p_ptr->wilderness_x,
- 0, WILDERNESS_SEE_RADIUS);
- }
-
- break;
- }
-
- /* Go down staircase */
- case '>':
- {
- /* Cannot move if rooted in place */
- if (p_ptr->tim_roots) break;
-
- if (p_ptr->control) break;
- /* Normal cases */
- if (!p_ptr->wild_mode)
- {
- do_cmd_go_down();
- }
-
- /* Special cases */
- else
- {
- if ((wf_info[wild_map[p_ptr->py][p_ptr->px].feat].entrance >= 1000) ||
- (wild_map[p_ptr->py][p_ptr->px].entrance > 1000))
- {
- p_ptr->wilderness_x = p_ptr->px;
- p_ptr->wilderness_y = p_ptr->py;
- p_ptr->wild_mode = !p_ptr->wild_mode;
- do_cmd_go_down();
-
- if (dun_level == 0)
- {
- p_ptr->wild_mode = !p_ptr->wild_mode;
- }
- else
- {
- p_ptr->wilderness_x = p_ptr->px;
- p_ptr->wilderness_y = p_ptr->py;
- change_wild_mode();
- }
- }
- else
- {
- p_ptr->wilderness_x = p_ptr->px;
- p_ptr->wilderness_y = p_ptr->py;
- change_wild_mode();
- }
- }
-
- break;
- }
-
- /* Open a door or chest */
- case 'o':
- {
- if (p_ptr->control) break;
- if (!p_ptr->wild_mode) do_cmd_open();
- break;
- }
-
- /* Close a door */
- case 'c':
- {
- if (p_ptr->control) break;
- if (!p_ptr->wild_mode) do_cmd_close();
- break;
- }
-
- /* Give an item */
- case 'y':
- {
- if (p_ptr->control) break;
- if (!p_ptr->wild_mode) do_cmd_give();
- break;
- }
-
- /* Chat */
- case 'Y':
- {
- if (p_ptr->control) break;
- if (!p_ptr->wild_mode) do_cmd_chat();
- break;
- }
-
- /* Jam a door with spikes */
- case 'j':
- {
- if (p_ptr->control) break;
- if (!p_ptr->wild_mode) do_cmd_spike();
- break;
- }
-
- /* Bash a door */
- case 'B':
- {
- if (p_ptr->control) break;
- if (!p_ptr->wild_mode) do_cmd_bash();
- break;
- }
-
- /* Disarm a trap or chest */
- case 'D':
- {
- if (p_ptr->control) break;
- if (!p_ptr->wild_mode) do_cmd_disarm();
- break;
- }
-
-
- /*** Magic and Prayers ***/
-
- /* Interact with skills */
- case 'G':
- {
- if (p_ptr->control) break;
- do_cmd_skill();
- break;
- }
-
- /* Interact with abilities */
- case 'N':
- {
- if (p_ptr->control) break;
- do_cmd_ability();
- break;
- }
-
- /* Browse a book */
- case 'b':
- {
- if (p_ptr->control) break;
- do_cmd_browse();
- break;
- }
-
- /* Cast a spell */
- case 'm':
- {
- if (do_control_magic()) break;
-
- /* No magic in the overworld map */
- if (p_ptr->wild_mode) break;
-
- /* Neither in the Arena */
- if (p_ptr->inside_arena)
- {
- msg_print("The arena absorbs all attempted magic!");
-
- break;
- }
- do_cmd_activate_skill();
- squeltch_inventory();
- squeltch_grid();
- break;
- }
-
- /* Pray a prayer */
- case 'p':
- {
- if (p_ptr->control || p_ptr->wild_mode) break;
- do_cmd_pray();
- squeltch_inventory();
- squeltch_grid();
- break;
- }
-
- /* Issue commands to pets */
- case 'P':
- {
- if (p_ptr->control) break;
- if (!p_ptr->wild_mode) do_cmd_pet();
- break;
- }
-
- /* Cut up a corpse */
- case 'h':
- {
- if (p_ptr->control || p_ptr->wild_mode) break;
- do_cmd_cut_corpse();
- squeltch_inventory();
- squeltch_grid();
- break;
- }
-
- /* Cure some meat */
- case 'K':
- {
- if (p_ptr->control) break;
- do_cmd_cure_meat();
- squeltch_inventory();
- squeltch_grid();
- break;
- }
-
- /* Steal an item form a monster */
- case 'Z':
- {
- if (p_ptr->control || p_ptr->wild_mode) break;
- do_cmd_steal();
- squeltch_inventory();
- squeltch_grid();
- break;
- }
-
- /*** Use various objects ***/
-
- /* Inscribe an object */
- case '{':
- {
- if (p_ptr->control) break;
- do_cmd_inscribe();
- break;
- }
-
- /* Uninscribe an object */
- case '}':
- {
- if (p_ptr->control) break;
- do_cmd_uninscribe();
- break;
- }
-
- /* Activate an artifact */
- case 'A':
- {
- if (p_ptr->control) break;
- if (p_ptr->wild_mode) break;
-
- if (p_ptr->inside_arena)
- {
- msg_print("The arena absorbs all attempted magic!");
- msg_print(NULL);
- break;
- }
-
- do_cmd_activate();
- squeltch_inventory();
- squeltch_grid();
- break;
- }
-
- /* Eat some food */
- case 'E':
- {
- if (p_ptr->control) break;
- do_cmd_eat_food();
- break;
- }
-
- /* Fuel your lantern/torch */
- case 'F':
- {
- if (p_ptr->control) break;
- do_cmd_refill();
- break;
- }
-
- /* Fire an item */
- case 'f':
- {
- object_type *j_ptr;
-
- if (p_ptr->control) break;
- if (p_ptr->wild_mode) break;
-
- if (p_ptr->inside_arena)
- {
- msg_print("You're in the arena now. This is hand-to-hand!");
- msg_print(NULL);
- break;
- }
-
- j_ptr = &p_ptr->inventory[INVEN_BOW];
-
- if (process_hooks(HOOK_FIRE, "(O)", j_ptr))
- break;
-
- if (j_ptr->tval == TV_BOOMERANG)
- {
- do_cmd_boomerang();
- }
- else
- {
- do_cmd_fire();
- }
-
- break;
- }
-
- /* Throw an item */
- case 'v':
- {
- if (p_ptr->control) break;
- if (p_ptr->wild_mode) break;
-
- if (p_ptr->inside_arena)
- {
- msg_print("You're in the arena now. This is hand-to-hand!");
- msg_print(NULL);
- break;
- }
-
- do_cmd_throw();
- break;
- }
-
- /* Aim a wand */
- case 'a':
- {
- if (p_ptr->control) break;
- if (p_ptr->wild_mode) break;
-
- if (p_ptr->inside_arena)
- {
- msg_print("The arena absorbs all attempted magic!");
- msg_print(NULL);
- break;
- }
-
- do_cmd_aim_wand();
- squeltch_inventory();
- squeltch_grid();
- break;
- }
-
- /* Zap a rod */
- case 'z':
- {
- if (p_ptr->control) break;
- if (p_ptr->wild_mode) break;
-
- if (p_ptr->inside_arena)
- {
- msg_print("The arena absorbs all attempted magic!");
- msg_print(NULL);
- break;
- }
-
- do_cmd_zap_rod();
- squeltch_inventory();
- squeltch_grid();
- break;
- }
-
- /* Quaff a potion */
- case 'q':
- {
- if (p_ptr->control) break;
- if (p_ptr->wild_mode) break;
-
- if (p_ptr->inside_arena)
- {
- msg_print("The arena absorbs all attempted magic!");
- msg_print(NULL);
- break;
- }
-
- do_cmd_quaff_potion();
- squeltch_inventory();
- squeltch_grid();
- break;
- }
-
- /* Drink from a fountain -SC- */
- case 'H':
- {
- cave_type *c_ptr = &cave[p_ptr->py][p_ptr->px];
-
- if (p_ptr->control) break;
- if ((c_ptr->feat == FEAT_FOUNTAIN) ||
- (c_ptr->feat == FEAT_EMPTY_FOUNTAIN))
- {
- do_cmd_drink_fountain();
- squeltch_inventory();
- squeltch_grid();
- }
- else
- {
- msg_print("You see no fountain here.");
- }
-
- break;
- }
-
- /* Read a scroll */
- case 'r':
- {
- if (p_ptr->control) break;
- if (p_ptr->wild_mode) break;
-
- if (p_ptr->inside_arena)
- {
- msg_print("The arena absorbs all attempted magic!");
- msg_print(NULL);
- break;
- }
-
- do_cmd_read_scroll();
- squeltch_inventory();
- squeltch_grid();
- break;
- }
-
- /* Use a staff */
- case 'u':
- {
- if (p_ptr->control) break;
- if (p_ptr->wild_mode) break;
-
- if (p_ptr->inside_arena)
- {
- msg_print("The arena absorbs all attempted magic!");
- msg_print(NULL);
- break;
- }
-
- do_cmd_use_staff();
- squeltch_inventory();
- squeltch_grid();
- break;
- }
-
- /* Use racial power */
- case 'U':
- {
- if (p_ptr->control) break;
- if (p_ptr->wild_mode) break;
-
- if (p_ptr->inside_arena)
- {
- msg_print("The arena absorbs all attempted magic!");
- msg_print(NULL);
- break;
- }
-
- do_cmd_power();
- squeltch_inventory();
- squeltch_grid();
- break;
- }
-
- /* Sacrifice at an altar */
- case 'O':
- {
- if (p_ptr->control) break;
- if (p_ptr->wild_mode) break;
-
- if (PRACE_FLAG(PR1_NO_GOD))
- {
- msg_print("You cannot worship gods.");
- }
- else
- {
- do_cmd_sacrifice();
- }
-
- break;
- }
-
- /*** Looking at Things (nearby or on map) ***/
-
- /* Full dungeon map */
- case 'M':
- {
- if (!p_ptr->wild_mode) do_cmd_view_map();
- break;
- }
-
- /* Locate player on map */
- case 'L':
- {
- do_cmd_locate();
- break;
- }
-
- /* Look around */
- case 'l':
- {
- do_cmd_look();
- break;
- }
-
- /* Target monster or location */
- case '*':
- {
- if (p_ptr->control) break;
- if (!p_ptr->wild_mode) do_cmd_target();
- break;
- }
-
- /* Engrave the floor */
- case 'x':
- {
- if (p_ptr->control) break;
- if (p_ptr->wild_mode) break;
-
- /* No point in engraving if there isn't any mana on this grid. */
- /* DG - actualy there is, it doesnt break macros */
- do_cmd_sense_grid_mana();
- do_cmd_engrave();
-
- break;
- }
-
- /*** Help and Such ***/
-
- /* Help */
- case '?':
- {
- do_cmd_help();
- break;
- }
-
- /* Identify symbol */
- case '/':
- {
- do_cmd_query_symbol();
- break;
- }
-
- /* Character description */
- case 'C':
- {
- do_cmd_change_name();
- break;
- }
-
-
- /*** System Commands ***/
-
- /* Hack -- User interface */
- case '!':
- {
- (void)Term_user(0);
- break;
- }
-
- /* Single line from a pref file */
- case '"':
- {
- do_cmd_pref();
- break;
- }
-
- /* Interact with macros */
- case '@':
- {
- do_cmd_macros();
- break;
- }
-
- /* Interact with visuals */
- case '%':
- {
- do_cmd_visuals();
- break;
- }
-
- /* Interact with colors */
- case '&':
- {
- do_cmd_colors();
- break;
- }
-
- /* Interact with options */
- case '=':
- {
- do_cmd_options();
- break;
- }
-
-
- /*** Misc Commands ***/
-
- /* Take notes */
- case ':':
- {
- do_cmd_note();
- break;
- }
-
- /* Version info */
- case 'V':
- {
- do_cmd_version();
- break;
- }
-
- /* Repeat level feeling */
- case KTRL('F'):
- {
- if (!p_ptr->wild_mode)
- do_cmd_feeling();
- break;
- }
-
- /* Show previous message */
- case KTRL('O'):
- {
- do_cmd_message_one();
- break;
- }
-
- /* Show previous messages */
- case KTRL('P'):
- {
- do_cmd_messages();
- break;
- }
-
- /* Show quest status -KMW- */
- case KTRL('Q'):
- case CMD_QUEST:
-{
- do_cmd_checkquest();
- break;
- }
-
- /* Redraw the screen */
- case KTRL('R'):
- {
- do_cmd_redraw();
- break;
- }
-
- /* Hack -- Save and don't quit */
- case KTRL('S'):
- {
- is_autosave = FALSE;
- do_cmd_save_game();
- break;
- }
-
- case KTRL('T'):
- {
- do_cmd_time();
- }
- break;
-
- /* Save and quit */
- case KTRL('X'):
- {
- alive = FALSE;
-
- /* Leaving */
- p_ptr->leaving = TRUE;
-
- break;
- }
-
- /* Quit (commit suicide) */
- case 'Q':
- {
- do_cmd_suicide();
- break;
- }
-
- /* Activate cmovie */
- case '|':
- {
- /* Stop ? */
- if (do_movies == 1)
- {
- do_stop_cmovie();
- msg_print("Cmovie recording stopped.");
- }
- else
- {
- do_start_cmovie();
- }
- break;
- }
-
- /* Extended command */
- case '#':
- {
- do_cmd_cli();
- break;
- }
-
- /* Check artifacts, uniques, objects */
- case '~':
- {
- do_cmd_knowledge();
- break;
- }
-
- /* Commands only available as extended commands: */
-
- /* Extended command help. */
- case CMD_CLI_HELP:
- {
- do_cmd_cli_help();
- break;
- }
-
- /* Game time. */
- case CMD_SHOW_TIME:
- {
- do_cmd_time();
- break;
- }
-
- /* Check skills. */
- case CMD_SHOW_SKILL:
- {
- do_cmd_skill();
- break;
- }
-
- /* Check abilities. */
- case CMD_SHOW_ABILITY:
- {
- do_cmd_ability();
- break;
- }
-
- /* Save a html screenshot. */
- case CMD_DUMP_HTML:
- {
- do_cmd_html_dump();
- break;
- }
-
- /* Record a macro. */
- case '$':
- case CMD_MACRO:
- {
- do_cmd_macro_recorder();
- break;
- }
- case CMD_BLUNDER:
- {
- if (do_control_walk()) break;
- do_cmd_walk(always_pickup, FALSE);
- break;
- }
- /* Hack -- Unknown command */
- default:
- {
- int insanity = (p_ptr->msane - p_ptr->csane) * 100 / p_ptr->msane;
-
- /* Would like to have an option disabling this -- pelpel */
- if (rand_int(100) < insanity)
- {
- get_rnd_line("error.txt", error_m);
- sound(SOUND_ILLEGAL);
- msg_print(error_m);
- }
- else
- {
- prt("Type '?' for help.", 0, 0);
- }
-
- break;
- }
- }
-}
-
-
-
-
-/*
- * Process the player
- *
- * Notice the annoying code to handle "pack overflow", which
- * must come first just in case somebody manages to corrupt
- * the savefiles by clever use of menu commands or something.
- */
-void process_player(void)
-{
- int i, j;
-
- int speed_use;
-
-
- /*** Apply energy ***/
-
- if (hack_corruption)
- {
- msg_print("You feel different!");
- (void)gain_random_corruption(0);
- hack_corruption = FALSE;
- }
-
- /* Obtain current speed */
- speed_use = p_ptr->pspeed;
-
- /* Maximum value */
- if (speed_use > 199)
- {
- speed_use = 199;
- }
-
- /* Minimum value */
- else if (speed_use < 0)
- {
- speed_use = 0;
- }
-
- /* Give the player some energy */
- p_ptr->energy += extract_energy[speed_use];
-
- /* No turn yet */
- if (p_ptr->energy < 100) return;
-
-
- /*** Check for interupts ***/
-
- /* Complete resting */
- if (resting < 0)
- {
- /* Basic resting */
- if (resting == -1)
- {
- /* Stop resting */
- if ((p_ptr->chp == p_ptr->mhp) && (p_ptr->csp >= p_ptr->msp))
- {
- disturb(0, 0);
- }
- }
-
- /* Complete resting */
- else if (resting == -2)
- {
- bool_ stop = TRUE;
- object_type *o_ptr;
-
- /* Get the carried monster */
- o_ptr = &p_ptr->inventory[INVEN_CARRY];
-
- /* Stop resting */
- if ((!p_ptr->drain_life) && (p_ptr->chp != p_ptr->mhp)) stop = FALSE;
- if ((!p_ptr->drain_mana) && (p_ptr->csp != p_ptr->msp)) stop = FALSE;
- if (o_ptr->pval2 < o_ptr->pval3) stop = FALSE;
- if (p_ptr->blind || p_ptr->confused) stop = FALSE;
- if (p_ptr->poisoned || p_ptr->afraid) stop = FALSE;
- if (p_ptr->stun || p_ptr->cut) stop = FALSE;
- if (p_ptr->slow || p_ptr->paralyzed) stop = FALSE;
- if (p_ptr->image || p_ptr->word_recall) stop = FALSE;
- if (p_ptr->immov_cntr != 0) stop = FALSE;
-
- for (i = 0; i < 6; i++)
- {
- if (p_ptr->stat_cnt[i] > 0) stop = FALSE;
- }
-
- if (stop)
- {
- disturb(0, 0);
- }
- p_ptr->redraw |= (PR_STATE);
- }
- }
-
- /* Handle "abort" */
- if (!avoid_abort)
- {
- /* Check for "player abort" (semi-efficiently for resting) */
- if (running || command_rep || (resting && !(resting & 0x0F)))
- {
- /* Do not wait */
- inkey_scan = TRUE;
-
- /* Check for a key */
- if (inkey())
- {
- /* Flush input */
- flush();
-
- /* Disturb */
- disturb(0, 0);
-
- /* Hack -- Show a Message */
- msg_print("Cancelled.");
- }
- }
- }
-
-
- /*** Handle actual user input ***/
-
- /* Repeat until out of energy */
- while (p_ptr->energy >= 100)
- {
- /* Notice stuff (if needed) */
- if (p_ptr->notice) notice_stuff();
-
- /* Update stuff (if needed) */
- if (p_ptr->update) update_stuff();
-
- /* Redraw stuff (if needed) */
- if (p_ptr->redraw) redraw_stuff();
-
- /* Redraw stuff (if needed) */
- if (p_ptr->window) window_stuff();
-
- /* Hack -- mark current wilderness location as known */
- if (!p_ptr->wild_mode && dun_level == 0)
- wild_map[p_ptr->wilderness_y][p_ptr->wilderness_x].known = TRUE;
-
-
- /* Place the cursor on the player */
- move_cursor_relative(p_ptr->py, p_ptr->px);
-
- /* Refresh (optional) */
- if (fresh_before) Term_fresh();
-
- /* Hack -- Pack Overflow */
- if (p_ptr->inventory[INVEN_PACK].k_idx)
- {
- int item = INVEN_PACK;
-
- char o_name[80];
-
- object_type *o_ptr;
-
- /* Access the slot to be dropped */
- o_ptr = &p_ptr->inventory[item];
-
- /* Disturbing */
- disturb(0, 0);
-
- /* Warning */
- msg_print("Your pack overflows!");
-
- /* Describe */
- object_desc(o_name, o_ptr, TRUE, 3);
-
- /* Message */
- msg_format("You drop %s (%c).", o_name, index_to_label(item));
-
- /* Drop it (carefully) near the player */
- drop_near(o_ptr, 0, p_ptr->py, p_ptr->px);
-
- /* Modify, Describe, Optimize */
- inc_stack_size(item, -255);
-
- /* Notice stuff (if needed) */
- if (p_ptr->notice) notice_stuff();
-
- /* Update stuff (if needed) */
- if (p_ptr->update) update_stuff();
-
- /* Redraw stuff (if needed) */
- if (p_ptr->redraw) redraw_stuff();
-
- /* Redraw stuff (if needed) */
- if (p_ptr->window) window_stuff();
- }
-
-
- /* Assume free turn */
- energy_use = 0;
-
-
- /* Paralyzed or Knocked Out */
- if ((p_ptr->paralyzed) || (p_ptr->stun >= 100))
- {
- /* Take a turn */
- energy_use = 100;
- }
-
- /* Resting */
- else if (resting)
- {
- /* Timed rest */
- if (resting > 0)
- {
- /* Reduce rest count */
- resting--;
-
- /* Redraw the state */
- p_ptr->redraw |= (PR_STATE);
- }
-
- p_ptr->did_nothing = TRUE;
-
- /* Take a turn */
- energy_use = 100;
- }
-
- /* Running */
- else if (running)
- {
- /* Take a step */
- run_step(0);
-
- /*
- * Commented out because it doesn't make any sense
- * to require a player holding down direction keys
- * instead of using running commands when s/he follows
- * Eru and do the opposite for the other deities -- pelpel
- */
- /* p_ptr->did_nothing = TRUE; */
- }
-
- /* Repeated command */
- else if (command_rep)
- {
- /* Count this execution */
- command_rep--;
-
- /* Redraw the state */
- p_ptr->redraw |= (PR_STATE);
-
- /* Redraw stuff */
- redraw_stuff();
-
- /* Hack -- Assume messages were seen */
- msg_flag = FALSE;
-
- /* Clear the top line */
- prt("", 0, 0);
-
- /* Process the command */
- process_command();
-
- p_ptr->did_nothing = TRUE;
- }
-
- /* Normal command */
- else
- {
- /* Place the cursor on the player */
- move_cursor_relative(p_ptr->py, p_ptr->px);
-
- /* Get a command (normal) */
- request_command(FALSE);
-
- /* Process the command */
- process_command();
- }
-
-
- /*** Clean up ***/
-
- /* Significant */
- if (energy_use)
- {
- /* Use some energy */
- p_ptr->energy -= energy_use;
-
-
- /* Hack -- constant hallucination */
- if (p_ptr->image) p_ptr->redraw |= (PR_MAP);
-
-
- /* Shimmer monsters if needed */
- if (!avoid_other && !use_graphics && shimmer_monsters)
- {
- /* Clear the flag */
- shimmer_monsters = FALSE;
-
- /* Shimmer multi-hued monsters */
- for (i = 1; i < m_max; i++)
- {
- monster_type *m_ptr;
- monster_race *r_ptr;
-
- /* Access monster */
- m_ptr = &m_list[i];
-
- /* Skip dead monsters */
- if (!m_ptr->r_idx) continue;
-
- /* Access the monster race */
- r_ptr = race_inf(m_ptr);
-
- /* Skip non-multi-hued monsters */
- if (!(r_ptr->flags1 & (RF1_ATTR_MULTI))) continue;
-
- /* Reset the flag */
- shimmer_monsters = TRUE;
-
- /* Redraw regardless */
- lite_spot(m_ptr->fy, m_ptr->fx);
- }
- }
-
- /* Shimmer objects if needed and requested */
- if (!avoid_other && !avoid_shimmer && !use_graphics &&
- shimmer_objects)
- {
- /* Clear the flag */
- shimmer_objects = FALSE;
-
- /* Shimmer multi-hued objects */
- for (i = 1; i < o_max; i++)
- {
- /* Acquire object -- for speed only base items are allowed to shimmer */
- object_type *o_ptr = &o_list[i];
- object_kind *k_ptr = &k_info[o_ptr->k_idx];
-
- /* Skip dead or carried objects */
- if ((!o_ptr->k_idx) || (!o_ptr->ix)) continue;
-
- /* Skip non-multi-hued monsters */
- if (!(k_ptr->flags5 & (TR5_ATTR_MULTI))) continue;
-
- /* Reset the flag */
- shimmer_objects = TRUE;
-
- /* Redraw regardless */
- lite_spot(o_ptr->iy, o_ptr->ix);
- }
- }
-
- /*
- * Shimmer features if needed and requested
- *
- * Note: this can be unbearably slow when a player chooses
- * to use a REALLY big screen in levels filled with shallow
- * water. I believe this also hurts a lot on multiuser systems.
- * However fast modern processors are, I/O cannot be made that
- * fast, and that's why shimmering has been limited to small
- * number of monsters -- pelpel
- */
- if (!avoid_other && !avoid_shimmer && !use_graphics &&
- !resting && !running)
- {
- for (j = panel_row_min; j <= panel_row_max; j++)
- {
- for (i = panel_col_min; i <= panel_col_max; i++)
- {
- cave_type *c_ptr = &cave[j][i];
- feature_type *f_ptr;
-
- /* Apply terrain feature mimics */
- if (c_ptr->mimic)
- {
- f_ptr = &f_info[c_ptr->mimic];
- }
- else
- {
- f_ptr = &f_info[f_info[c_ptr->feat].mimic];
- }
-
- /* Skip normal features */
- if (!(f_ptr->flags1 & (FF1_ATTR_MULTI))) continue;
-
- /* Redraw a shimmering spot */
- lite_spot(j, i);
- }
- }
- }
-
-
- /* Handle monster detection */
- if (repair_monsters)
- {
- /* Reset the flag */
- repair_monsters = FALSE;
-
- /* Rotate detection flags */
- for (i = 1; i < m_max; i++)
- {
- monster_type *m_ptr;
-
- /* Access monster */
- m_ptr = &m_list[i];
-
- /* Skip dead monsters */
- if (!m_ptr->r_idx) continue;
-
- /* Nice monsters get mean */
- if (m_ptr->mflag & (MFLAG_NICE))
- {
- /* Nice monsters get mean */
- m_ptr->mflag &= ~(MFLAG_NICE);
- }
-
- /* Handle memorized monsters */
- if (m_ptr->mflag & (MFLAG_MARK))
- {
- /* Maintain detection */
- if (m_ptr->mflag & (MFLAG_SHOW))
- {
- /* Forget flag */
- m_ptr->mflag &= ~(MFLAG_SHOW);
-
- /* Still need repairs */
- repair_monsters = TRUE;
- }
-
- /* Remove detection */
- else
- {
- /* Forget flag */
- m_ptr->mflag &= ~(MFLAG_MARK);
-
- /* Assume invisible */
- m_ptr->ml = FALSE;
-
- /* Update the monster */
- update_mon(i, FALSE);
-
- /* Redraw regardless */
- lite_spot(m_ptr->fy, m_ptr->fx);
- }
- }
- }
- }
-
- /*
- * Moved from dungeon() -- It'll get called whenever player
- * spends energy, so that maze isn't incredibly easy for
- * Sorcerors and alike any longer -- pelpel
- *
- * Forget everything when requested hehe I'm *NASTY*
- */
- if (dun_level && (dungeon_flags1 & DF1_FORGET))
- {
- wiz_dark();
- }
- }
-
-
- /* Hack -- notice death */
- if (!alive || death) break;
-
- /* Handle "leaving" */
- if (p_ptr->leaving) break;
- }
-}
-
-
-
-/*
- * Interact with the current dungeon level.
- *
- * This function will not exit until the level is completed,
- * the user dies, or the game is terminated.
- */
-static void dungeon(void)
-{
- /* Reset various flags */
- hack_mind = FALSE;
-
- /* Not leaving */
- p_ptr->leaving = FALSE;
-
- /* Reset the "command" vars */
- command_cmd = 0;
- command_new = 0;
- command_rep = 0;
- command_arg = 0;
- command_dir = 0;
-
- /* Make sure partial summoning counter is initialized. */
- p_ptr->maintain_sum = 0;
-
- /* Cancel the target */
- target_who = 0;
-
- /* Cancel the health bar */
- health_track(0);
-
-
- /* Check visual effects */
- shimmer_monsters = TRUE;
- shimmer_objects = TRUE;
- repair_monsters = TRUE;
- repair_objects = TRUE;
-
-
- /* Disturb */
- disturb(1, 0);
-
- /* Track maximum player level */
- if (p_ptr->max_plv < p_ptr->lev)
- {
- p_ptr->max_plv = p_ptr->lev;
- }
-
- /* Track maximum dungeon level (if not in quest -KMW-) */
- if ((max_dlv[dungeon_type] < dun_level) && !p_ptr->inside_quest)
- {
- max_dlv[dungeon_type] = dun_level;
- }
-
- /* No stairs down from Quest */
- if (is_quest(dun_level) && !p_ptr->astral)
- {
- create_down_stair = FALSE;
- create_down_shaft = FALSE;
- }
-
- /* Paranoia -- no stairs from town or wilderness */
- if (!dun_level) create_down_stair = create_up_stair = FALSE;
- if (!dun_level) create_down_shaft = create_up_shaft = FALSE;
-
- /* Option -- no connected stairs */
- if (!dungeon_stair) create_down_stair = create_up_stair = FALSE;
- if (!dungeon_stair) create_down_shaft = create_up_shaft = FALSE;
-
- /* no connecting stairs on special levels */
- if (!(dungeon_flags2 & DF2_NO_STAIR)) create_down_stair = create_up_stair = FALSE;
- if (!(dungeon_flags2 & DF2_NO_STAIR)) create_down_shaft = create_up_shaft = FALSE;
-
- /* Make a stairway. */
- if ((create_up_stair || create_down_stair ||
- create_up_shaft || create_down_shaft) &&
- !get_fbranch())
- {
- /* Place a stairway */
- if (cave_valid_bold(p_ptr->py, p_ptr->px))
- {
- /* XXX XXX XXX */
- delete_object(p_ptr->py, p_ptr->px);
-
- /* Make stairs */
- if (create_down_stair)
- {
- cave_set_feat(p_ptr->py, p_ptr->px, (dungeon_flags1 & DF1_FLAT) ? FEAT_WAY_MORE : FEAT_MORE);
- }
- else if (create_down_shaft)
- {
- cave_set_feat(p_ptr->py, p_ptr->px, (dungeon_flags1 & DF1_FLAT) ? FEAT_WAY_MORE : FEAT_SHAFT_DOWN);
- }
- else if (create_up_shaft)
- {
- cave_set_feat(p_ptr->py, p_ptr->px, (dungeon_flags1 & DF1_FLAT) ? FEAT_WAY_LESS : FEAT_SHAFT_UP);
- }
- else
- {
- cave_set_feat(p_ptr->py, p_ptr->px, (dungeon_flags1 & DF1_FLAT) ? FEAT_WAY_LESS : FEAT_LESS);
- }
- }
-
- /* Cancel the stair request */
- create_down_stair = create_up_stair = FALSE;
- create_down_shaft = create_up_shaft = FALSE;
- }
-
- /* Hack - Assume invalid panel */
- panel_row_min = cur_hgt;
- panel_row_max = 0;
- panel_col_min = cur_wid;
- panel_col_max = 0;
-
- /* Center the panel */
- verify_panel();
-
- /* Flush messages */
- msg_print(NULL);
-
-
- /* Enter "xtra" mode */
- character_xtra = TRUE;
-
- /* Window stuff */
- p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
-
- /* Window stuff */
- p_ptr->window |= (PW_MONSTER);
-
- /* Redraw dungeon */
- p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA);
-
- /* Redraw map */
- p_ptr->redraw |= (PR_MAP);
-
- /* Window stuff */
- p_ptr->window |= (PW_OVERHEAD);
-
- /* Update stuff */
- p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS | PU_POWERS | PU_SANITY | PU_BODY);
-
- /* Calculate torch radius */
- p_ptr->update |= (PU_TORCH);
-
- /* Update stuff */
- update_stuff();
-
- /* Redraw stuff */
- redraw_stuff();
-
- /* Redraw stuff */
- window_stuff();
-
- /* Update stuff */
- p_ptr->update |= (PU_VIEW | PU_FLOW | PU_DISTANCE | PU_MON_LITE);
-
- /* Update stuff */
- update_stuff();
-
- /* Redraw stuff */
- redraw_stuff();
-
- /* Leave "xtra" mode */
- character_xtra = FALSE;
-
- /* Update stuff */
- p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS | PU_POWERS | PU_BODY);
-
- /* Combine / Reorder the pack */
- p_ptr->notice |= (PN_COMBINE | PN_REORDER);
-
- /* Notice stuff */
- notice_stuff();
-
- /* Update stuff */
- update_stuff();
-
- /* Redraw stuff */
- redraw_stuff();
-
- /* Window stuff */
- window_stuff();
-
- /* Refresh */
- Term_fresh();
-
-
- /* Announce (or repeat) the feeling */
- if (dun_level) do_cmd_feeling();
-
-
- /* Hack -- notice death or departure */
- if (!alive || death) return;
-
- /*** Process this dungeon level ***/
-
- /* Reset the monster generation level */
- monster_level = dun_level;
-
- /* Reset the object generation level */
- object_level = dun_level;
-
- hack_mind = TRUE;
-
- /* Mega Hack, if needed wipe all stairs */
- if (dungeon_type == DUNGEON_DEATH)
- {
- int i, j;
-
- for (i = 0; i < cur_wid; i++)
- {
- for (j = 0; j < cur_hgt; j++)
- {
- cave_type *c_ptr = &cave[j][i];
-
- switch (c_ptr->feat)
- {
- case FEAT_MORE:
- case FEAT_LESS:
- case FEAT_SHAFT_UP:
- case FEAT_SHAFT_DOWN:
- {
- cave_set_feat(j, i, FEAT_FLOOR);
- break;
- }
- }
- }
- }
-
- /* Reset the monster generation level */
- monster_level = 127;
-
- /* Reset the object generation level */
- object_level = 0;
- }
-
- /* Main loop */
- while (TRUE)
- {
- /* Hack -- Compact the monster list occasionally */
- if (m_cnt + 32 > max_m_idx) compact_monsters(64);
-
- /* Hack -- Compress the monster list occasionally */
- if (m_cnt + 32 < m_max) compact_monsters(0);
-
-
- /* Hack -- Compact the object list occasionally */
- if (o_cnt + 32 > max_o_idx) compact_objects(64);
-
- /* Hack -- Compress the object list occasionally */
- if (o_cnt + 32 < o_max) compact_objects(0);
-
-
-
- /* Process the player */
- process_player();
-
- /* Notice stuff */
- if (p_ptr->notice) notice_stuff();
-
- /* Update stuff */
- if (p_ptr->update) update_stuff();
-
- /* Redraw stuff */
- if (p_ptr->redraw) redraw_stuff();
-
- /* Redraw stuff */
- if (p_ptr->window) window_stuff();
-
- /* Hack -- Hilite the player */
- move_cursor_relative(p_ptr->py, p_ptr->px);
-
- /* Optional fresh */
- if (fresh_after) Term_fresh();
-
- /* Hack -- Notice death or departure */
- if (!alive || death) break;
-
-
- total_friends = 0;
- total_friend_levels = 0;
-
- /* Process all of the monsters */
- process_monsters();
-
- /* Notice stuff */
- if (p_ptr->notice) notice_stuff();
-
- /* Update stuff */
- if (p_ptr->update) update_stuff();
-
- /* Redraw stuff */
- if (p_ptr->redraw) redraw_stuff();
-
- /* Redraw stuff */
- if (p_ptr->window) window_stuff();
-
- /* Hack -- Hilite the player */
- move_cursor_relative(p_ptr->py, p_ptr->px);
-
- /* Optional fresh */
- if (fresh_after) Term_fresh();
-
- /* Hack -- Notice death or departure */
- if (!alive || death) break;
-
-
- /* Process the world */
- process_world();
-
- /* Process the appropriate hooks */
- process_hooks(HOOK_END_TURN, "(d)", is_quest(dun_level));
-
- /* Make it pulsate and live !!!! */
- if ((dungeon_flags1 & DF1_EVOLVE) && dun_level)
- {
- if (!(turn % 10)) evolve_level(TRUE);
- }
-
- /* Notice stuff */
- if (p_ptr->notice) notice_stuff();
-
- /* Update stuff */
- if (p_ptr->update) update_stuff();
-
- /* Redraw stuff */
- if (p_ptr->redraw) redraw_stuff();
-
- /* Window stuff */
- if (p_ptr->window) window_stuff();
-
- /* Hack -- Hilite the player */
- move_cursor_relative(p_ptr->py, p_ptr->px);
-
- /* Optional fresh */
- if (fresh_after) Term_fresh();
-
- /* Hack -- Notice death or departure */
- if (!alive || death) break;
-
- /* Handle "leaving" */
- if (p_ptr->leaving) break;
-
- /* Count game turns */
- turn++;
- }
-
- /* Did we leave a dungeon ? */
- if ((dun_level < d_info[dungeon_type].mindepth) && !is_recall)
- {
- dun_level = 0;
-
- if (d_info[dungeon_type].ix > -1)
- {
- p_ptr->wilderness_x = d_info[dungeon_type].ix;
- p_ptr->wilderness_y = d_info[dungeon_type].iy;
- }
-
- dungeon_type = DUNGEON_WILDERNESS;
- }
-
- if (dun_level > d_info[dungeon_type].maxdepth)
- {
- dun_level = 0;
-
- if (d_info[dungeon_type].ox > -1)
- {
- p_ptr->wilderness_x = d_info[dungeon_type].ox;
- p_ptr->wilderness_y = d_info[dungeon_type].oy;
- }
-
- dungeon_type = DUNGEON_WILDERNESS;
- }
-
- is_recall = FALSE;
-}
-
-
-
-
-/*
- * Load some "user pref files"
- */
-static void load_all_pref_files(void)
-{
- char buf[1024];
-
-
- /* Access the "race" pref file */
- sprintf(buf, "%s.prf", rp_ptr->title + rp_name);
-
- /* Process that file */
- process_pref_file(buf);
-
- /* Access the "class" pref file */
- sprintf(buf, "%s.prf", spp_ptr->title + c_name);
-
- /* Process that file */
- process_pref_file(buf);
-
- /* Access the "character" pref file */
- sprintf(buf, "%s.prf", player_name);
-
- /* Process that file */
- process_pref_file(buf);
-
- /* Process player specific automatizer sets */
- tome_dofile_anywhere(ANGBAND_DIR_USER, format("%s.atm", player_name), FALSE);
-}
-
-/*
- * Actually play a game
- *
- * If the "new_game" parameter is true, then, after loading the
- * savefile, we will commit suicide, if necessary, to allow the
- * player to start a new game.
- */
-void play_game(bool_ new_game)
-{
- int i, tmp_dun;
-
- bool_ cheat_death = FALSE;
-
- hack_corruption = FALSE;
-
- /* Hack -- Character is "icky" */
- character_icky = TRUE;
-
-
- /* Make sure main term is active */
- Term_activate(angband_term[0]);
-
- /* Initialise the resize hook XXX XXX XXX */
- angband_term[0]->resize_hook = resize_map;
-
- /* XXX XXX XXX hardcoded number of terms */
- for (i = 1; i < 8; i++)
- {
- if (angband_term[i])
- {
- /* Add redraw hook */
- angband_term[i]->resize_hook = resize_window;
- }
- }
-
-
- /* Hack -- turn off the cursor */
- (void)Term_set_cursor(0);
-
- /* Character list */
- if (!new_game && !no_begin_screen) new_game = begin_screen();
- no_begin_screen = FALSE;
-
- /* Attempt to load */
- if (!load_player())
- {
- /* Oops */
- quit("broken savefile");
- }
-
- /* Nothing loaded */
- if (!character_loaded)
- {
- /* Make new player */
- new_game = TRUE;
-
- /* The dungeon is not ready */
- character_dungeon = FALSE;
- }
- else
- {
- int i;
-
- /* Init new skills to their defaults */
- for (i = old_max_s_idx; i < max_s_idx; i++)
- {
- s32b value = 0, mod = 0;
-
- compute_skills(&value, &mod, i);
-
- init_skill(value, mod, i);
- }
- }
-
-#if 1
-
- /* Process old character */
- if (!new_game)
- {
- /* Process the player name */
- process_player_name(FALSE);
- }
-
-#endif
-
- /* Init the RNG */
- if (Rand_quick)
- {
- u32b seed;
-
- /* Basic seed */
- seed = (time(NULL));
-
-#ifdef SET_UID
-
- /* Mutate the seed on Unix machines */
- seed = ((seed >> 3) * (getpid() << 1));
-
-#endif
-
- /* Use the complex RNG */
- Rand_quick = FALSE;
-
- /* Seed the "complex" RNG */
- Rand_state_init(seed);
- }
-
- /* Extract the options */
- for (i = 0; option_info[i].o_desc; i++)
- {
- int os = option_info[i].o_page;
- int ob = option_info[i].o_bit;
-
- /* Set the "default" options */
- if (option_info[i].o_var)
- {
- /* Set */
- if (option_flag[os] & (1L << ob))
- {
- /* Set */
- (*option_info[i].o_var) = TRUE;
- }
-
- /* Clear */
- else
- {
- /* Clear */
- (*option_info[i].o_var) = FALSE;
- }
- }
- }
-
- /* Roll new character */
- if (new_game)
- {
- s32b ret;
-
- /* Are we authorized to create new chars? */
- call_lua("get_module_info", "(s)", "d", "allow_birth", &ret);
-
- if (!ret)
- {
- msg_box("Sorry, this module does not allow character creation.", -1, -1);
-
- /* Close stuff */
- close_game();
-
- /* Quit */
- quit(NULL);
- }
-
- process_hooks(HOOK_INIT, "()");
-
- /* The dungeon is not ready */
- character_dungeon = FALSE;
-
- /* Hack -- seed for flavors */
- seed_flavor = rand_int(0x10000000);
-
- /* Roll up a new character */
- player_birth();
-
- /* Start in town, or not */
- if (p_ptr->astral) dun_level = 98;
- else dun_level = 0;
- p_ptr->inside_quest = 0;
- p_ptr->inside_arena = 0;
-
- /* Hack -- enter the world */
- /* Mega-hack Vampires and Spectres start in the dungeon */
- if (PRACE_FLAG(PR1_UNDEAD))
- {
- turn = (10L * DAY / 2) + (START_DAY * 10) + 1;
- }
- else
- {
- turn = (START_DAY * 10) + 1;
- }
- }
-
- /* Flash a message */
- prt("Please wait...", 0, 0);
-
- /* Flush the message */
- Term_fresh();
-
- /* Be sure to not bother the player */
- calc_powers_silent = TRUE;
-
- /* Hack -- Enter wizard mode */
- if (arg_wizard && enter_wizard_mode()) wizard = TRUE;
-
- /* Flavor the objects */
- flavor_init();
-
- /* Reset the visual mappings */
- reset_visuals();
-
- /* Window stuff */
- p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
-
- /* Window stuff */
- p_ptr->window |= (PW_MONSTER);
-
- /* Window stuff */
- window_stuff();
-
- /* load user file */
- process_pref_file("user.prf");
-
- /* Load the "pref" files */
- load_all_pref_files();
-
- /* Set or clear "rogue_like_commands" if requested */
- if (arg_force_original) rogue_like_commands = FALSE;
- if (arg_force_roguelike) rogue_like_commands = TRUE;
-
- /* Initialize vault info */
- if (init_v_info()) quit("Cannot initialize vaults");
-
- /* Initialize hooks */
- init_hooks();
- ingame_help(p_ptr->help.enabled);
-
- /* React to changes */
- Term_xtra(TERM_XTRA_REACT, 0);
-
- /* Mega hack, prevent lots of bugs */
- if ((p_ptr->px == 0) || (p_ptr->py == 0))
- {
- p_ptr->px = 1;
- p_ptr->py = 1;
- };
-
- /* Hack - if note file exists, load it */
- if (!new_game && take_notes)
- {
- add_note_type(NOTE_ENTER_DUNGEON);
- }
-
- /* Generate a dungeon level if needed */
- if (!character_dungeon) generate_cave();
-
- /* Ok tell the scripts that the game is about to start */
- process_hooks(HOOK_GAME_START, "()");
-
- /* Character is now "complete" */
- character_generated = TRUE;
-
-
- /* Hack -- Character is no longer "icky" */
- character_icky = FALSE;
-
-
- /* Start game */
- alive = TRUE;
-
- /* Hack -- Enforce "delayed death" */
- if (p_ptr->chp < 0) death = TRUE;
-
- /* Should we use old colors */
- if (autoload_old_colors)
- {
- process_pref_file("422color.prf");
- }
-
-
- /* Process */
- while (TRUE)
- {
- /* Save the level */
- old_dun_level = dun_level;
- p_ptr->old_wild_mode = p_ptr->wild_mode;
-
- /* We reached surface ? good, lets go down again !! */
- if (p_ptr->astral && !dun_level)
- {
- p_ptr->astral = FALSE;
- cmsg_print(TERM_L_GREEN,
- "Well done ! You reached the town ! "
- "You can now go down again.");
- }
-
- /* Update monster list window */
- p_ptr->window |= (PW_M_LIST);
-
- /* Process the level */
- dungeon();
-
- /* Save the current level if in a persistent level */
- tmp_dun = dun_level;
- dun_level = old_dun_level;
- save_dungeon();
- dun_level = tmp_dun;
-
- /* A death fate affects level generation */
- for (i = 0; i < MAX_FATES; i++)
- {
- /* Ignore empty slots */
- if (!fates[i].fate) continue;
-
- /* Ignore non-applicable fates */
- if (fates[i].level != dun_level) continue;
-
- /* Non-serious fate fails to fire 50% of time */
- if (!fates[i].serious && (rand_int(2) == 0)) continue;
-
- /* Analyse fate */
- switch (fates[i].fate)
- {
- /* You are doomed */
- case FATE_DIE:
- {
- cmsg_print(TERM_L_DARK, "You were fated to die here. DIE!");
-
- /* You shall perish there */
- dungeon_type = DUNGEON_DEATH;
- dun_level = d_info[dungeon_type].mindepth; /* was 1 */
-
- fates[i].fate = FATE_NONE;
- break;
- }
- }
- }
-
- /* Notice stuff */
- if (p_ptr->notice) notice_stuff();
-
- /* Update stuff */
- if (p_ptr->update) update_stuff();
-
- /* Redraw stuff */
- if (p_ptr->redraw) redraw_stuff();
-
- /* Window stuff */
- if (p_ptr->window) window_stuff();
-
- /* Cancel the target */
- target_who = 0;
-
- /* Cancel the health bar */
- health_track(0);
-
-
- /* Forget the lite */
- forget_mon_lite();
-
- /* Forget the view */
- forget_view();
-
- /* Handle "quit and save" */
- if (!alive && !death) break;
-
-
- /* Erase the old cave */
- wipe_o_list();
-
-
- /* XXX XXX XXX */
- msg_print(NULL);
-
- /* Accidental Death */
- if (alive && death)
- {
- cheat_death = FALSE;
-
- /* Can we die ? please let us die ! */
- if (process_hooks(HOOK_DIE, "()"))
- {
- cheat_death = TRUE;
- }
-
- /* Deus ex machina */
- else if (granted_resurrection())
- {
- cheat_death = TRUE;
- p_ptr->grace = -200000;
- cmsg_format(TERM_L_GREEN,
- "The power of %s raises you back from the grave!",
- deity_info[p_ptr->pgod].name);
- msg_print(NULL);
- }
-
- /* Blood of life */
- else if (p_ptr->allow_one_death > 0)
- {
- cheat_death = TRUE;
-
- /* Lose one extra life */
- p_ptr->allow_one_death--;
-
- cmsg_print(TERM_L_GREEN,
- "You have been saved by the Blood of Life!");
- msg_print(NULL);
- }
-
- /* Cheat death option */
- else if ((wizard || cheat_live) && !get_check("Die? "))
- {
- cheat_death = TRUE;
-
- /* Mark social class, reset age, if needed */
- if (p_ptr->sc) p_ptr->sc = p_ptr->age = 0;
-
- /* Increase age */
- p_ptr->age++;
-
- /* Mark savefile */
- noscore |= 0x0001;
- msg_print("You invoke wizard mode and cheat death.");
- msg_print(NULL);
- }
-
- if (cheat_death)
- {
- /* Restore the winner status */
- total_winner = has_won;
-
- /* One more life spent */
- p_ptr->lives++;
-
- /* Restore hit points */
- p_ptr->chp = p_ptr->mhp;
- p_ptr->chp_frac = 0;
-
- /* Heal sanity */
- p_ptr->csane = p_ptr->msane;
- p_ptr->csane_frac = 0;
-
- /* Restore spell points */
- p_ptr->csp = p_ptr->msp;
- p_ptr->csp_frac = 0;
-
- /* Hack -- Healing */
- (void)set_blind(0);
- (void)set_confused(0);
- (void)set_poisoned(0);
- (void)set_afraid(0);
- (void)set_paralyzed(0);
- (void)set_image(0);
- (void)set_stun(0);
- (void)set_cut(0);
-
- /* accounting for a new ailment. -LM- */
- p_ptr->black_breath = FALSE;
-
- /* Hack -- don't go to undead form */
- p_ptr->necro_extra &= ~CLASS_UNDEAD;
-
- /* Hack -- Prevent starvation */
- (void)set_food(PY_FOOD_MAX - 1);
-
- /* Hack -- cancel recall */
- if (p_ptr->word_recall)
- {
- /* Message */
- msg_print("A tension leaves the air around you...");
- msg_print(NULL);
-
- /* Hack -- Prevent recall */
- p_ptr->word_recall = 0;
- }
-
- /* Note cause of death XXX XXX XXX */
- (void)strcpy(died_from, "Cheating death");
-
- /* Do not die */
- death = FALSE;
-
- /* New depth -KMW- */
- /* dun_level = 0; */
- p_ptr->inside_arena = 0;
- leaving_quest = 0;
- p_ptr->inside_quest = 0;
-
- /* Leaving */
- p_ptr->leaving = TRUE;
- }
- }
-
- /* Handle "death" */
- if (death)
- {
- break;
- }
-
- /* Mega hack */
- if (dun_level) p_ptr->wild_mode = FALSE;
-
- /* Make a new level */
- process_hooks(HOOK_NEW_LEVEL, "(d)", is_quest(dun_level));
- generate_cave();
- }
-
- /* Close stuff */
- close_game();
-
- /* Quit */
- quit(NULL);
-}
-