summaryrefslogtreecommitdiffstats
path: root/stone_soup/crawl-ref/source/acr.cc
diff options
context:
space:
mode:
Diffstat (limited to 'stone_soup/crawl-ref/source/acr.cc')
-rw-r--r--stone_soup/crawl-ref/source/acr.cc3201
1 files changed, 0 insertions, 3201 deletions
diff --git a/stone_soup/crawl-ref/source/acr.cc b/stone_soup/crawl-ref/source/acr.cc
deleted file mode 100644
index 95618e83c0..0000000000
--- a/stone_soup/crawl-ref/source/acr.cc
+++ /dev/null
@@ -1,3201 +0,0 @@
-/*
- * File: acr.cc
- * Summary: Main entry point, event loop, and some initialization functions
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <18> 7/29/00 JDJ values.h isn't included on Macs
- * <17> 19jun2000 GDL added Windows console support
- * <16> 06mar2000 bwr changes to berserk
- * <15> 09jan2000 BCR new Wiz command: blink
- * <14> 10/13/99 BCR Added auto door opening,
- * move "you have no
- * religion" to describe.cc
- * <13> 10/11/99 BCR Added Daniel's wizard patch
- * <12> 10/9/99 BCR swapped 'v' and 'V' commands,
- * added wizard help command
- * <11> 10/7/99 BCR haste and slow now take amulet of
- * resist slow into account
- * <10> 9/25/99 CDL Changes to Linux input
- * switch on command enums
- * <9> 6/12/99 BWR New init code, restructured
- * wiz commands, added equipment
- * listing commands
- * <8> 6/7/99 DML Autopickup
- * <7> 5/30/99 JDJ Added game_has_started.
- * <6> 5/25/99 BWR Changed move() to move_player()
- * <5> 5/20/99 BWR New berserk code, checking
- * scan_randarts for NO_TELEPORT
- * and NO_SPELLCASTING.
- * <4> 5/12/99 BWR Solaris support.
- * <3> 5/09/99 JDJ look_around no longer prints a prompt.
- * <2> 5/08/99 JDJ you and env are no longer arrays.
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-
-#include <string>
-
-// I don't seem to need values.h for VACPP..
-#if !defined(__IBMCPP__) && !defined(MAC)
-#include <limits.h>
-#endif
-
-#if DEBUG
- // this contains the DBL_MAX constant
- #include <float.h>
-#endif
-
-#include <time.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-#ifdef DOS
-#include <dos.h>
-#include <conio.h>
-#include <file.h>
-#endif
-
-#ifdef USE_UNIX_SIGNALS
-#include <signal.h>
-#endif
-
-#ifdef USE_EMX
-#include <sys/types.h>
-#endif
-
-#ifdef OS9
-#include <stat.h>
-#else
-#include <sys/stat.h>
-#endif
-
-#include "externs.h"
-
-#include "abl-show.h"
-#include "abyss.h"
-#include "chardump.h"
-#include "clua.h"
-#include "command.h"
-#include "debug.h"
-#include "delay.h"
-#include "describe.h"
-#include "direct.h"
-#include "dungeon.h"
-#include "effects.h"
-#include "fight.h"
-#include "files.h"
-#include "food.h"
-#include "hiscores.h"
-#include "initfile.h"
-#include "invent.h"
-#include "item_use.h"
-#include "it_use2.h"
-#include "it_use3.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "items.h"
-#include "lev-pand.h"
-#include "macro.h"
-#include "misc.h"
-#include "monplace.h"
-#include "monstuff.h"
-#include "mon-util.h"
-#include "mutation.h"
-#include "newgame.h"
-#include "ouch.h"
-#include "output.h"
-#include "overmap.h"
-#include "player.h"
-#include "randart.h"
-#include "religion.h"
-#include "shopping.h"
-#include "skills.h"
-#include "skills2.h"
-#include "spells1.h"
-#include "spells3.h"
-#include "spells4.h"
-#include "spl-book.h"
-#include "spl-cast.h"
-#include "spl-util.h"
-#include "stuff.h"
-#include "tags.h"
-#include "transfor.h"
-#include "travel.h"
-#include "view.h"
-#include "wpn-misc.h"
-#include "stash.h"
-
-struct crawl_environment env;
-struct player you;
-struct system_environment SysEnv;
-
-char info[ INFO_SIZE ]; // messaging queue extern'd everywhere {dlb}
-
-int stealth; // externed in view.h // no it is not {dlb}
-char use_colour = 1;
-
-FixedVector< char, NUM_STATUE_TYPES > Visible_Statue;
-
-// set to true once a new game starts or an old game loads
-bool game_has_started = false;
-
-// Clockwise, around the compass from north (same order as enum RUN_DIR)
-static const struct coord_def Compass[8] =
-{
- { 0, -1 }, { 1, -1 }, { 1, 0 }, { 1, 1 },
- { 0, 1 }, { -1, 1 }, { -1, 0 }, { -1, -1 },
-};
-
-/*
-
- Functions needed:
- New:
- int player_speed(player you);
- hit_player(damage, flavour, then last two ouch values, env);
-
-
- Old:
- wield(player you);
- show_map
- noisy()
- losight
-
-*/
-
-void (*viewwindow) (char, bool);
-
-/*
- Function pointers are used to make switching between Unix and DOS char sets
- possible as a runtime option (command-line -c)
-*/
-
-// these two are defined in view.cc. What does the player look like?
-// (changed for shapechanging)
-extern unsigned char your_sign;
-extern unsigned char your_colour;
-
-// Functions in main module
-static void close_door(char move_x, char move_y);
-static void do_berserk_no_combat_penalty(void);
-static bool initialise(void);
-static void input(void);
-static void move_player(char move_x, char move_y);
-static void open_door(char move_x, char move_y);
-
-/*
- It all starts here. Some initialisations are run first, then straight to
- new_game and then input.
-*/
-int main( int argc, char *argv[] )
-{
-#ifdef USE_ASCII_CHARACTERS
- apply_ascii_display(true);
-#else
- apply_ascii_display(false);
-#endif
-
- // Load in the system environment variables
- get_system_environment();
-
- // parse command line args -- look only for initfile & crawl_dir entries
- if (!parse_args(argc, argv, true))
- {
- // print help
- puts("Command line options:");
- puts(" -name <string> character name");
- puts(" -race <arg> preselect race (by letter, abbreviation, or name)");
- puts(" -class <arg> preselect class (by letter, abbreviation, or name)");
- puts(" -pizza <string> crawl pizza");
- puts(" -plain don't use IBM extended characters");
- puts(" -dir <path> crawl directory");
- puts(" -rc <file> init file name");
- puts("");
- puts("Command line options override init file options, which override");
- puts("environment options (CRAWL_NAME, CRAWL_PIZZA, CRAWL_DIR, CRAWL_RC).");
- puts("");
- puts("Highscore list options: (Can now be redirected to more, etc)");
- puts(" -scores [N] highscore list");
- puts(" -tscores [N] terse highscore list");
- puts(" -vscores [N] verbose highscore list");
- exit(1);
- }
-
- // Read the init file
- read_init_file();
-
- // now parse the args again, looking for everything else.
- parse_args( argc, argv, false );
-
- if (Options.sc_entries > 0)
- {
- printf( " Best Crawlers -" EOL );
- hiscores_print_list( Options.sc_entries, Options.sc_format );
- exit(0);
- }
-
-#ifdef UNIX
- unixcurses_startup();
-#endif
-
-#ifdef MAC
- init_mac();
-#endif
-
-#ifdef WIN32CONSOLE
- init_libw32c();
-#endif
-
-#ifdef USE_MACROS
- // Load macros
- macro_init();
-#endif
-
- init_overmap(); // in overmap.cc (duh?)
- clear_ids(); // in itemname.cc
-
- bool game_start = initialise();
-
- if (game_start || Options.always_greet)
- {
- snprintf( info, INFO_SIZE, "Welcome, %s the %s %s.",
- you.your_name, species_name( you.species,you.experience_level ), you.class_name );
-
- mpr( info );
-
- // Starting messages can go here as this should only happen
- // at the start of a new game -- bwr
- // This message isn't appropriate for Options.always_greet
- if (you.char_class == JOB_WANDERER && game_start)
- {
- int skill_levels = 0;
- for (int i = 0; i <= NUM_SKILLS; i++)
- skill_levels += you.skills[ i ];
-
- if (skill_levels <= 2)
- {
- // Demigods and Demonspawn wanderers stand to not be
- // able to see any of their skills at the start of
- // the game (one or two skills should be easily guessed
- // from starting equipment)... Anyways, we'll give the
- // player a message to warn them (and give a reason why). -- bwr
- mpr("You wake up in a daze, and can't recall much.");
- }
- }
-
- // These need some work -- should make sure that the god's
- // name is metioned, else the message might be confusing.
- switch (you.religion)
- {
- case GOD_ZIN:
- simple_god_message( " says: Spread the light, my child." );
- break;
- case GOD_SHINING_ONE:
- simple_god_message( " says: Smite the infidels!" );
- break;
- case GOD_KIKUBAAQUDGHA:
- case GOD_YREDELEMNUL:
- case GOD_NEMELEX_XOBEH:
- simple_god_message( " says: Welcome..." );
- break;
- case GOD_XOM:
- if (game_start)
- simple_god_message( " says: A new plaything!" );
- break;
- case GOD_VEHUMET:
- god_speaks( you.religion, "Let it end in hellfire!");
- break;
- case GOD_OKAWARU:
- simple_god_message(" says: Welcome, disciple.");
- break;
- case GOD_MAKHLEB:
- god_speaks( you.religion, "Blood and souls for Makhleb!" );
- break;
- case GOD_SIF_MUNA:
- simple_god_message( " whispers: I know many secrets...");
- break;
- case GOD_TROG:
- simple_god_message( " says: Kill them all!" );
- break;
- case GOD_ELYVILON:
- simple_god_message( " says: Go forth and aid the weak!" );
- break;
- default:
- break;
- }
-
- // warn player about their weapon, if unsuitable
- wield_warning(false);
- }
-
- while (true)
- {
- input();
- // cprintf("x");
- }
-
- // Should never reach this stage, right?
-
-#ifdef UNIX
- unixcurses_shutdown();
-#endif
-
-#ifdef MAC
- deinit_mac();
-#endif
-
-#ifdef USE_EMX
- deinit_emx();
-#endif
-
- return 0;
-} // end main()
-
-#ifdef WIZARD
-static void handle_wizard_command( void )
-{
- int wiz_command, i, j, tmp;
- char specs[256];
-
- // WIZ_NEVER gives protection for those who have wiz compiles,
- // and don't want to risk their characters.
- if (Options.wiz_mode == WIZ_NEVER)
- return;
-
- if (!you.wizard)
- {
- mpr( "WARNING: ABOUT TO ENTER WIZARD MODE!", MSGCH_WARN );
-
-#ifndef SCORE_WIZARD_MODE
- mpr( "If you continue, your game will not be scored!", MSGCH_WARN );
-#endif
-
- if (!yesno( "Do you really want to enter wizard mode?",
- false, 'n' ))
- return;
-
- you.wizard = true;
- redraw_screen();
- }
-
- mpr( "Enter Wizard Command: ", MSGCH_PROMPT );
- wiz_command = getch();
-
- switch (wiz_command)
- {
- case '?':
- list_commands(true); // tell it to list wizard commands
- redraw_screen();
- break;
-
- case CONTROL('G'):
- save_ghost(true);
- break;
-
- case 'x':
- you.experience = 1 + exp_needed( 2 + you.experience_level );
- level_change();
- break;
-
- case 's':
- you.exp_available = 20000;
- you.redraw_experience = 1;
- break;
-
- case 'S':
- debug_set_skills();
- break;
-
- case 'A':
- debug_set_all_skills();
- break;
-
- case '$':
- you.gold += 1000;
- you.redraw_gold = 1;
- break;
-
- case 'a':
- acquirement( OBJ_RANDOM, AQ_WIZMODE );
- break;
-
- case 'v':
- // this command isn't very exciting... feel free to replace
- i = prompt_invent_item( "Value of which item?", -1 );
- if (i == PROMPT_ABORT || !is_random_artefact( you.inv[i] ))
- {
- canned_msg( MSG_OK );
- break;
- }
- else
- {
- snprintf( info, INFO_SIZE, "randart val: %d", randart_value( you.inv[i] ) );
- mpr( info );
- }
- break;
-
- case '+':
- i = prompt_invent_item( "Make an artefact out of which item?", -1 );
- if (i == PROMPT_ABORT)
- {
- canned_msg( MSG_OK );
- break;
- }
-
- // set j == equipment slot of chosen item, remove old randart benefits
- for (j = 0; j < NUM_EQUIP; j++)
- {
- if (you.equip[j] == i)
- {
- if (j == EQ_WEAPON)
- you.wield_change = true;
-
- if (is_random_artefact( you.inv[i] ))
- unuse_randart( i );
-
- break;
- }
- }
-
- make_item_randart( you.inv[i] );
-
- // if equiped, apply new randart benefits
- if (j != NUM_EQUIP)
- use_randart( i );
-
- item_name( you.inv[i], DESC_INVENTORY_EQUIP, info );
- mpr( info );
- break;
-
- case '|':
- // create all unrand arts
- for (tmp = 1; tmp < NO_UNRANDARTS; tmp++)
- {
- int islot = get_item_slot();
- if (islot == NON_ITEM)
- break;
-
- make_item_unrandart( mitm[islot], tmp );
-
- mitm[ islot ].quantity = 1;
- set_ident_flags( mitm[ islot ], ISFLAG_IDENT_MASK );
-
- move_item_to_grid( &islot, you.x_pos, you.y_pos );
- }
-
- // create all fixed artefacts
- for (tmp = SPWPN_SINGING_SWORD; tmp <= SPWPN_STAFF_OF_WUCAD_MU; tmp++)
- {
- int islot = get_item_slot();
- if (islot == NON_ITEM)
- break;
-
- if (make_item_fixed_artefact( mitm[ islot ], false, tmp ))
- {
- mitm[ islot ].quantity = 1;
- item_colour( mitm[ islot ] );
- set_ident_flags( mitm[ islot ], ISFLAG_IDENT_MASK );
-
- move_item_to_grid( &islot, you.x_pos, you.y_pos );
- }
- }
- break;
-
- case 'B':
- if (you.level_type != LEVEL_ABYSS)
- banished( DNGN_ENTER_ABYSS );
- else
- {
- grd[you.x_pos][you.y_pos] = DNGN_EXIT_ABYSS;
- down_stairs(true, you.your_level, true);
- untag_followers();
- }
- break;
-
- case 'g':
- debug_add_skills();
- break;
-
- case 'G':
- // Genocide... "unsummon" all the monsters from the level.
- for (int mon = 0; mon < MAX_MONSTERS; mon++)
- {
- struct monsters *monster = &menv[mon];
-
- if (monster->type == -1)
- continue;
-
- monster_die(monster, KILL_RESET, 0);
-
- }
- break;
-
- case 'h':
- you.rotting = 0;
- you.poison = 0;
- you.disease = 0;
- set_hp( abs(you.hp_max), false );
- set_hunger( 5000 + abs(you.hunger), true );
- break;
-
- case 'H':
- you.rotting = 0;
- you.poison = 0;
- you.disease = 0;
- inc_hp( 10, true );
- set_hp( you.hp_max, false );
- set_hunger( 12000, true );
- you.redraw_hit_points = 1;
- break;
-
- case 'b':
- blink(); // wizards can always blink
- break;
-
- case '\"':
- case '~':
- level_travel(0);
- break;
-
- case 'd':
- case 'D':
- level_travel(1);
- break;
-
- case 'u':
- case 'U':
- level_travel(-1);
- break;
-
- case '%':
- case 'o':
- create_spec_object();
- break;
-
- case 't':
- tweak_object();
- break;
-
- case 'f':
- debug_fight_statistics(false);
- break;
-
- case 'F':
- debug_fight_statistics(true);
- break;
-
- case 'm':
- create_spec_monster();
- break;
-
- case 'M':
- create_spec_monster_name();
- break;
-
- case 'r':
- debug_change_species();
- break;
-
- case '>':
- grd[you.x_pos][you.y_pos] = DNGN_STONE_STAIRS_DOWN_I;
- break;
-
- case '<':
- grd[you.x_pos][you.y_pos] = DNGN_ROCK_STAIRS_UP;
- break;
-
- case 'p':
- grd[you.x_pos][you.y_pos] = DNGN_ENTER_PANDEMONIUM;
- break;
-
- case 'l':
- grd[you.x_pos][you.y_pos] = DNGN_ENTER_LABYRINTH;
- break;
-
- case 'i':
- mpr( "You feel a rush of knowledge." );
- for (i = 0; i < ENDOFPACK; i++)
- {
- if (is_valid_item( you.inv[i] ))
- {
- set_ident_type( you.inv[i].base_type, you.inv[i].sub_type,
- ID_KNOWN_TYPE );
-
- set_ident_flags( you.inv[i], ISFLAG_IDENT_MASK );
- }
- }
- you.wield_change = true;
- break;
-
- case 'I':
- mpr( "You feel a rush of antiknowledge." );
- for (i = 0; i < ENDOFPACK; i++)
- {
- if (is_valid_item( you.inv[i] ))
- {
- set_ident_type( you.inv[i].base_type, you.inv[i].sub_type,
- ID_UNKNOWN_TYPE );
-
- unset_ident_flags( you.inv[i], ISFLAG_IDENT_MASK );
- }
- }
- you.wield_change = true;
- break;
-
- case 'X':
- Xom_acts(true, 20, true);
- break;
-
- case 'z':
- cast_spec_spell();
- break; /* cast spell by number */
-
- case 'Z':
- cast_spec_spell_name();
- break; /* cast spell by name */
-
- case '(':
- mpr( "Create which feature (by number)? ", MSGCH_PROMPT );
- get_input_line( specs, sizeof( specs ) );
-
- if (specs[0] != '\0')
- grd[you.x_pos][you.y_pos] = atoi(specs);
- break;
-
- case ']':
- if (!debug_add_mutation())
- mpr( "Failure to give mutation." );
- break;
-
- case '[':
- demonspawn();
- break;
-
- case ':':
- j = 0;
- for (i = 0; i < 20; i++)
- {
- if (you.branch_stairs[i] == 0)
- continue;
-
- snprintf( info, INFO_SIZE, "Branch %2d is on level %2d",
- i, you.branch_stairs[i] + 1 );
-
- mpr(info);
- }
- break;
-
- case '{':
- magic_mapping(99, 100);
- break;
-
- case '^':
- {
- int old_piety = you.piety;
-
- gain_piety(50);
- snprintf( info, INFO_SIZE, "Congratulations, your piety went from %d to %d!",
- old_piety, you.piety);
- mpr(info);
- }
- break;
-
- case '=':
- snprintf( info, INFO_SIZE,
- "Cost level: %d Skill points: %d Next cost level: %d",
- you.skill_cost_level, you.total_skill_points,
- skill_cost_needed( you.skill_cost_level + 1 ) );
-
- mpr( info );
- break;
-
- case '_':
- debug_get_religion();
- break;
-
- case '\'':
- for (i = 0; i < MAX_ITEMS; i++)
- {
- if (mitm[i].link == NON_ITEM)
- continue;
-
- snprintf( info, INFO_SIZE, "item:%3d link:%3d cl:%3d ty:%3d pl:%3d pl2:%3d sp:%3ld q:%3d",
- i, mitm[i].link,
- mitm[i].base_type, mitm[i].sub_type,
- mitm[i].plus, mitm[i].plus2, mitm[i].special,
- mitm[i].quantity );
-
- mpr(info);
- }
-
- strcpy(info, "igrid:");
- mpr(info);
-
- for (i = 0; i < GXM; i++)
- {
- for (j = 0; j < GYM; j++)
- {
- if (igrd[i][j] != NON_ITEM)
- {
- snprintf( info, INFO_SIZE, "%3d at (%2d,%2d), cl:%3d ty:%3d pl:%3d pl2:%3d sp:%3ld q:%3d",
- igrd[i][j], i, j,
- mitm[i].base_type, mitm[i].sub_type,
- mitm[i].plus, mitm[i].plus2, mitm[i].special,
- mitm[i].quantity );
-
- mpr(info);
- }
- }
- }
- break;
-
- default:
- mpr("Not a Wizard Command.");
- break;
- }
-}
-#endif
-
-// This function creates "equivalence classes" so that undiscovered
-// traps and secret doors aren't running stopping points.
-static char base_grid_type( char grid )
-{
- // Don't stop for undiscovered traps:
- if (grid == DNGN_UNDISCOVERED_TRAP)
- return (DNGN_FLOOR);
-
- // Or secret doors (which currently always look like rock walls):
- if (grid == DNGN_SECRET_DOOR)
- return (DNGN_ROCK_WALL);
-
- return (grid);
-}
-
-// Set up the front facing array for detecting terrain based stops
-static void set_run_check( int index, int dir )
-{
- you.run_check[index].dx = Compass[dir].x;
- you.run_check[index].dy = Compass[dir].y;
-
- const int targ_x = you.x_pos + Compass[dir].x;
- const int targ_y = you.y_pos + Compass[dir].y;
-
- you.run_check[index].grid = base_grid_type( grd[ targ_x ][ targ_y ] );
-}
-
-// Set up the running variables for the current run.
-static void start_running( int dir, char mode )
-{
- if (dir == RDIR_REST)
- {
- you.run_x = 0;
- you.run_y = 0;
- you.running = mode;
- return;
- }
-
- ASSERT( dir >= 0 && dir <= 7 );
-
- you.run_x = Compass[dir].x;
- you.run_y = Compass[dir].y;
- you.running = mode;
-
- // Get the compass point to the left/right of intended travel:
- const int left = (dir - 1 < 0) ? 7 : (dir - 1);
- const int right = (dir + 1 > 7) ? 0 : (dir + 1);
-
- // Record the direction and starting tile type for later reference:
- set_run_check( 0, left );
- set_run_check( 1, dir );
- set_run_check( 2, right );
-}
-
-// Returns true if one of the front three grids has changed.
-static bool check_stop_running( void )
-{
- if (env.cgrid[you.x_pos + you.run_x][you.y_pos + you.run_y] != EMPTY_CLOUD)
- return (true);
-
- if (mgrd[you.x_pos + you.run_x][you.y_pos + you.run_y] != NON_MONSTER)
- return (true);
-
- for (int i = 0; i < 3; i++)
- {
- const int targ_x = you.x_pos + you.run_check[i].dx;
- const int targ_y = you.y_pos + you.run_check[i].dy;
- const int targ_grid = base_grid_type( grd[ targ_x ][ targ_y ] );
-
- if (you.run_check[i].grid != targ_grid)
- return (true);
- }
-
- return (false);
-}
-
-static bool recharge_rod( item_def &rod, bool wielded )
-{
- if (!item_is_rod(rod) || rod.plus >= rod.plus2 || !enough_mp(1, true))
- return (false);
-
- const int charge = rod.plus / ROD_CHARGE_MULT;
-
- int rate = ((charge + 1) * ROD_CHARGE_MULT) / 10;
-
- rate *= (10 + skill_bump( SK_EVOCATIONS ));
- rate = div_rand_round( rate, 100 );
-
- if (rate < 5)
- rate = 5;
- else if (rate > ROD_CHARGE_MULT / 2)
- rate = ROD_CHARGE_MULT / 2;
-
- // If not wielded, the rod charges far more slowly.
- if (!wielded)
- rate /= 3;
-
- if (rod.plus / ROD_CHARGE_MULT != (rod.plus + rate) / ROD_CHARGE_MULT)
- {
- dec_mp(1);
- if (wielded)
- you.wield_change = true;
- }
-
- rod.plus += rate;
- if (rod.plus > rod.plus2)
- rod.plus = rod.plus2;
-
- if (wielded && rod.plus == rod.plus2 && is_resting())
- stop_running();
-
- return (true);
-}
-
-static void recharge_rods()
-{
- const int wielded = you.equip[EQ_WEAPON];
- if (wielded != -1)
- {
- if (recharge_rod( you.inv[wielded], true ))
- return ;
- }
-
- for (int i = 0; i < ENDOFPACK; ++i)
- {
- if (i != wielded && is_valid_item(you.inv[i])
- && one_chance_in(3)
- && recharge_rod( you.inv[i], false ))
- return;
- }
-}
-
-/*
- This function handles the player's input. It's called from main(), from
- inside an endless loop.
- */
-static void input(void)
-{
-
- bool its_quiet; //jmf: for silence messages
- FixedVector < int, 2 > plox;
- char move_x = 0;
- char move_y = 0;
-
- int keyin = 0;
-
-#ifdef UNIX
- // Stuff for the Unix keypad kludge
- bool running = false;
- bool opening = false;
-#endif
-
- you.shield_blocks = 0; // no blocks this round
-
- you.time_taken = player_speed();
-
-#ifdef UNIX
- update_screen();
-#else
- window( 1, 1, 80, get_number_of_lines() );
-#endif
-
- textcolor(LIGHTGREY);
-
- set_redraw_status( REDRAW_LINE_2_MASK | REDRAW_LINE_3_MASK );
- print_stats();
-
- if (you.paralysis)
- {
- keyin = '.'; // end of if you.paralysis == 0
- }
- else
- {
-#ifdef STASH_TRACKING
- if (Options.stash_tracking)
- stashes.update_visible_stashes(
- Options.stash_tracking == STM_ALL?
- StashTracker::ST_AGGRESSIVE :
- StashTracker::ST_PASSIVE);
-#endif
- handle_delay();
-
- gotoxy(18, 9);
-
- if (you_are_delayed())
- keyin = '.';
- else if (you.activity)
- {
- keyin = 128;
- you.turn_is_over = 0;
- perform_activity();
- }
- else
- {
- if (you.running < 0) // Travel and explore
- travel(&keyin, &move_x, &move_y);
-
- if (you.running > 0)
- {
- keyin = 128;
-
- move_x = you.run_x;
- move_y = you.run_y;
-
- if (kbhit())
- {
- stop_running();
- goto gutch;
- }
-
- if (you.run_x == 0 && you.run_y == 0)
- {
- you.running--;
- keyin = '.';
- }
- }
- else if (!you.running)
- {
-
-#if DEBUG_DIAGNOSTICS
- // save hunger at start of round
- // for use with hunger "delta-meter" in output.cc
- you.old_hunger = you.hunger;
-#endif
-
-#if DEBUG_ITEM_SCAN
- debug_item_scan();
-#endif
-
- gutch:
- flush_input_buffer( FLUSH_BEFORE_COMMAND );
- keyin = getch_with_command_macros();
- }
-
- mesclr();
-
-#ifdef UNIX
- // Kludging running and opening as two character sequences
- // for Unix systems. This is an easy way out... all the
- // player has to do is find a termcap and numlock setting
- // that will get curses the numbers from the keypad. This
- // will hopefully be easy.
-
- if (keyin == '*')
- {
- opening = true;
- keyin = getch();
- }
- else if (keyin == '/')
- {
- running = true;
- keyin = getch();
- }
-
- // Translate keypad codes into command enums
- keyin = key_to_command(keyin);
-#else
- // Old DOS keypad support
- if (keyin == 0) // ALT also works - see ..\KEYTEST.CPP
- {
- keyin = getch();
- switch (keyin)
- {
- case 'O': move_x = -1; move_y = 1; break;
- case 'P': move_x = 0; move_y = 1; break;
- case 'I': move_x = 1; move_y = -1; break;
- case 'H': move_x = 0; move_y = -1; break;
- case 'G': move_x = -1; move_y = -1; break;
- case 'K': move_x = -1; move_y = 0; break;
- case 'Q': move_x = 1; move_y = 1; break;
- case 'M': move_x = 1; move_y = 0; break;
-
- case 119: open_door(-1, -1); move_x = 0; move_y = 0; break;
- case 141: open_door( 0, -1); move_x = 0; move_y = 0; break;
- case 132: open_door( 1, -1); move_x = 0; move_y = 0; break;
- case 116: open_door( 1, 0); move_x = 0; move_y = 0; break;
- case 118: open_door( 1, 1); move_x = 0; move_y = 0; break;
- case 145: open_door( 0, 1); move_x = 0; move_y = 0; break;
- case 117: open_door(-1, 1); move_x = 0; move_y = 0; break;
- case 115: open_door(-1, 0); move_x = 0; move_y = 0; break;
-
- case 76:
- case 'S':
- keyin = '.';
- goto get_keyin_again;
- }
-
- keyin = 128;
- }
-#endif
- }
- }
-
- if (keyin != 128)
- {
- move_x = 0;
- move_y = 0;
- you.turn_is_over = 0;
- }
-
-#ifndef UNIX
- get_keyin_again:
-#endif //jmf: just stops an annoying gcc warning
-
- if (is_userfunction(keyin))
- {
- run_macro(get_userfunction(keyin));
- keyin = 128;
- }
-
- switch (keyin)
- {
- case CONTROL('Y'):
- case CMD_OPEN_DOOR_UP_RIGHT:
- open_door(-1, -1); move_x = 0; move_y = 0; break;
-
- case CONTROL('K'):
- case CMD_OPEN_DOOR_UP:
- open_door( 0, -1); move_x = 0; move_y = 0; break;
-
- case CONTROL('U'):
- case CMD_OPEN_DOOR_UP_LEFT:
- open_door( 1, -1); move_x = 0; move_y = 0; break;
-
- case CONTROL('L'):
- case CMD_OPEN_DOOR_RIGHT:
- open_door( 1, 0); move_x = 0; move_y = 0; break;
-
- case CONTROL('N'):
- case CMD_OPEN_DOOR_DOWN_RIGHT:
- open_door( 1, 1); move_x = 0; move_y = 0; break;
-
- case CONTROL('J'):
- case CMD_OPEN_DOOR_DOWN:
- open_door( 0, 1); move_x = 0; move_y = 0; break;
-
- case CONTROL('B'):
- case CMD_OPEN_DOOR_DOWN_LEFT:
- open_door(-1, 1); move_x = 0; move_y = 0; break;
-
- case CONTROL('H'):
- case CMD_OPEN_DOOR_LEFT:
- open_door(-1, 0); move_x = 0; move_y = 0; break;
-
- case 'b': case CMD_MOVE_DOWN_LEFT: move_x = -1; move_y = 1; break;
- case 'j': case CMD_MOVE_DOWN: move_y = 1; move_x = 0; break;
- case 'u': case CMD_MOVE_UP_RIGHT: move_x = 1; move_y = -1; break;
- case 'k': case CMD_MOVE_UP: move_y = -1; move_x = 0; break;
- case 'y': case CMD_MOVE_UP_LEFT: move_y = -1; move_x = -1; break;
- case 'h': case CMD_MOVE_LEFT: move_x = -1; move_y = 0; break;
- case 'n': case CMD_MOVE_DOWN_RIGHT: move_y = 1; move_x = 1; break;
- case 'l': case CMD_MOVE_RIGHT: move_x = 1; move_y = 0; break;
-
- case CMD_REST:
- // Yes this is backwards, but everyone here is used to using
- // straight 5s for long rests... might need to define a roguelike
- // rest key and get people switched over. -- bwr
-
-#ifdef UNIX
- if (!running && !opening)
- start_running( RDIR_REST, 100 );
- else
- {
- search_around();
- move_x = 0;
- move_y = 0;
- you.turn_is_over = 1;
- }
-#endif
- break;
-
- case 'B': case CMD_RUN_DOWN_LEFT:
- start_running( RDIR_DOWN_LEFT, 2 ); break;
-
- case 'J': case CMD_RUN_DOWN:
- start_running( RDIR_DOWN, 2 ); break;
-
- case 'U': case CMD_RUN_UP_RIGHT:
- start_running( RDIR_UP_RIGHT, 2 ); break;
-
- case 'K': case CMD_RUN_UP:
- start_running( RDIR_UP, 2 ); break;
-
- case 'Y': case CMD_RUN_UP_LEFT:
- start_running( RDIR_UP_LEFT, 2 ); break;
-
- case 'H': case CMD_RUN_LEFT:
- start_running( RDIR_LEFT, 2 ); break;
-
- case 'N': case CMD_RUN_DOWN_RIGHT:
- start_running( RDIR_DOWN_RIGHT, 2 ); break;
-
- case 'L': case CMD_RUN_RIGHT:
- start_running( RDIR_RIGHT, 2 ); break;
-
-#ifdef UNIX
- // taken care of via key -> command mapping
-#else
- // Old DOS keypad support
- case '1': start_running( RDIR_DOWN_LEFT, 2 ); break;
- case '2': start_running( RDIR_DOWN, 2 ); break;
- case '9': start_running( RDIR_UP_RIGHT, 2 ); break;
- case '8': start_running( RDIR_UP, 2 ); break;
- case '7': start_running( RDIR_UP_LEFT, 2 ); break;
- case '4': start_running( RDIR_LEFT, 2 ); break;
- case '3': start_running( RDIR_DOWN_RIGHT, 2 ); break;
- case '6': start_running( RDIR_RIGHT, 2 ); break;
- case '5': start_running( RDIR_REST, 100 ); break;
-
-#endif
-
- case CONTROL('A'):
- case CMD_TOGGLE_AUTOPICKUP:
- autopickup_on = !autopickup_on;
- strcpy(info, "Autopickup is now ");
- strcat(info, (autopickup_on) ? "on" : "off");
- strcat(info, ".");
- mpr(info);
- break;
-
- case CONTROL('C'):
- case CMD_CLEAR_MAP:
- if (you.level_type != LEVEL_LABYRINTH && you.level_type != LEVEL_ABYSS)
- {
- mpr("Clearing level map.");
- clear_map();
- }
- break;
-
- case '<':
- case CMD_GO_UPSTAIRS:
- if (grd[you.x_pos][you.y_pos] == DNGN_ENTER_SHOP)
- {
- shop();
- break;
- }
- else if ((grd[you.x_pos][you.y_pos] < DNGN_STONE_STAIRS_UP_I
- || grd[you.x_pos][you.y_pos] > DNGN_ROCK_STAIRS_UP)
- && (grd[you.x_pos][you.y_pos] < DNGN_RETURN_FROM_ORCISH_MINES
- || grd[you.x_pos][you.y_pos] >= 150))
- {
- mpr( "You can't go up here!" );
- break;
- }
-
- tag_followers(); // only those beside us right now can follow
- start_delay( DELAY_ASCENDING_STAIRS,
- 1 + (you.burden_state > BS_UNENCUMBERED) );
- break;
-
- case '>':
- case CMD_GO_DOWNSTAIRS:
- if ((grd[you.x_pos][you.y_pos] < DNGN_ENTER_LABYRINTH
- || grd[you.x_pos][you.y_pos] > DNGN_ROCK_STAIRS_DOWN)
- && grd[you.x_pos][you.y_pos] != DNGN_ENTER_HELL
- && ((grd[you.x_pos][you.y_pos] < DNGN_ENTER_DIS
- || grd[you.x_pos][you.y_pos] > DNGN_TRANSIT_PANDEMONIUM)
- && grd[you.x_pos][you.y_pos] != DNGN_STONE_ARCH)
- && !(grd[you.x_pos][you.y_pos] >= DNGN_ENTER_ORCISH_MINES
- && grd[you.x_pos][you.y_pos] < DNGN_RETURN_FROM_ORCISH_MINES))
- {
- mpr( "You can't go down here!" );
- break;
- }
-
- tag_followers(); // only those beside us right now can follow
- start_delay( DELAY_DESCENDING_STAIRS,
- 1 + (you.burden_state > BS_UNENCUMBERED),
- you.your_level );
- break;
-
- case 'O':
- case CMD_DISPLAY_OVERMAP:
- display_overmap();
- break;
-
- case 'o':
- case CMD_OPEN_DOOR:
- open_door(0, 0);
- break;
- case 'c':
- case CMD_CLOSE_DOOR:
- close_door(0, 0);
- break;
-
- case 'd':
- case CMD_DROP:
- drop();
-#ifdef STASH_TRACKING
- if (Options.stash_tracking >= STM_DROPPED)
- stashes.add_stash();
-#endif
- break;
-
-#ifdef STASH_TRACKING
- case CONTROL('F'):
- case CMD_SEARCH_STASHES:
- stashes.search_stashes();
- break;
-
- case CONTROL('S'):
- case CMD_MARK_STASH:
- if (Options.stash_tracking >= STM_EXPLICIT)
- stashes.add_stash(-1, -1, true);
- break;
-
- case CONTROL('E'):
- case CMD_FORGET_STASH:
- if (Options.stash_tracking >= STM_EXPLICIT)
- stashes.no_stash();
- break;
-#endif
-
- case 'D':
- case CMD_BUTCHER:
- butchery();
- break;
-
- case 'i':
- case CMD_DISPLAY_INVENTORY:
- get_invent(-1);
- break;
-
- case 'I':
- case CMD_OBSOLETE_INVOKE:
- // We'll leave this message in for a while. Eventually, this
- // might be some special for of inventory command, or perhaps
- // actual god invocations will be split to here from abilities. -- bwr
- mpr( "This command is now 'E'voke wielded item.", MSGCH_WARN );
- break;
-
- case 'E':
- case CMD_EVOKE:
- if (!evoke_wielded())
- flush_input_buffer( FLUSH_ON_FAILURE );
- break;
-
- case 'g':
- case ',':
- case CMD_PICKUP:
- pickup();
- break;
-
- case ';':
- case CMD_INSPECT_FLOOR:
- item_check(';');
- break;
-
- case 'w':
- case CMD_WIELD_WEAPON:
- wield_weapon(false);
- break;
-
- case 't':
- case CMD_THROW:
- throw_anything();
- break;
-
- case 'f':
- case CMD_FIRE:
- shoot_thing();
- break;
-
- case 'W':
- case CMD_WEAR_ARMOUR:
- wear_armour();
- break;
-
- case 'T':
- case CMD_REMOVE_ARMOUR:
- {
- int index=0;
-
- if (armour_prompt("Take off which item?", &index))
- takeoff_armour(index);
- }
- break;
-
- case 'R':
- case CMD_REMOVE_JEWELLERY:
- remove_ring();
- break;
- case 'P':
- case CMD_WEAR_JEWELLERY:
- puton_ring();
- break;
-
- case '=':
- case CMD_ADJUST_INVENTORY:
- adjust();
- return;
-
- case 'M':
- case CMD_MEMORISE_SPELL:
- if (!learn_spell())
- flush_input_buffer( FLUSH_ON_FAILURE );
- break;
-
- case 'z':
- case CMD_ZAP_WAND:
- zap_wand();
- break;
-
- case 'e':
- case CMD_EAT:
- eat_food();
- break;
-
- case 'a':
- case CMD_USE_ABILITY:
- if (!activate_ability())
- flush_input_buffer( FLUSH_ON_FAILURE );
- break;
-
- case 'A':
- case CMD_DISPLAY_MUTATIONS:
- display_mutations();
- redraw_screen();
- break;
-
- case 'v':
- case CMD_EXAMINE_OBJECT:
- original_name();
- break;
-
- case 'p':
- case CMD_PRAY:
- pray();
- break;
-
- case '^':
- case CMD_DISPLAY_RELIGION:
- describe_god( you.religion, true );
- redraw_screen();
- break;
-
- case '.':
- case CMD_MOVE_NOWHERE:
- search_around();
- move_x = 0;
- move_y = 0;
- you.turn_is_over = 1;
- break;
-
- case 'q':
- case CMD_QUAFF:
- drink();
- break;
-
- case 'r':
- case CMD_READ:
- read_scroll();
- break;
-
- case 'x':
- case CMD_LOOK_AROUND:
- mpr("Move the cursor around to observe a square.", MSGCH_PROMPT);
- mpr("Press '?' for a monster description.", MSGCH_PROMPT);
-
- struct dist lmove;
- lmove.isValid = lmove.isTarget = lmove.isCancel = false;
- look_around( lmove, true );
- if (lmove.isValid && lmove.isTarget && !lmove.isCancel)
- start_travel( lmove.tx, lmove.ty );
- break;
-
- case 's':
- case CMD_SEARCH:
- search_around();
- you.turn_is_over = 1;
- break;
-
- case 'Z':
- case CMD_CAST_SPELL:
- /* randart wpns */
- if (scan_randarts(RAP_PREVENT_SPELLCASTING))
- {
- mpr("Something interferes with your magic!");
- flush_input_buffer( FLUSH_ON_FAILURE );
- break;
- }
-
- if (!cast_a_spell())
- flush_input_buffer( FLUSH_ON_FAILURE );
- break;
-
- case '\'':
- case CMD_WEAPON_SWAP:
- wield_weapon(true);
- break;
-
- // [ds] Waypoints can be added from the level-map, and we need Ctrl+F for
- // nobler things. Who uses waypoints, anyway?
- // Update: Appears people do use waypoints. Reinstating, on CONTROL('W').
- // This means Ctrl+W is no longer a wizmode trigger, but there's
- // always '&'. :-)
- case CMD_FIX_WAYPOINT:
- case CONTROL('W'):
- travel_cache.add_waypoint();
- break;
-
- case CMD_INTERLEVEL_TRAVEL:
- case CONTROL('G'):
- if (!can_travel_interlevel())
- {
- mpr("Sorry, you can't auto-travel out of here.");
- break;
- }
- start_translevel_travel();
- redraw_screen();
- break;
-
- case CONTROL('O'):
- case CMD_EXPLORE:
- if (you.level_type == LEVEL_LABYRINTH || you.level_type == LEVEL_ABYSS)
- {
- mpr("It would help if you knew where you were, first.");
- break;
- }
- // Start exploring
- start_explore();
- break;
-
- case 'X':
- case CMD_DISPLAY_MAP:
-#if (!DEBUG_DIAGNOSTICS)
- if (you.level_type == LEVEL_LABYRINTH || you.level_type == LEVEL_ABYSS)
- {
- mpr("It would help if you knew where you were, first.");
- break;
- }
-#endif
- plox[0] = 0;
- show_map(plox);
- redraw_screen();
- if (plox[0] > 0)
- start_travel(plox[0], plox[1]);
- break;
-
- case '\\':
- case CMD_DISPLAY_KNOWN_OBJECTS:
- check_item_knowledge(); //nothing = check_item_knowledge();
- redraw_screen();
- break;
-
-#ifdef ALLOW_DESTROY_ITEM_COMMAND
- case CONTROL('D'):
- case CMD_DESTROY_ITEM:
- cmd_destroy_item();
- break;
-#endif
-
- case CONTROL('P'):
- case CMD_REPLAY_MESSAGES:
- replay_messages();
- redraw_screen();
- break;
-
- case CONTROL('R'):
- case CMD_REDRAW_SCREEN:
- redraw_screen();
- break;
-
- case CONTROL('X'):
- case CMD_SAVE_GAME_NOW:
- mpr("Saving game... please wait.");
- save_game(true);
- break;
-
-#ifdef USE_UNIX_SIGNALS
- case CONTROL('Z'):
- case CMD_SUSPEND_GAME:
- // CTRL-Z suspend behaviour is implemented here,
- // because we want to have CTRL-Y available...
- // and unfortuantely they tend to be stuck together.
- clrscr();
- unixcurses_shutdown();
- kill(0, SIGTSTP);
- unixcurses_startup();
- redraw_screen();
- break;
-#endif
-
- case '?':
- case CMD_DISPLAY_COMMANDS:
- list_commands(false);
- redraw_screen();
- break;
-
- case 'C':
- case CMD_EXPERIENCE_CHECK:
- snprintf( info, INFO_SIZE, "You are a level %d %s %s.", you.experience_level,
- species_name(you.species,you.experience_level), you.class_name);
- mpr(info);
-
- if (you.experience_level < 27)
- {
- int xp_needed = (exp_needed(you.experience_level+2) - you.experience) + 1;
- snprintf( info, INFO_SIZE, "Level %d requires %ld experience (%d point%s to go!)",
- you.experience_level + 1,
- exp_needed(you.experience_level + 2) + 1,
- xp_needed,
- (xp_needed > 1) ? "s" : "");
- mpr(info);
- }
- else
- {
- mpr( "I'm sorry, level 27 is as high as you can go." );
- mpr( "With the way you've been playing, I'm surprised you got this far." );
- }
-
- if (you.real_time != -1)
- {
- const time_t curr = you.real_time + (time(NULL) - you.start_time);
- char buff[200];
-
- make_time_string( curr, buff, sizeof(buff) );
-
- snprintf( info, INFO_SIZE, "Play time: %s (%ld turns)",
- buff, you.num_turns );
-
- mpr( info );
- }
- break;
-
-
- case '!':
- case CMD_SHOUT:
- yell(); /* in effects.cc */
- break;
-
- case '@':
- case CMD_DISPLAY_CHARACTER_STATUS:
- display_char_status();
- break;
-
- case 'm':
- case CMD_DISPLAY_SKILLS:
- show_skills();
- redraw_screen();
- break;
-
- case '#':
- case CMD_CHARACTER_DUMP:
- char name_your[kNameLen+1];
-
- strncpy(name_your, you.your_name, kNameLen);
- name_your[kNameLen] = '\0';
- if (dump_char( name_your, false ))
- strcpy(info, "Char dumped successfully.");
- else
- strcat(info, "Char dump unsuccessful! Sorry about that.");
- mpr(info);
- break;
-
-#ifdef USE_MACROS
- case '`':
- case CMD_MACRO_ADD:
- macro_add_query();
- break;
- case '~':
- case CMD_MACRO_SAVE:
- mpr("Saving macros.");
- macro_save();
- break;
-#endif
-
- case ')':
- case CMD_LIST_WEAPONS:
- list_weapons();
- return;
-
- case ']':
- case CMD_LIST_ARMOUR:
- list_armour();
- return;
-
- case '"':
- case CMD_LIST_JEWELLERY:
- list_jewellery();
- return;
-
-#ifdef WIZARD
- case CMD_WIZARD:
- case '&':
- handle_wizard_command();
- break;
-#endif
-
- case 'S':
- case CMD_SAVE_GAME:
- if (yesno("Save game and exit?", false, 'n'))
- save_game(true);
- break;
-
- case 'Q':
- case CMD_QUIT:
- quit_game();
- break;
-
- case 'V':
- case CMD_GET_VERSION:
- version();
- break;
-
- case 128: // Can't use this char -- it's the special value 128
- break;
-
- default:
- case CMD_NO_CMD:
- mpr("Unknown command.");
- break;
-
- }
-
-#ifdef UNIX
- // New Unix keypad stuff
- if (running)
- {
- int dir = -1;
-
- // XXX: ugly hack to interface this with the new running code. -- bwr
- for (int i = 0; i < 8; i++)
- {
- if (Compass[i].x == move_x && Compass[i].y == move_y)
- {
- dir = i;
- break;
- }
- }
-
- if (dir != -1)
- {
- start_running( dir, 2 );
- move_x = 0;
- move_y = 0;
- }
- }
- else if (opening)
- {
- open_door(move_x, move_y);
- move_x = 0;
- move_y = 0;
- }
-#endif
-
- if (move_x != 0 || move_y != 0)
- move_player(move_x, move_y);
- else if (you.turn_is_over) // we did something other than move/attack
- do_berserk_no_combat_penalty();
-
- if (!you.turn_is_over)
- {
- viewwindow(1, false);
- return;
- }
-
- if (you.num_turns != -1)
- you.num_turns++;
-
- //if (random2(10) < you.skills [SK_TRAPS_DOORS] + 2) search_around();
-
- stealth = check_stealth();
-
-#if 0
- // too annoying for regular diagnostics
- snprintf( info, INFO_SIZE, "stealth: %d", stealth );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (you.special_wield != SPWLD_NONE)
- special_wielded();
-
- if (one_chance_in(10))
- {
- // this is instantaneous
- if (player_teleport() > 0 && one_chance_in(100 / player_teleport()))
- you_teleport2( true );
- else if (you.level_type == LEVEL_ABYSS && one_chance_in(30))
- you_teleport2( false, true ); // to new area of the Abyss
- }
-
- if (env.cgrid[you.x_pos][you.y_pos] != EMPTY_CLOUD)
- in_a_cloud();
-
- if (you.duration[DUR_REPEL_UNDEAD] > 1)
- you.duration[DUR_REPEL_UNDEAD]--;
-
- if (you.duration[DUR_REPEL_UNDEAD] == 4)
- {
- mpr( "Your holy aura is starting to fade.", MSGCH_DURATION );
- you.duration[DUR_REPEL_UNDEAD] -= random2(3);
- }
-
- if (you.duration[DUR_REPEL_UNDEAD] == 1)
- {
- mpr( "Your holy aura fades away.", MSGCH_DURATION );
- you.duration[DUR_REPEL_UNDEAD] = 0;
- }
-
- // paradox: it both lasts longer & does more damage overall if you're
- // moving slower.
- // rationalisation: I guess it gets rubbed off/falls off/etc if you
- // move around more.
- if (you.duration[DUR_LIQUID_FLAMES] > 0)
- you.duration[DUR_LIQUID_FLAMES]--;
-
- if (you.duration[DUR_LIQUID_FLAMES] != 0)
- {
- const int res_fire = player_res_fire();
-
- mpr( "You are covered in liquid flames!", MSGCH_WARN );
- scrolls_burn(8, OBJ_SCROLLS);
-
- if (res_fire > 0)
- {
- ouch( (((random2avg(9, 2) + 1) * you.time_taken) /
- (1 + (res_fire * res_fire))) / 10, 0, KILLED_BY_BURNING );
- }
-
- if (res_fire <= 0)
- {
- ouch(((random2avg(9, 2) + 1) * you.time_taken) / 10, 0,
- KILLED_BY_BURNING);
- }
-
- if (res_fire < 0)
- {
- ouch(((random2avg(9, 2) + 1) * you.time_taken) / 10, 0,
- KILLED_BY_BURNING);
- }
-
- if (you.duration[DUR_CONDENSATION_SHIELD] > 0)
- {
- mpr("Your icy shield dissipates!", MSGCH_DURATION);
- you.duration[DUR_CONDENSATION_SHIELD] = 0;
- you.redraw_armour_class = 1;
- }
- }
-
- if (you.duration[DUR_ICY_ARMOUR] > 1)
- {
- you.duration[DUR_ICY_ARMOUR]--;
- //scrolls_burn(4, OBJ_POTIONS);
- }
- else if (you.duration[DUR_ICY_ARMOUR] == 1)
- {
- mpr("Your icy armour evaporates.", MSGCH_DURATION);
- you.redraw_armour_class = 1; // is this needed? 2apr2000 {dlb}
- you.duration[DUR_ICY_ARMOUR] = 0;
- }
-
- if (you.duration[DUR_REPEL_MISSILES] > 1)
- {
- you.duration[DUR_REPEL_MISSILES]--;
- if (you.duration[DUR_REPEL_MISSILES] == 6)
- {
- mpr("Your repel missiles spell is about to expire...", MSGCH_DURATION);
- if (coinflip())
- you.duration[DUR_REPEL_MISSILES]--;
- }
- }
- else if (you.duration[DUR_REPEL_MISSILES] == 1)
- {
- mpr("You feel less protected from missiles.", MSGCH_DURATION);
- you.duration[DUR_REPEL_MISSILES] = 0;
- }
-
- if (you.duration[DUR_DEFLECT_MISSILES] > 1)
- {
- you.duration[DUR_DEFLECT_MISSILES]--;
- if (you.duration[DUR_DEFLECT_MISSILES] == 6)
- {
- mpr("Your deflect missiles spell is about to expire...", MSGCH_DURATION);
- if (coinflip())
- you.duration[DUR_DEFLECT_MISSILES]--;
- }
- }
- else if (you.duration[DUR_DEFLECT_MISSILES] == 1)
- {
- mpr("You feel less protected from missiles.", MSGCH_DURATION);
- you.duration[DUR_DEFLECT_MISSILES] = 0;
- }
-
- if (you.duration[DUR_REGENERATION] > 1)
- {
- you.duration[DUR_REGENERATION]--;
-
- if (you.duration[DUR_REGENERATION] == 6)
- {
- mpr("Your skin is crawling a little less now.", MSGCH_DURATION);
- if (coinflip())
- you.duration[DUR_REGENERATION]--;
- }
- }
- else if (you.duration[DUR_REGENERATION] == 1)
- {
- mpr("Your skin stops crawling.", MSGCH_DURATION);
- you.duration[DUR_REGENERATION] = 0;
- }
-
- if (you.duration[DUR_PRAYER] > 1)
- you.duration[DUR_PRAYER]--;
- else if (you.duration[DUR_PRAYER] == 1)
- {
- god_speaks(you.religion, "Your prayer is over.");
- you.duration[DUR_PRAYER] = 0;
- }
-
-
- //jmf: more flexible weapon branding code
- if (you.duration[DUR_WEAPON_BRAND] > 1)
- you.duration[DUR_WEAPON_BRAND]--;
- else if (you.duration[DUR_WEAPON_BRAND] == 1)
- {
- const int wpn = you.equip[EQ_WEAPON];
- const int temp_effect = get_weapon_brand( you.inv[wpn] );
-
- you.duration[DUR_WEAPON_BRAND] = 0;
-
- char str_pass[ITEMNAME_SIZE];
-
- set_item_ego_type( you.inv[wpn], OBJ_WEAPONS, SPWPN_NORMAL );
- in_name(wpn, DESC_CAP_YOUR, str_pass);
- strncpy(info, str_pass, INFO_SIZE);
-
- switch (temp_effect)
- {
- case SPWPN_VORPAL:
- if (get_vorpal_type(you.inv[you.equip[EQ_WEAPON]])
- == DVORP_SLICING)
- strcat(info, " seems blunter.");
- else
- strcat(info, " feels lighter.");
- break;
-
- case SPWPN_FLAMING:
- strcat(info, " goes out.");
- break;
- case SPWPN_FREEZING:
- strcat(info, " stops glowing.");
- break;
- case SPWPN_VENOM:
- strcat(info, " stops dripping with poison.");
- break;
- case SPWPN_DRAINING:
- strcat(info, " stops crackling.");
- break;
- case SPWPN_DISTORTION:
- strcat( info, " seems straighter." );
- // [dshaligram] Makes the brand unusable
- // miscast_effect( SPTYP_TRANSLOCATION, 9, 90, 100, "a distortion effect" );
- break;
- default:
- strcat(info, " seems inexplicably less special.");
- break;
- }
-
- //you.attribute[ATTR_WEAPON_BRAND] = 0;
- mpr(info, MSGCH_DURATION);
- you.wield_change = true;
- }
-
- if (you.duration[DUR_BREATH_WEAPON] > 1)
- you.duration[DUR_BREATH_WEAPON]--;
- else if (you.duration[DUR_BREATH_WEAPON] == 1)
- {
- mpr("You have got your breath back.", MSGCH_RECOVERY);
- you.duration[DUR_BREATH_WEAPON] = 0;
- }
-
- if (you.duration[DUR_TRANSFORMATION] > 1)
- {
- you.duration[DUR_TRANSFORMATION]--;
-
- if (you.duration[DUR_TRANSFORMATION] == 10)
- {
- mpr("Your transformation is almost over.", MSGCH_DURATION);
- you.duration[DUR_TRANSFORMATION] -= random2(3);
- }
- }
- else if (you.duration[DUR_TRANSFORMATION] == 1)
- {
- untransform();
- you.duration[DUR_BREATH_WEAPON] = 0;
- }
-
- if (you.duration[DUR_SWIFTNESS] > 1)
- {
- you.duration[DUR_SWIFTNESS]--;
- if (you.duration[DUR_SWIFTNESS] == 6)
- {
- mpr("You start to feel a little slower.", MSGCH_DURATION);
- if (coinflip())
- you.duration[DUR_SWIFTNESS]--;
- }
- }
- else if (you.duration[DUR_SWIFTNESS] == 1)
- {
- mpr("You feel sluggish.", MSGCH_DURATION);
- you.duration[DUR_SWIFTNESS] = 0;
- }
-
- if (you.duration[DUR_INSULATION] > 1)
- {
- you.duration[DUR_INSULATION]--;
- if (you.duration[DUR_INSULATION] == 6)
- {
- mpr("You start to feel a little less insulated.", MSGCH_DURATION);
- if (coinflip())
- you.duration[DUR_INSULATION]--;
- }
- }
- else if (you.duration[DUR_INSULATION] == 1)
- {
- mpr("You feel conductive.", MSGCH_DURATION);
- you.duration[DUR_INSULATION] = 0;
- }
-
- if (you.duration[DUR_STONEMAIL] > 1)
- {
- you.duration[DUR_STONEMAIL]--;
- if (you.duration[DUR_STONEMAIL] == 6)
- {
- mpr("Your scaly stone armour is starting to flake away.", MSGCH_DURATION);
- you.redraw_armour_class = 1;
- if (coinflip())
- you.duration[DUR_STONEMAIL]--;
- }
- }
- else if (you.duration[DUR_STONEMAIL] == 1)
- {
- mpr("Your scaly stone armour disappears.", MSGCH_DURATION);
- you.duration[DUR_STONEMAIL] = 0;
- you.redraw_armour_class = 1;
- burden_change();
- }
-
- if (you.duration[DUR_FORESCRY] > 1) //jmf: added
- you.duration[DUR_FORESCRY]--;
- else if (you.duration[DUR_FORESCRY] == 1)
- {
- mpr("You feel firmly rooted in the present.", MSGCH_DURATION);
- you.duration[DUR_FORESCRY] = 0;
- you.redraw_evasion = 1;
- }
-
- if (you.duration[DUR_SEE_INVISIBLE] > 1) //jmf: added
- you.duration[DUR_SEE_INVISIBLE]--;
- else if (you.duration[DUR_SEE_INVISIBLE] == 1)
- {
- you.duration[DUR_SEE_INVISIBLE] = 0;
-
- if (!player_see_invis())
- mpr("Your eyesight blurs momentarily.", MSGCH_DURATION);
- }
-
- if (you.duration[DUR_SILENCE] > 0) //jmf: cute message handled elsewhere
- you.duration[DUR_SILENCE]--;
-
- if (you.duration[DUR_CONDENSATION_SHIELD] > 1)
- {
- you.duration[DUR_CONDENSATION_SHIELD]--;
-
- // [dshaligram] Makes this spell useless
- // scrolls_burn( 1, OBJ_POTIONS );
-
- if (player_res_cold() < 0)
- {
- mpr( "You feel very cold." );
- ouch( 2 + random2avg(13, 2), 0, KILLED_BY_FREEZING );
- }
- }
- else if (you.duration[DUR_CONDENSATION_SHIELD] == 1)
- {
- you.duration[DUR_CONDENSATION_SHIELD] = 0;
- mpr("Your icy shield evaporates.", MSGCH_DURATION);
- you.redraw_armour_class = 1;
- }
-
- if (you.duration[DUR_STONESKIN] > 1)
- you.duration[DUR_STONESKIN]--;
- else if (you.duration[DUR_STONESKIN] == 1)
- {
- mpr("Your skin feels tender.", MSGCH_DURATION);
- you.redraw_armour_class = 1;
- you.duration[DUR_STONESKIN] = 0;
- }
-
- if (you.duration[DUR_GLAMOUR] > 1) //jmf: actually GLAMOUR_RELOAD, like
- you.duration[DUR_GLAMOUR]--; // the breath weapon delay
- else if (you.duration[DUR_GLAMOUR] == 1)
- {
- you.duration[DUR_GLAMOUR] = 0;
- //FIXME: cute message or not?
- }
-
- if (you.duration[DUR_TELEPORT] > 1)
- you.duration[DUR_TELEPORT]--;
- else if (you.duration[DUR_TELEPORT] == 1)
- {
- // only to a new area of the abyss sometimes (for abyss teleports)
- you_teleport2( true, one_chance_in(5) );
- you.duration[DUR_TELEPORT] = 0;
- }
-
- if (you.duration[DUR_CONTROL_TELEPORT] > 1)
- {
- you.duration[DUR_CONTROL_TELEPORT]--;
-
- if (you.duration[DUR_CONTROL_TELEPORT] == 6)
- {
- mpr("You start to feel a little uncertain.", MSGCH_DURATION);
- if (coinflip())
- you.duration[DUR_CONTROL_TELEPORT]--;
- }
- }
- else if (you.duration[DUR_CONTROL_TELEPORT] == 1)
- {
- mpr("You feel uncertain.", MSGCH_DURATION);
- you.duration[DUR_CONTROL_TELEPORT] = 0;
- you.attribute[ATTR_CONTROL_TELEPORT]--;
- }
-
- if (you.duration[DUR_RESIST_POISON] > 1)
- {
- you.duration[DUR_RESIST_POISON]--;
- if (you.duration[DUR_RESIST_POISON] == 6)
- {
- mpr("Your poison resistance is about to expire.", MSGCH_DURATION);
- if (coinflip())
- you.duration[DUR_RESIST_POISON]--;
- }
- }
- else if (you.duration[DUR_RESIST_POISON] == 1)
- {
- mpr("Your poison resistance expires.", MSGCH_DURATION);
- you.duration[DUR_RESIST_POISON] = 0;
- }
-
- if (you.duration[DUR_DEATH_CHANNEL] > 1)
- {
- you.duration[DUR_DEATH_CHANNEL]--;
- if (you.duration[DUR_DEATH_CHANNEL] == 6)
- {
- mpr("Your unholy channel is weakening.", MSGCH_DURATION);
- if (coinflip())
- you.duration[DUR_DEATH_CHANNEL]--;
- }
- }
- else if (you.duration[DUR_DEATH_CHANNEL] == 1)
- {
- mpr("Your unholy channel expires.", MSGCH_DURATION); // Death channel wore off
- you.duration[DUR_DEATH_CHANNEL] = 0;
- }
-
- if (you.invis > 1)
- {
- you.invis--;
-
- if (you.invis == 6)
- {
- mpr("You flicker for a moment.", MSGCH_DURATION);
- if (coinflip())
- you.invis--;
- }
- }
- else if (you.invis == 1)
- {
- mpr("You flicker back into view.", MSGCH_DURATION);
- you.invis = 0;
- }
-
- if (you.conf > 0)
- reduce_confuse_player(1);
-
- if (you.paralysis > 1)
- you.paralysis--;
- else if (you.paralysis == 1)
- {
- mpr("You can move again.", MSGCH_DURATION);
- you.paralysis = 0;
- }
-
- if (you.exhausted > 1)
- you.exhausted--;
- else if (you.exhausted == 1)
- {
- mpr("You feel less fatigued.", MSGCH_DURATION);
- you.exhausted = 0;
- }
-
- dec_slow_player();
- dec_haste_player();
-
- if (you.might > 1)
- you.might--;
- else if (you.might == 1)
- {
- mpr("You feel a little less mighty now.", MSGCH_DURATION);
- you.might = 0;
- modify_stat(STAT_STRENGTH, -5, true);
- }
-
- if (you.berserker > 1)
- you.berserker--;
- else if (you.berserker == 1)
- {
- mpr( "You are no longer berserk.", MSGCH_DURATION );
- you.berserker = 0;
-
- //jmf: guilty for berserking /after/ berserk
- did_god_conduct( DID_STIMULANTS, 6 + random2(6) );
-
- //
- // Sometimes berserk leaves us physically drained
- //
-
- // chance of passing out:
- // - mutation gives a large plus in order to try and
- // avoid the mutation being a "death sentence" to
- // certain characters.
- // - knowing the spell gives an advantage just
- // so that people who have invested 3 spell levels
- // are better off than the casual potion drinker...
- // this should make it a bit more interesting for
- // Crusaders again.
- // - similarly for the amulet
- int chance = 10 + you.mutation[MUT_BERSERK] * 25
- + (wearing_amulet( AMU_RAGE ) ? 10 : 0)
- + (player_has_spell( SPELL_BERSERKER_RAGE ) ? 5 : 0);
-
- // Note the beauty of Trog! They get an extra save that's at
- // the very least 20% and goes up to 100%.
- if (you.berserk_penalty == NO_BERSERK_PENALTY
- || (you.religion == GOD_TROG && you.piety > random2(150))
- || !one_chance_in( chance ))
- {
- mpr("You are exhausted.");
- }
- else
- {
- mpr("You pass out from exhaustion.", MSGCH_WARN);
- you.paralysis += roll_dice( 1, 4 );
- }
-
- // this resets from an actual penalty or from NO_BERSERK_PENALTY
- you.berserk_penalty = 0;
-
- int dur = 12 + roll_dice( 2, 12 );
- you.exhausted += dur;
- slow_player( dur );
-
- make_hungry(700, true);
-
- if (you.hunger < 50)
- you.hunger = 50;
-
- calc_hp();
- }
-
- if (you.confusing_touch > 1)
- you.confusing_touch--;
- else if (you.confusing_touch == 1)
- {
- snprintf( info, INFO_SIZE, "Your %s stop glowing.", your_hand(true) );
- mpr( info, MSGCH_DURATION );
- you.confusing_touch = 0;
- }
-
- if (you.sure_blade > 1)
- you.sure_blade--;
- else if (you.sure_blade == 1)
- {
- mpr("The bond with your blade fades away.", MSGCH_DURATION);
- you.sure_blade = 0;
- }
-
- if (you.levitation > 1)
- {
- if (you.species != SP_KENKU || you.experience_level < 15)
- you.levitation--;
-
- if (player_equip_ego_type( EQ_BOOTS, SPARM_LEVITATION ))
- you.levitation = 2;
-
- if (you.levitation == 10)
- {
- mpr("You are starting to lose your buoyancy!", MSGCH_DURATION);
- you.levitation -= random2(6);
-
- if (you.duration[DUR_CONTROLLED_FLIGHT] > 0)
- you.duration[DUR_CONTROLLED_FLIGHT] = you.levitation;
- }
- }
- else if (you.levitation == 1)
- {
- mpr("You float gracefully downwards.", MSGCH_DURATION);
- you.levitation = 0;
- burden_change();
- you.duration[DUR_CONTROLLED_FLIGHT] = 0;
-
- if (grd[you.x_pos][you.y_pos] == DNGN_LAVA
- || grd[you.x_pos][you.y_pos] == DNGN_DEEP_WATER
- || grd[you.x_pos][you.y_pos] == DNGN_SHALLOW_WATER)
- {
- if (you.species == SP_MERFOLK
- && grd[you.x_pos][you.y_pos] != DNGN_LAVA)
- {
- mpr("You dive into the water and return to your normal form.");
- merfolk_start_swimming();
- }
-
- if (grd[you.x_pos][you.y_pos] != DNGN_SHALLOW_WATER)
- fall_into_a_pool(true, grd[you.x_pos][you.y_pos]);
- }
- }
-
- if (you.rotting > 0)
- {
- // XXX: Mummies have an ability (albeit an expensive one) that
- // can fix rotted HPs now... it's probably impossible for them
- // to even start rotting right now, but that could be changed. -- bwr
- if (you.species == SP_MUMMY)
- you.rotting = 0;
- else if (random2(20) <= (you.rotting - 1))
- {
- mpr("You feel your flesh rotting away.", MSGCH_WARN);
- ouch(1, 0, KILLED_BY_ROTTING);
- rot_hp(1);
- you.rotting--;
- }
- }
-
- // ghoul rotting is special, but will deduct from you.rotting
- // if it happens to be positive - because this is placed after
- // the "normal" rotting check, rotting attacks can be somewhat
- // more painful on ghouls - reversing order would make rotting
- // attacks somewhat less painful, but that seems wrong-headed {dlb}:
- if (you.species == SP_GHOUL)
- {
- if (one_chance_in(400))
- {
- mpr("You feel your flesh rotting away.", MSGCH_WARN);
- ouch(1, 0, KILLED_BY_ROTTING);
- rot_hp(1);
-
- if (you.rotting > 0)
- you.rotting--;
- }
- }
-
- dec_disease_player();
-
- if (you.poison > 0)
- {
- if (random2(5) <= (you.poison - 1))
- {
- if (you.poison > 10 && random2(you.poison) >= 8)
- {
- ouch(random2(10) + 5, 0, KILLED_BY_POISON);
- mpr("You feel extremely sick.", MSGCH_DANGER);
- }
- else if (you.poison > 5 && coinflip())
- {
- ouch((coinflip()? 3 : 2), 0, KILLED_BY_POISON);
- mpr("You feel very sick.", MSGCH_WARN);
- }
- else
- {
- // the poison running through your veins.");
- ouch(1, 0, KILLED_BY_POISON);
- mpr("You feel sick.");
- }
-
- if ((you.hp == 1 && one_chance_in(3)) || one_chance_in(8))
- reduce_poison_player(1);
- }
- }
-
- if (you.deaths_door)
- {
- if (you.hp > allowed_deaths_door_hp())
- {
- mpr("Your life is in your own hands once again.", MSGCH_DURATION);
- you.paralysis += 5 + random2(5);
- confuse_player( 10 + random2(10) );
- you.hp_max--;
- deflate_hp(you.hp_max, false);
- you.deaths_door = 0;
- }
- else
- you.deaths_door--;
-
- if (you.deaths_door == 10)
- {
- mpr("Your time is quickly running out!", MSGCH_DURATION);
- you.deaths_door -= random2(6);
- }
- if (you.deaths_door == 1)
- {
- mpr("Your life is in your own hands again!", MSGCH_DURATION);
- more();
- }
- }
-
- const int food_use = player_hunger_rate();
-
- if (food_use > 0 && you.hunger >= 40)
- make_hungry( food_use, true );
-
- // XXX: using an int tmp to fix the fact that hit_points_regeneration
- // is only an unsigned char and is thus likely to overflow. -- bwr
- int tmp = static_cast< int >( you.hit_points_regeneration );
-
- if (you.hp < you.hp_max && !you.disease && !you.deaths_door)
- tmp += player_regen();
-
- while (tmp >= 100)
- {
- if (you.hp >= you.hp_max - 1
- && you.running && you.run_x == 0 && you.run_y == 0)
- {
- stop_running();
- }
-
- inc_hp(1, false);
- tmp -= 100;
- }
-
- ASSERT( tmp >= 0 && tmp < 100 );
- you.hit_points_regeneration = static_cast< unsigned char >( tmp );
-
- // XXX: Doing the same as the above, although overflow isn't an
- // issue with magic point regeneration, yet. -- bwr
- tmp = static_cast< int >( you.magic_points_regeneration );
-
- if (you.magic_points < you.max_magic_points)
- tmp += 7 + you.max_magic_points / 2;
-
- while (tmp >= 100)
- {
- if (you.magic_points >= you.max_magic_points - 1
- && you.running && you.run_x == 0 && you.run_y == 0)
- {
- stop_running();
- }
-
- inc_mp(1, false);
- tmp -= 100;
- }
-
- ASSERT( tmp >= 0 && tmp < 100 );
- you.magic_points_regeneration = static_cast< unsigned char >( tmp );
-
- // If you're wielding a rod, it'll gradually recharge.
- recharge_rods();
-
- viewwindow(1, true);
-
- handle_monsters();
-
- ASSERT(you.time_taken >= 0);
- // make sure we don't overflow
- ASSERT(DBL_MAX - you.elapsed_time > you.time_taken);
-
- you.elapsed_time += you.time_taken;
-
- if (you.synch_time <= you.time_taken)
- {
- handle_time(200 + (you.time_taken - you.synch_time));
- you.synch_time = 200;
- }
- else
- {
- you.synch_time -= you.time_taken;
- }
-
- manage_clouds();
-
- if (you.fire_shield > 0)
- manage_fire_shield();
-
- // There used to be signs of intent to have statues as some sort
- // of more complex state machine... I'm boiling them down to bare
- // basics for now. -- bwr
- if (Visible_Statue[ STATUE_SILVER ])
- {
- interrupt_activity( AI_STATUE );
-
- if ((!you.invis && one_chance_in(3)) || one_chance_in(5))
- {
- char wc[30];
-
- weird_colours( random2(256), wc );
- snprintf(info, INFO_SIZE, "The silver statue's eyes glow %s.", wc);
- mpr( info, MSGCH_WARN );
-
- create_monster( summon_any_demon((coinflip() ? DEMON_COMMON
- : DEMON_LESSER)),
- ENCH_ABJ_V, BEH_HOSTILE,
- you.x_pos, you.y_pos,
- MHITYOU, 250 );
- }
-
- Visible_Statue[ STATUE_SILVER ] = 0;
- }
-
- if (Visible_Statue[ STATUE_ORANGE_CRYSTAL ])
- {
- interrupt_activity( AI_STATUE );
-
- if ((!you.invis && coinflip()) || one_chance_in(4))
- {
- mpr("A hostile presence attacks your mind!", MSGCH_WARN);
-
- miscast_effect( SPTYP_DIVINATION, random2(15), random2(150), 100,
- "an orange crystal statue" );
- }
-
- Visible_Statue[ STATUE_ORANGE_CRYSTAL ] = 0;
- }
-
- // food death check:
- if (you.is_undead != US_UNDEAD && you.hunger <= 500)
- {
- if (!you.paralysis && one_chance_in(40))
- {
- mpr("You lose consciousness!", MSGCH_FOOD);
- you.paralysis += 5 + random2(8);
-
- if (you.paralysis > 13)
- you.paralysis = 13;
- }
-
- if (you.hunger <= 100)
- {
- mpr( "You have starved to death.", MSGCH_FOOD );
- ouch( -9999, 0, KILLED_BY_STARVATION );
- }
- }
-
- //jmf: added silence messages
- its_quiet = silenced(you.x_pos, you.y_pos);
-
- if (you.attribute[ATTR_WAS_SILENCED] != its_quiet)
- {
- if (its_quiet)
- {
- if (random2(30))
- mpr("You are enveloped in profound silence.", MSGCH_WARN);
- else
- mpr("The dungeon seems quiet ... too quiet!", MSGCH_WARN);
- }
- else
- {
- mpr("Your hearing returns.", MSGCH_RECOVERY);
- }
-
- you.attribute[ATTR_WAS_SILENCED] = its_quiet;
- }
-
- viewwindow(1, false);
-
- if (you.paralysis > 0 && any_messages())
- more();
-
- // place normal dungeon monsters, but not in player LOS
- if (you.level_type == LEVEL_DUNGEON
- && !player_in_branch( BRANCH_ECUMENICAL_TEMPLE )
- && one_chance_in((you.char_direction == DIR_DESCENDING) ? 240 : 10))
- {
- int prox = (one_chance_in(10) ? PROX_NEAR_STAIRS
- : PROX_AWAY_FROM_PLAYER);
-
- // The rules change once the player has picked up the Orb...
- if (you.char_direction == DIR_ASCENDING)
- prox = (one_chance_in(10) ? PROX_CLOSE_TO_PLAYER : PROX_ANYWHERE);
-
- mons_place( WANDERING_MONSTER, BEH_HOSTILE, MHITNOT, false,
- 50, 50, LEVEL_DUNGEON, prox );
- }
-
- // place Abyss monsters.
- if (you.level_type == LEVEL_ABYSS && one_chance_in(5))
- {
- mons_place( WANDERING_MONSTER, BEH_HOSTILE, MHITNOT, false,
- 50, 50, LEVEL_ABYSS, PROX_ANYWHERE );
- }
-
- // place Pandemonium monsters
- if (you.level_type == LEVEL_PANDEMONIUM && one_chance_in(50))
- pandemonium_mons();
-
- // No monsters in the Labyrinth, or Ecumenical Temple
- return;
-}
-
-/*
- Opens doors and handles some aspects of untrapping. If either move_x or
- move_y are non-zero, the pair carries a specific direction for the door
- to be opened (eg if you type ctrl - dir).
- */
-static void open_door(char move_x, char move_y)
-{
- struct dist door_move;
- int dx, dy; // door x, door y
-
- door_move.dx = move_x;
- door_move.dy = move_y;
-
- if (move_x || move_y)
- {
- // convenience
- dx = you.x_pos + move_x;
- dy = you.y_pos + move_y;
-
- const int mon = mgrd[dx][dy];
-
- if (mon != NON_MONSTER && !mons_has_ench( &menv[mon], ENCH_SUBMERGED ))
- {
- you_attack(mgrd[dx][dy], true);
- you.turn_is_over = 1;
-
- if (you.berserk_penalty != NO_BERSERK_PENALTY)
- you.berserk_penalty = 0;
-
- return;
- }
-
- if (grd[dx][dy] >= DNGN_TRAP_MECHANICAL && grd[dx][dy] <= DNGN_TRAP_III)
- {
- if (env.cgrid[dx][dy] != EMPTY_CLOUD)
- {
- mpr("You can't get to that trap right now.");
- return;
- }
-
- disarm_trap(door_move);
- return;
- }
-
- }
- else
- {
- mpr("Which direction?", MSGCH_PROMPT);
- direction( door_move, DIR_DIR );
- if (!door_move.isValid)
- return;
-
- // convenience
- dx = you.x_pos + door_move.dx;
- dy = you.y_pos + door_move.dy;
- }
-
- if (grd[dx][dy] == DNGN_CLOSED_DOOR)
- {
- int skill = you.dex + (you.skills[SK_TRAPS_DOORS] + you.skills[SK_STEALTH]) / 2;
-
- if (one_chance_in(skill) && !silenced(you.x_pos, you.y_pos))
- {
- mpr( "As you open the door, it creaks loudly!" );
- noisy( 10, you.x_pos, you.y_pos );
- }
- else
- {
- mpr( player_is_levitating() ? "You reach down and open the door."
- : "You open the door." );
- }
-
- grd[dx][dy] = DNGN_OPEN_DOOR;
- you.turn_is_over = 1;
- }
- else
- {
- mpr("You swing at nothing.");
- make_hungry(3, true);
- you.turn_is_over = 1;
- }
-} // end open_door()
-
-/*
- Similar to open_door. Can you spot the difference?
- */
-static void close_door(char door_x, char door_y)
-{
- struct dist door_move;
- int dx, dy; // door x, door y
-
- door_move.dx = door_x;
- door_move.dy = door_y;
-
- if (!(door_x || door_y))
- {
- mpr("Which direction?", MSGCH_PROMPT);
- direction( door_move, DIR_DIR );
- if (!door_move.isValid)
- return;
- }
-
- if (door_move.dx == 0 && door_move.dy == 0)
- {
- mpr("You can't close doors on yourself!");
- return;
- }
-
- // convenience
- dx = you.x_pos + door_move.dx;
- dy = you.y_pos + door_move.dy;
-
- if (grd[dx][dy] == DNGN_OPEN_DOOR)
- {
- if (mgrd[dx][dy] != NON_MONSTER)
- {
- // Need to make sure that turn_is_over = 1 if creature is invisible
- mpr("There's a creature in the doorway!");
- door_move.dx = 0;
- door_move.dy = 0;
- return;
- }
-
- if (igrd[dx][dy] != NON_ITEM)
- {
- mpr("There's something blocking the doorway.");
- door_move.dx = 0;
- door_move.dy = 0;
- return;
- }
-
- int skill = you.dex + (you.skills[SK_TRAPS_DOORS] + you.skills[SK_STEALTH]) / 2;
-
- if (one_chance_in(skill) && !silenced(you.x_pos, you.y_pos))
- {
- mpr("As you close the door, it creaks loudly!");
- noisy( 10, you.x_pos, you.y_pos );
- }
- else
- {
- mpr( player_is_levitating() ? "You reach down and close the door."
- : "You close the door." );
- }
-
- grd[dx][dy] = DNGN_CLOSED_DOOR;
- you.turn_is_over = 1;
- }
- else
- {
- mpr("There isn't anything that you can close there!");
- }
-} // end open_door()
-
-
-// initialise whole lot of stuff...
-// returns true if a new character
-static bool initialise(void)
-{
- bool ret;
-
- int i = 0, j = 0; // counter variables {dlb}
-
- your_sign = '@';
- your_colour = LIGHTGREY;
-
- // system initialisation stuff:
- textbackground(0);
-
-#ifdef DOS
- directvideo = 1;
-#endif
-
-#ifdef USE_EMX
- init_emx();
-#endif
-
- seed_rng();
-
- init_properties();
- init_monsters(mcolour); // this needs to be way up top {dlb}
- init_playerspells(); // this needs to be way up top {dlb}
-
- clrscr();
-
- // init item array:
- for (i = 1; i < MAX_ITEMS; i++)
- init_item( i );
-
- // empty messaging string
- strcpy(info, "");
-
- for (i = 0; i < MAX_MONSTERS; i++)
- {
- menv[i].type = -1;
- menv[i].speed_increment = 10;
- menv[i].flags = 0;
- menv[i].behaviour = BEH_SLEEP;
-
- menv[i].foe = NON_MONSTER;
- menv[i].attitude = ATT_HOSTILE;
-
- for (j = 0; j < NUM_MON_ENCHANTS; j++)
- menv[i].enchantment[j] = ENCH_NONE;
-
- for (j = 0; j < NUM_MONSTER_SLOTS; j++)
- menv[i].inv[j] = NON_ITEM;
-
- menv[i].number = 0;
- }
-
- for (i = 0; i < GXM; i++)
- {
- for (j = 0; j < GYM; j++)
- {
- igrd[i][j] = NON_ITEM;
- mgrd[i][j] = NON_MONSTER;
- env.map[i][j] = 0;
- }
- }
-
- for (i = 0; i < 50; i++)
- {
- you.unique_creatures[i] = 0;
- you.unique_items[i] = UNIQ_NOT_EXISTS;
- }
-
- for (i = 0; i < NUM_STATUE_TYPES; i++)
- Visible_Statue[i] = 0;
-
- // initialize tag system before we try loading anything!
- tag_init();
-
- // sets up a new game:
- bool newc = new_game();
- ret = newc; // newc will be mangled later so we'll take a copy --bwr
-
- if (!newc)
- restore_game();
-
- game_has_started = true;
-
- calc_hp();
- calc_mp();
-
- load( 82, (newc ? LOAD_START_GAME : LOAD_RESTART_GAME), false, 0,
- you.where_are_you );
-
-#if DEBUG_DIAGNOSTICS
- // Debug compiles display a lot of "hidden" information, so we auto-wiz
- you.wizard = true;
-#endif
-
- init_properties();
- burden_change();
- make_hungry(0,true);
-
- you.redraw_strength = 1;
- you.redraw_intelligence = 1;
- you.redraw_dexterity = 1;
- you.redraw_armour_class = 1;
- you.redraw_evasion = 1;
- you.redraw_experience = 1;
- you.redraw_gold = 1;
- you.wield_change = true;
-
- you.start_time = time( NULL ); // start timer on session
-
- draw_border();
- new_level();
-
- travel_init_new_level();
- // Mark items in inventory as of unknown origin.
- origin_set_inventory(origin_set_unknown);
-
- // set vision radius to player's current vision
- setLOSRadius( you.current_vision );
-
- if (newc)
- {
- // For a new game, wipe out monsters in LOS.
- zap_los_monsters();
- }
-
- viewwindow(1, false); // This just puts the view up for the first turn.
- item();
-
-#ifdef CLUA_BINDINGS
- clua.runhook("chk_startgame", "%b", ret);
- std::string yname = you.your_name;
- read_init_file(true);
- strncpy(you.your_name, yname.c_str(), kNameLen);
- you.your_name[kNameLen - 1] = 0;
-#endif
-
- return (ret);
-}
-
-// An attempt to tone down berserk a little bit. -- bwross
-//
-// This function does the accounting for not attacking while berserk
-// This gives a triangluar number function for the additional penalty
-// Turn: 1 2 3 4 5 6 7 8
-// Penalty: 1 3 6 10 15 21 28 36
-//
-// Total penalty (including the standard one during upkeep is:
-// 2 5 9 14 20 27 35 44
-//
-static void do_berserk_no_combat_penalty(void)
-{
- // Butchering/eating a corpse will maintain a blood rage.
- const int delay = current_delay_action();
- if (delay == DELAY_BUTCHER || delay == DELAY_EAT)
- return;
-
- if (you.berserk_penalty == NO_BERSERK_PENALTY)
- return;
-
- if (you.berserker)
- {
- you.berserk_penalty++;
-
- switch (you.berserk_penalty)
- {
- case 2:
- mpr("You feel a strong urge to attack something.", MSGCH_DURATION);
- break;
- case 4:
- mpr("You feel your anger subside.", MSGCH_DURATION);
- break;
- case 6:
- mpr("Your blood rage is quickly leaving you.", MSGCH_DURATION);
- break;
- }
-
- // I do these three separately, because the might and
- // haste counters can be different.
- you.berserker -= you.berserk_penalty;
- if (you.berserker < 1)
- you.berserker = 1;
-
- you.might -= you.berserk_penalty;
- if (you.might < 1)
- you.might = 1;
-
- you.haste -= you.berserk_penalty;
- if (you.haste < 1)
- you.haste = 1;
- }
- return;
-} // end do_berserk_no_combat_penalty()
-
-
-// Called when the player moves by walking/running. Also calls
-// attack function and trap function etc when necessary.
-static void move_player(char move_x, char move_y)
-{
- bool attacking = false;
- bool moving = true; // used to prevent eventual movement (swap)
-
- int i;
- bool trap_known;
-
- if (you.conf)
- {
- if (!one_chance_in(3))
- {
- move_x = random2(3) - 1;
- move_y = random2(3) - 1;
- }
-
- const int new_targ_x = you.x_pos + move_x;
- const int new_targ_y = you.y_pos + move_y;
- const unsigned char new_targ_grid = grd[ new_targ_x ][ new_targ_y ];
-
- if (new_targ_grid < MINMOVE)
- {
- you.turn_is_over = 1;
- mpr("Ouch!");
- return;
- }
-
- if (new_targ_grid == DNGN_LAVA
- && you.duration[DUR_CONDENSATION_SHIELD] > 0)
- {
- mpr("Your icy shield dissipates!", MSGCH_DURATION);
- you.duration[DUR_CONDENSATION_SHIELD] = 0;
- you.redraw_armour_class = 1;
- }
-
- if ((new_targ_grid == DNGN_LAVA
- || new_targ_grid == DNGN_DEEP_WATER
- || new_targ_grid == DNGN_SHALLOW_WATER)
- && !player_is_levitating())
- {
- if (you.species == SP_MERFOLK && new_targ_grid != DNGN_LAVA)
- {
- mpr("You stumble into the water and return to your normal form.");
- merfolk_start_swimming();
- }
-
- if (new_targ_grid != DNGN_SHALLOW_WATER)
- fall_into_a_pool( false, new_targ_grid );
-
- you.turn_is_over = 1;
- do_berserk_no_combat_penalty();
- return;
- }
- } // end of if you.conf
-
- if (you.running > 0 && you.running != 2 && check_stop_running())
- {
- stop_running();
- move_x = 0;
- move_y = 0;
- you.turn_is_over = 0;
- return;
- }
-
- const int targ_x = you.x_pos + move_x;
- const int targ_y = you.y_pos + move_y;
- const unsigned char old_grid = grd[ you.x_pos ][ you.y_pos ];
- const unsigned char targ_grid = grd[ targ_x ][ targ_y ];
- const unsigned char targ_monst = mgrd[ targ_x ][ targ_y ];
-
- if (targ_monst != NON_MONSTER)
- {
- struct monsters *mon = &menv[targ_monst];
-
- if (mons_has_ench( mon, ENCH_SUBMERGED ))
- goto break_out;
-
- // you can swap places with a friendly monster if you
- // can see it and you're not confused
- if (mons_friendly( mon ) && player_monster_visible( mon ) && !you.conf)
- {
- if (!swap_places( mon ))
- moving = false;
-
- goto break_out;
- }
-
- you_attack( targ_monst, true );
- you.turn_is_over = 1;
-
- // we don't want to create a penalty if there isn't
- // supposed to be one
- if (you.berserk_penalty != NO_BERSERK_PENALTY)
- you.berserk_penalty = 0;
-
- attacking = true;
- }
-
- break_out:
- if (targ_grid == DNGN_LAVA && you.duration[DUR_CONDENSATION_SHIELD] > 0)
- {
- mpr("Your icy shield dissipates!", MSGCH_DURATION);
- you.duration[DUR_CONDENSATION_SHIELD] = 0;
- you.redraw_armour_class = 1;
- }
-
- // Handle dangerous tiles
- if ((targ_grid == DNGN_LAVA
- || targ_grid == DNGN_DEEP_WATER
- || targ_grid == DNGN_SHALLOW_WATER)
- && !attacking && !player_is_levitating() && moving)
- {
- // Merfold automatically enter deep water... every other case
- // we ask for confirmation.
- if (you.species == SP_MERFOLK && targ_grid != DNGN_LAVA)
- {
- // Only mention diving if we just entering the water.
- if (!player_in_water())
- {
- mpr("You dive into the water and return to your normal form.");
- merfolk_start_swimming();
- }
- }
- else if (targ_grid != DNGN_SHALLOW_WATER)
- {
- bool enter = yesno("Do you really want to step there?", false, 'n');
-
- if (enter)
- {
- fall_into_a_pool( false, targ_grid );
- you.turn_is_over = 1;
- do_berserk_no_combat_penalty();
- return;
- }
- else
- {
- canned_msg(MSG_OK);
- return;
- }
- }
- }
-
- if (!attacking && targ_grid >= MINMOVE && moving)
- {
- if (targ_grid == DNGN_UNDISCOVERED_TRAP
- && random2(you.skills[SK_TRAPS_DOORS] + 1) > 3)
- {
- strcpy(info, "Wait a moment, ");
- strcat(info, you.your_name);
- strcat(info, "! Do you really want to step there?");
- mpr(info, MSGCH_WARN);
- more();
- you.turn_is_over = 0;
-
- i = trap_at_xy( targ_x, targ_y );
- if (i != -1)
- grd[ targ_x ][ targ_y ] = trap_category(env.trap[i].type);
- return;
- }
-
- you.x_pos += move_x;
- you.y_pos += move_y;
-
- if (targ_grid == DNGN_SHALLOW_WATER && !player_is_levitating())
- {
- if (you.species != SP_MERFOLK)
- {
- if (one_chance_in(3) && !silenced(you.x_pos, you.y_pos))
- {
- mpr("Splash!");
- noisy( 10, you.x_pos, you.y_pos );
- }
-
- you.time_taken *= 13 + random2(8);
- you.time_taken /= 10;
-
- if (old_grid != DNGN_SHALLOW_WATER)
- {
- mpr( "You enter the shallow water. "
- "Moving in this stuff is going to be slow." );
-
- if (you.invis)
- mpr( "And don't expect to remain undetected." );
- }
- }
- else if (old_grid != DNGN_SHALLOW_WATER
- && old_grid != DNGN_DEEP_WATER)
- {
- mpr("You return to your normal form as you enter the water.");
- merfolk_start_swimming();
- }
- }
-
- move_x = 0;
- move_y = 0;
-
- you.time_taken *= player_movement_speed();
- you.time_taken /= 10;
-
- you.turn_is_over = 1;
- item_check(0);
-
- if (targ_grid >= DNGN_TRAP_MECHANICAL
- && targ_grid <= DNGN_UNDISCOVERED_TRAP)
- {
- if (targ_grid == DNGN_UNDISCOVERED_TRAP)
- {
- i = trap_at_xy(you.x_pos, you.y_pos);
- if (i != -1)
- grd[ you.x_pos ][ you.y_pos ] = trap_category(env.trap[i].type);
- trap_known = false;
- }
- else
- {
- trap_known = true;
- }
-
- i = trap_at_xy( you.x_pos, you.y_pos );
- if (i != -1)
- {
- if (player_is_levitating()
- && trap_category(env.trap[i].type) == DNGN_TRAP_MECHANICAL)
- {
- goto out_of_traps; // can fly over mechanical traps
- }
-
- handle_traps(env.trap[i].type, i, trap_known);
- }
- } // end of if another grd == trap
- }
-
- out_of_traps:
- // BCR - Easy doors single move
- if (targ_grid == DNGN_CLOSED_DOOR && (Options.easy_open || you.running < 0))
- open_door(move_x, move_y);
- else if (targ_grid <= MINMOVE)
- {
- stop_running();
- move_x = 0;
- move_y = 0;
- you.turn_is_over = 0;
- }
-
- if (you.running == 2)
- you.running = 1;
-
- if (you.level_type == LEVEL_ABYSS
- && (you.x_pos <= 15 || you.x_pos >= (GXM - 16)
- || you.y_pos <= 15 || you.y_pos >= (GYM - 16)))
- {
- area_shift();
- you.pet_target = MHITNOT;
-
-#if DEBUG_DIAGNOSTICS
- mpr( "Shifting.", MSGCH_DIAGNOSTICS );
- int igly = 0;
- int ig2 = 0;
-
- for (igly = 0; igly < MAX_ITEMS; igly++)
- {
- if (is_valid_item( mitm[igly] ))
- ig2++;
- }
-
- snprintf( info, INFO_SIZE, "Number of items present: %d", ig2 );
- mpr( info, MSGCH_DIAGNOSTICS );
-
- ig2 = 0;
- for (igly = 0; igly < MAX_MONSTERS; igly++)
- {
- if (menv[igly].type != -1)
- ig2++;
- }
-
- snprintf( info, INFO_SIZE, "Number of monsters present: %d", ig2 );
- mpr( info, MSGCH_DIAGNOSTICS );
-
- snprintf( info, INFO_SIZE, "Number of clouds present: %d", env.cloud_no );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
- }
-
- if (!attacking)
- {
- do_berserk_no_combat_penalty();
- }
-} // end move_player()