diff options
author | Manoj Srivastava <srivasta@debian.org> | 2016-01-27 13:11:31 -0800 |
---|---|---|
committer | Manoj Srivastava <srivasta@debian.org> | 2016-01-27 13:11:31 -0800 |
commit | 02819db3483514d49df7ec3f7e372b5aeb831466 (patch) | |
tree | 6a86adac74beac293bc688dafcfa1709a6476901 /src/dungeon.c | |
parent | 2a61dffe127e22c1aaf955db6f085ac2eefbebba (diff) | |
parent | 6f6de67c70fd98815088ce49f046f48f88ea35bd (diff) |
Merge branch 'upstream'
Signed-off-by: Manoj Srivastava <srivasta@debian.org>
# Conflicts:
# src/CMakeLists.txt
# src/config.h
# src/lua/llimits.h
Diffstat (limited to 'src/dungeon.c')
-rw-r--r-- | src/dungeon.c | 5664 |
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); -} - |