summaryrefslogtreecommitdiffstats
path: root/stone_soup/crawl-ref/source/player.cc
diff options
context:
space:
mode:
Diffstat (limited to 'stone_soup/crawl-ref/source/player.cc')
-rw-r--r--stone_soup/crawl-ref/source/player.cc4127
1 files changed, 0 insertions, 4127 deletions
diff --git a/stone_soup/crawl-ref/source/player.cc b/stone_soup/crawl-ref/source/player.cc
deleted file mode 100644
index 91ee0dea54..0000000000
--- a/stone_soup/crawl-ref/source/player.cc
+++ /dev/null
@@ -1,4127 +0,0 @@
-/*
- * File: player.cc
- * Summary: Player related functions.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <6> 7/30/99 BWR Added player_spell_levels()
- * <5> 7/13/99 BWR Added player_res_electricity()
- * and player_hunger_rate()
- * <4> 6/22/99 BWR Racial adjustments to stealth and Armour.
- * <3> 5/20/99 BWR Fixed problems with random stat increases, added kobold
- * stat increase. increased EV recovery for Armour.
- * <2> 5/08/99 LRH display_char_status correctly handles magic_contamination.
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "player.h"
-
-#ifdef DOS
-#include <conio.h>
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-#include <ctype.h>
-
-#include "externs.h"
-
-#include "clua.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "items.h"
-#include "macro.h"
-#include "misc.h"
-#include "mon-util.h"
-#include "mutation.h"
-#include "output.h"
-#include "randart.h"
-#include "religion.h"
-#include "skills2.h"
-#include "spl-util.h"
-#include "spells4.h"
-#include "stuff.h"
-#include "transfor.h"
-#include "travel.h"
-#include "view.h"
-#include "wpn-misc.h"
-
-
-/*
- you.duration []: //jmf: obsolete, see enum.h instead
- 0 - liquid flames
- 1 - icy armour
- 2 - repel missiles
- 3 - prayer
- 4 - regeneration
- 5 - vorpal blade
- 6 - fire brand
- 7 - ice brand
- 8 - lethal infusion
- 9 - swiftness
- 10 - insulation
- 11 - stonemail
- 12 - controlled flight
- 13 - teleport
- 14 - control teleport
- 15 - poison weapon
- 16 - resist poison
- 17 - breathe something
- 18 - transformation (duration)
- 19 - death channel
- 20 - deflect missiles
- */
-
-/* attributes
- 0 - resist lightning
- 1 - spec_air
- 2 - spec_earth
- 3 - control teleport
- 4 - walk slowly (eg naga)
- 5 - transformation (form)
- 6 - Nemelex card gift countdown
- 7 - Nemelex has given you a card table
- 8 - How many demonic powers a dspawn has
- */
-
-/* armour list
- 0 - wielded
- 1 - cloak
- 2 - helmet
- 3 - gloves
- 4 - boots
- 5 - shield
- 6 - body armour
- 7 - ring 0
- 8 - ring 1
- 9 - amulet
- */
-
-/* Contains functions which return various player state vars,
- and other stuff related to the player. */
-
-int species_exp_mod(char species);
-void ability_increase(void);
-
-//void priest_spells(int priest_pass[10], char religious); // see actual function for reasoning here {dlb}
-bool player_in_branch( int branch )
-{
- return (you.level_type == LEVEL_DUNGEON && you.where_are_you == branch);
-}
-
-bool player_in_hell( void )
-{
- return (you.level_type == LEVEL_DUNGEON
- && (you.where_are_you >= BRANCH_DIS
- && you.where_are_you <= BRANCH_THE_PIT)
- && you.where_are_you != BRANCH_VESTIBULE_OF_HELL);
-}
-
-bool player_in_water(void)
-{
- return (!player_is_levitating()
- && (grd[you.x_pos][you.y_pos] == DNGN_DEEP_WATER
- || grd[you.x_pos][you.y_pos] == DNGN_SHALLOW_WATER));
-}
-
-bool player_is_swimming(void)
-{
- return (player_in_water() && you.species == SP_MERFOLK);
-}
-
-bool player_under_penance(void)
-{
- if (you.religion != GOD_NO_GOD)
- return (you.penance[you.religion]);
- else
- return (false);
-}
-
-bool player_genus(unsigned char which_genus, unsigned char species)
-{
- if (species == SP_UNKNOWN)
- species = you.species;
-
- switch (species)
- {
- case SP_RED_DRACONIAN:
- case SP_WHITE_DRACONIAN:
- case SP_GREEN_DRACONIAN:
- case SP_GOLDEN_DRACONIAN:
- case SP_GREY_DRACONIAN:
- case SP_BLACK_DRACONIAN:
- case SP_PURPLE_DRACONIAN:
- case SP_MOTTLED_DRACONIAN:
- case SP_PALE_DRACONIAN:
- case SP_UNK0_DRACONIAN:
- case SP_UNK1_DRACONIAN:
- case SP_BASE_DRACONIAN:
- return (which_genus == GENPC_DRACONIAN);
-
- case SP_ELF:
- case SP_HIGH_ELF:
- case SP_GREY_ELF:
- case SP_DEEP_ELF:
- case SP_SLUDGE_ELF:
- return (which_genus == GENPC_ELVEN);
-
- case SP_HILL_DWARF:
- case SP_MOUNTAIN_DWARF:
- return (which_genus == GENPC_DWARVEN);
-
- default:
- break;
- }
-
- return (false);
-} // end player_genus()
-
-bool player_weapon_wielded()
-{
- const int wpn = you.equip[EQ_WEAPON];
-
- if (wpn == -1)
- return (false);
-
- if (you.inv[wpn].base_type != OBJ_WEAPONS
- && you.inv[wpn].base_type != OBJ_STAVES)
- {
- return (false);
- }
-
- // FIXME: This needs to go in eventually.
- /*
- // should never have a bad "shape" weapon in hand
- ASSERT( check_weapon_shape( you.inv[wpn], false ) );
-
- if (!check_weapon_wieldable_size( you.inv[wpn], player_size() ))
- return (false);
- */
-
- return (true);
-}
-
-// Returns the you.inv[] index of our wielded weapon or -1 (no item, not wield)
-int get_player_wielded_item()
-{
- return (you.equip[EQ_WEAPON]);
-}
-
-int get_player_wielded_weapon()
-{
- return (player_weapon_wielded()? get_player_wielded_item() : -1);
-}
-
-// Looks in equipment "slot" to see if there is an equiped "sub_type".
-// Returns number of matches (in the case of rings, both are checked)
-int player_equip( int slot, int sub_type, bool calc_unid )
-{
- int ret = 0;
-
- switch (slot)
- {
- case EQ_WEAPON:
- // Hands can have more than just weapons.
- if (you.equip[EQ_WEAPON] != -1
- && you.inv[you.equip[EQ_WEAPON]].base_type == OBJ_WEAPONS
- && you.inv[you.equip[EQ_WEAPON]].sub_type == sub_type)
- {
- ret++;
- }
- break;
-
- case EQ_STAFF:
- // Like above, but must be magical stave.
- if (you.equip[EQ_WEAPON] != -1
- && you.inv[you.equip[EQ_WEAPON]].base_type == OBJ_STAVES
- && you.inv[you.equip[EQ_WEAPON]].sub_type == sub_type
- && (calc_unid ||
- item_ident(you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_TYPE)))
- {
- ret++;
- }
- break;
-
- case EQ_RINGS:
- if (you.equip[EQ_LEFT_RING] != -1
- && you.inv[you.equip[EQ_LEFT_RING]].sub_type == sub_type
- && (calc_unid ||
- item_type_known(you.inv[you.equip[EQ_LEFT_RING]])))
- {
- ret++;
- }
-
- if (you.equip[EQ_RIGHT_RING] != -1
- && you.inv[you.equip[EQ_RIGHT_RING]].sub_type == sub_type
- && (calc_unid ||
- item_type_known(you.inv[you.equip[EQ_RIGHT_RING]])))
- {
- ret++;
- }
- break;
-
- case EQ_RINGS_PLUS:
- if (you.equip[EQ_LEFT_RING] != -1
- && you.inv[you.equip[EQ_LEFT_RING]].sub_type == sub_type)
- {
- ret += you.inv[you.equip[EQ_LEFT_RING]].plus;
- }
-
- if (you.equip[EQ_RIGHT_RING] != -1
- && you.inv[you.equip[EQ_RIGHT_RING]].sub_type == sub_type)
- {
- ret += you.inv[you.equip[EQ_RIGHT_RING]].plus;
- }
- break;
-
- case EQ_RINGS_PLUS2:
- if (you.equip[EQ_LEFT_RING] != -1
- && you.inv[you.equip[EQ_LEFT_RING]].sub_type == sub_type)
- {
- ret += you.inv[you.equip[EQ_LEFT_RING]].plus2;
- }
-
- if (you.equip[EQ_RIGHT_RING] != -1
- && you.inv[you.equip[EQ_RIGHT_RING]].sub_type == sub_type)
- {
- ret += you.inv[you.equip[EQ_RIGHT_RING]].plus2;
- }
- break;
-
- case EQ_ALL_ARMOUR:
- // doesn't make much sense here... be specific. -- bwr
- break;
-
- default:
- if (you.equip[slot] != -1
- && you.inv[you.equip[slot]].sub_type == sub_type
- && (calc_unid ||
- item_ident(you.inv[you.equip[slot]], ISFLAG_KNOW_TYPE)))
- {
- ret++;
- }
- break;
- }
-
- return (ret);
-}
-
-
-// Looks in equipment "slot" to see if equiped item has "special" ego-type
-// Returns number of matches (jewellery returns zero -- no ego type).
-int player_equip_ego_type( int slot, int special )
-{
- int ret = 0;
- int wpn;
-
- switch (slot)
- {
- case EQ_WEAPON:
- // This actually checks against the "branding", so it will catch
- // randart brands, but not fixed artefacts. -- bwr
-
- // Hands can have more than just weapons.
- wpn = you.equip[EQ_WEAPON];
- if (wpn != -1
- && you.inv[wpn].base_type == OBJ_WEAPONS
- && get_weapon_brand( you.inv[wpn] ) == special)
- {
- ret++;
- }
- break;
-
- case EQ_LEFT_RING:
- case EQ_RIGHT_RING:
- case EQ_AMULET:
- case EQ_STAFF:
- case EQ_RINGS:
- case EQ_RINGS_PLUS:
- case EQ_RINGS_PLUS2:
- // no ego types for these slots
- break;
-
- case EQ_ALL_ARMOUR:
- // Check all armour slots:
- for (int i = EQ_CLOAK; i <= EQ_BODY_ARMOUR; i++)
- {
- if (you.equip[i] != -1
- && get_armour_ego_type( you.inv[you.equip[i]] ) == special)
- {
- ret++;
- }
- }
- break;
-
- default:
- // Check a specific armour slot for an ego type:
- if (you.equip[slot] != -1
- && get_armour_ego_type( you.inv[you.equip[slot]] ) == special)
- {
- ret++;
- }
- break;
- }
-
- return (ret);
-}
-
-int player_damage_type( void )
-{
- const int wpn = you.equip[ EQ_WEAPON ];
-
- if (wpn != -1)
- {
- return (damage_type(you.inv[wpn]));
- }
- else if (you.equip[EQ_GLOVES] == -1 &&
- (you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON
- || you.mutation[MUT_CLAWS]
- || you.species == SP_TROLL
- || you.species == SP_GHOUL))
- {
- return (DVORP_SLICING);
- }
-
- return (DVORP_CRUSHING);
-}
-
-// returns band of player's melee damage
-int player_damage_brand( void )
-{
- int ret = SPWPN_NORMAL;
- const int wpn = you.equip[ EQ_WEAPON ];
-
- if (wpn != -1)
- ret = get_weapon_brand( you.inv[wpn] );
- else if (you.confusing_touch)
- ret = SPWPN_CONFUSE;
- else if (you.mutation[MUT_DRAIN_LIFE])
- ret = SPWPN_DRAINING;
- else
- {
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_SPIDER:
- ret = SPWPN_VENOM;
- break;
-
- case TRAN_ICE_BEAST:
- ret = SPWPN_FREEZING;
- break;
-
- case TRAN_LICH:
- ret = SPWPN_DRAINING;
- break;
-
- default:
- break;
- }
- }
-
- return (ret);
-}
-
-int player_teleport(bool calc_unid)
-{
- int tp = 0;
-
- /* rings */
- tp += 8 * player_equip( EQ_RINGS, RING_TELEPORTATION, calc_unid );
-
- /* mutations */
- tp += you.mutation[MUT_TELEPORT] * 3;
-
- /* randart weapons only */
- if (you.equip[EQ_WEAPON] != -1
- && you.inv[you.equip[EQ_WEAPON]].base_type == OBJ_WEAPONS
- && is_random_artefact( you.inv[you.equip[EQ_WEAPON]] ))
- {
- tp += scan_randarts(RAP_CAUSE_TELEPORTATION, calc_unid);
- }
-
- return tp;
-} // end player_teleport()
-
-int player_regen(void)
-{
- int rr = you.hp_max / 3;
-
- if (rr > 20)
- rr = 20 + ((rr - 20) / 2);
-
- /* rings */
- rr += 40 * player_equip( EQ_RINGS, RING_REGENERATION );
-
- /* spell */
- if (you.duration[DUR_REGENERATION])
- rr += 100;
-
- /* troll or troll leather -- trolls can't get both */
- if (you.species == SP_TROLL)
- rr += 40;
- else if (player_equip( EQ_BODY_ARMOUR, ARM_TROLL_LEATHER_ARMOUR ))
- rr += 30;
-
- /* fast heal mutation */
- rr += you.mutation[MUT_REGENERATION] * 20;
-
- /* ghouls heal slowly */
- // dematerialized people heal slowly
- // dematerialized ghouls shouldn't heal any more slowly -- bwr
- if ((you.species == SP_GHOUL
- && (you.attribute[ATTR_TRANSFORMATION] == TRAN_NONE
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS))
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_AIR)
- {
- rr /= 2;
- }
-
- if (rr < 1)
- rr = 1;
-
- return (rr);
-}
-
-int player_hunger_rate(void)
-{
- int hunger = 3;
-
- // jmf: hunger isn't fair while you can't eat
- // Actually, it is since you can detransform any time you like -- bwr
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_AIR)
- return 0;
-
- switch (you.species)
- {
- case SP_HALFLING:
- case SP_SPRIGGAN:
- hunger--;
- break;
-
- case SP_OGRE:
- case SP_OGRE_MAGE:
- case SP_DEMIGOD:
- hunger++;
- break;
-
- case SP_CENTAUR:
- hunger += 2;
- break;
-
- case SP_TROLL:
- hunger += 6;
- break;
- }
-
- if (you.duration[DUR_REGENERATION] > 0)
- hunger += 4;
-
- // moved here from acr.cc... maintaining the >= 40 behaviour
- if (you.hunger >= 40)
- {
- if (you.invis > 0)
- hunger += 5;
-
- // berserk has its own food penalty -- excluding berserk haste
- if (you.haste > 0 && !you.berserker)
- hunger += 5;
- }
-
- hunger += you.mutation[MUT_FAST_METABOLISM];
-
- if (you.mutation[MUT_SLOW_METABOLISM] > 2)
- hunger -= 2;
- else if (you.mutation[MUT_SLOW_METABOLISM] > 0)
- hunger--;
-
- // rings
- hunger += 2 * player_equip( EQ_RINGS, RING_REGENERATION );
- hunger += 4 * player_equip( EQ_RINGS, RING_HUNGER );
- hunger -= 2 * player_equip( EQ_RINGS, RING_SUSTENANCE );
-
- // weapon ego types
- hunger += 6 * player_equip_ego_type( EQ_WEAPON, SPWPN_VAMPIRICISM );
- hunger += 9 * player_equip_ego_type( EQ_WEAPON, SPWPN_VAMPIRES_TOOTH );
-
- // troll leather armour
- hunger += player_equip( EQ_BODY_ARMOUR, ARM_TROLL_LEATHER_ARMOUR );
-
- // randarts
- hunger += scan_randarts(RAP_METABOLISM);
-
- // burden
- hunger += you.burden_state;
-
- if (hunger < 1)
- hunger = 1;
-
- return (hunger);
-}
-
-int player_spell_levels(void)
-{
- int sl = (you.experience_level - 1) + (you.skills[SK_SPELLCASTING] * 2);
-
- bool fireball = false;
- bool delayed_fireball = false;
-
- if (sl > 99)
- sl = 99;
-
- for (int i = 0; i < 25; i++)
- {
- if (you.spells[i] == SPELL_FIREBALL)
- fireball = true;
- else if (you.spells[i] == SPELL_DELAYED_FIREBALL)
- delayed_fireball = true;
-
- if (you.spells[i] != SPELL_NO_SPELL)
- sl -= spell_difficulty(you.spells[i]);
- }
-
- // Fireball is free for characters with delayed fireball
- if (fireball && delayed_fireball)
- sl += spell_difficulty( SPELL_FIREBALL );
-
- // Note: This can happen because of level drain. Maybe we should
- // force random spells out when that happens. -- bwr
- if (sl < 0)
- sl = 0;
-
- return (sl);
-}
-
-int player_res_magic(void)
-{
- int rm = 0;
-
- switch (you.species)
- {
- default:
- rm = you.experience_level * 3;
- break;
- case SP_HIGH_ELF:
- case SP_GREY_ELF:
- case SP_ELF:
- case SP_SLUDGE_ELF:
- case SP_HILL_DWARF:
- case SP_MOUNTAIN_DWARF:
- rm = you.experience_level * 4;
- break;
- case SP_NAGA:
- rm = you.experience_level * 5;
- break;
- case SP_PURPLE_DRACONIAN:
- case SP_GNOME:
- case SP_DEEP_ELF:
- rm = you.experience_level * 6;
- break;
- case SP_SPRIGGAN:
- rm = you.experience_level * 7;
- break;
- }
-
- /* armour */
- rm += 30 * player_equip_ego_type( EQ_ALL_ARMOUR, SPARM_MAGIC_RESISTANCE );
-
- /* rings of magic resistance */
- rm += 40 * player_equip( EQ_RINGS, RING_PROTECTION_FROM_MAGIC );
-
- /* randarts */
- rm += scan_randarts(RAP_MAGIC);
-
- /* Enchantment skill */
- rm += 2 * you.skills[SK_ENCHANTMENTS];
-
- /* Mutations */
- rm += 30 * you.mutation[MUT_MAGIC_RESISTANCE];
-
- /* transformations */
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_LICH)
- rm += 50;
-
- return rm;
-}
-
-int player_res_fire(bool calc_unid)
-{
- int rf = 0;
-
- /* rings of fire resistance/fire */
- rf += player_equip( EQ_RINGS, RING_PROTECTION_FROM_FIRE, calc_unid );
- rf += player_equip( EQ_RINGS, RING_FIRE, calc_unid );
-
- /* rings of ice */
- rf -= player_equip( EQ_RINGS, RING_ICE, calc_unid );
-
- /* Staves */
- rf += player_equip( EQ_STAFF, STAFF_FIRE, calc_unid );
-
- // body armour:
- rf += 2 * player_equip( EQ_BODY_ARMOUR, ARM_DRAGON_ARMOUR );
- rf += player_equip( EQ_BODY_ARMOUR, ARM_GOLD_DRAGON_ARMOUR );
- rf -= player_equip( EQ_BODY_ARMOUR, ARM_ICE_DRAGON_ARMOUR );
-
- // ego armours
- rf += player_equip_ego_type( EQ_ALL_ARMOUR, SPARM_FIRE_RESISTANCE );
- rf += player_equip_ego_type( EQ_ALL_ARMOUR, SPARM_RESISTANCE );
-
- // randart weapons:
- rf += scan_randarts(RAP_FIRE, calc_unid);
-
- // species:
- if (you.species == SP_MUMMY)
- rf--;
- else if (you.species == SP_RED_DRACONIAN && you.experience_level > 17)
- rf++;
-
- // mutations:
- rf += you.mutation[MUT_HEAT_RESISTANCE];
-
- if (you.fire_shield)
- rf += 2;
-
- // transformations:
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_ICE_BEAST:
- rf--;
- break;
- case TRAN_DRAGON:
- rf += 2;
- break;
- case TRAN_SERPENT_OF_HELL:
- rf += 2;
- break;
- case TRAN_AIR:
- rf -= 2;
- break;
- }
-
- if (rf < -3)
- rf = -3;
- else if (rf > 3)
- rf = 3;
-
- return (rf);
-}
-
-int player_res_cold(bool calc_unid)
-{
- int rc = 0;
-
- /* rings of fire resistance/fire */
- rc += player_equip( EQ_RINGS, RING_PROTECTION_FROM_COLD, calc_unid );
- rc += player_equip( EQ_RINGS, RING_ICE, calc_unid );
-
- /* rings of ice */
- rc -= player_equip( EQ_RINGS, RING_FIRE, calc_unid );
-
- /* Staves */
- rc += player_equip( EQ_STAFF, STAFF_COLD, calc_unid );
-
- // body armour:
- rc += 2 * player_equip( EQ_BODY_ARMOUR, ARM_ICE_DRAGON_ARMOUR );
- rc += player_equip( EQ_BODY_ARMOUR, ARM_GOLD_DRAGON_ARMOUR );
- rc -= player_equip( EQ_BODY_ARMOUR, ARM_DRAGON_ARMOUR );
-
- // ego armours
- rc += player_equip_ego_type( EQ_ALL_ARMOUR, SPARM_COLD_RESISTANCE );
- rc += player_equip_ego_type( EQ_ALL_ARMOUR, SPARM_RESISTANCE );
-
- // randart weapons:
- rc += scan_randarts(RAP_COLD, calc_unid);
-
- // species:
- if (you.species == SP_MUMMY || you.species == SP_GHOUL)
- rc++;
- else if (you.species == SP_WHITE_DRACONIAN && you.experience_level > 17)
- rc++;
-
- // mutations:
- rc += you.mutation[MUT_COLD_RESISTANCE];
-
- if (you.fire_shield)
- rc -= 2;
-
- // transformations:
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_ICE_BEAST:
- rc += 3;
- break;
- case TRAN_DRAGON:
- rc--;
- break;
- case TRAN_LICH:
- rc++;
- break;
- case TRAN_AIR:
- rc -= 2;
- break;
- }
-
- if (rc < -3)
- rc = -3;
- else if (rc > 3)
- rc = 3;
-
- return (rc);
-}
-
-int player_res_acid( void )
-{
- return (!transform_changed_physiology()
- && ((you.species == SP_GOLDEN_DRACONIAN
- && you.experience_level >= 7)
- || you.mutation[MUT_YELLOW_SCALES] == 3));
-}
-
-int player_res_electricity(bool calc_unid)
-{
- int re = 0;
-
- if (you.duration[DUR_INSULATION])
- re++;
-
- // staff
- re += player_equip( EQ_STAFF, STAFF_AIR, calc_unid );
-
- // body armour:
- re += player_equip( EQ_BODY_ARMOUR, ARM_STORM_DRAGON_ARMOUR );
-
- // randart weapons:
- re += scan_randarts(RAP_ELECTRICITY, calc_unid);
-
- // species:
- if (you.species == SP_BLACK_DRACONIAN && you.experience_level > 17)
- re++;
-
- // mutations:
- if (you.mutation[MUT_SHOCK_RESISTANCE])
- re++;
-
- // transformations:
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_STATUE)
- re += 1;
-
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_AIR)
- re += 2; // mutliple levels currently meaningless
-
- if (you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION] > 0)
- re = 3;
- else if (re > 1)
- re = 1;
-
- return (re);
-} // end player_res_electricity()
-
-// Does the player resist asphyxiation?
-bool player_res_asphyx()
-{
- // The undead are immune to asphyxiation, or so we'll assume.
- if (you.is_undead)
- return (true);
-
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_LICH:
- case TRAN_STATUE:
- case TRAN_SERPENT_OF_HELL:
- case TRAN_AIR:
- return (true);
- }
- return (false);
-}
-
-// funny that no races are susceptible to poisons {dlb}
-int player_res_poison(bool calc_unid)
-{
- int rp = 0;
-
- /* rings of poison resistance */
- rp += player_equip( EQ_RINGS, RING_POISON_RESISTANCE, calc_unid );
-
- /* Staves */
- rp += player_equip( EQ_STAFF, STAFF_POISON, calc_unid );
-
- /* the staff of Olgreb: */
- if (you.equip[EQ_WEAPON] != -1
- && you.inv[you.equip[EQ_WEAPON]].base_type == OBJ_WEAPONS
- && you.inv[you.equip[EQ_WEAPON]].special == SPWPN_STAFF_OF_OLGREB)
- {
- rp++;
- }
-
- // ego armour:
- rp += player_equip_ego_type( EQ_ALL_ARMOUR, SPARM_POISON_RESISTANCE );
-
- // body armour:
- rp += player_equip( EQ_BODY_ARMOUR, ARM_GOLD_DRAGON_ARMOUR );
- rp += player_equip( EQ_BODY_ARMOUR, ARM_SWAMP_DRAGON_ARMOUR );
-
- // spells:
- if (you.duration[DUR_RESIST_POISON] > 0)
- rp++;
-
- // randart weapons:
- rp += scan_randarts(RAP_POISON, calc_unid);
-
- // species:
- if (you.species == SP_MUMMY || you.species == SP_NAGA
- || you.species == SP_GHOUL
- || (you.species == SP_GREEN_DRACONIAN && you.experience_level > 6))
- {
- rp++;
- }
-
- // mutations:
- rp += you.mutation[MUT_POISON_RESISTANCE];
-
- // transformations:
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_LICH:
- case TRAN_ICE_BEAST:
- case TRAN_STATUE:
- case TRAN_DRAGON:
- case TRAN_SERPENT_OF_HELL:
- case TRAN_AIR:
- rp++;
- break;
- }
-
- if (rp > 3)
- rp = 3;
-
- return (rp);
-} // end player_res_poison()
-
-unsigned char player_spec_death(void)
-{
- int sd = 0;
-
- /* Staves */
- sd += player_equip( EQ_STAFF, STAFF_DEATH );
-
- // body armour:
- if (player_equip_ego_type( EQ_BODY_ARMOUR, SPARM_ARCHMAGI ))
- sd++;
-
- // species:
- if (you.species == SP_MUMMY)
- {
- if (you.experience_level >= 13)
- sd++;
- if (you.experience_level >= 26)
- sd++;
- }
-
- // transformations:
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_LICH)
- sd++;
-
- return sd;
-}
-
-unsigned char player_spec_holy(void)
-{
- //if ( you.char_class == JOB_PRIEST || you.char_class == JOB_PALADIN )
- // return 1;
- return 0;
-}
-
-unsigned char player_spec_fire(void)
-{
- int sf = 0;
-
- // staves:
- sf += player_equip( EQ_STAFF, STAFF_FIRE );
-
- // rings of fire:
- sf += player_equip( EQ_RINGS, RING_FIRE );
-
- if (you.fire_shield)
- sf++;
-
- return sf;
-}
-
-unsigned char player_spec_cold(void)
-{
- int sc = 0;
-
- // staves:
- sc += player_equip( EQ_STAFF, STAFF_COLD );
-
- // rings of ice:
- sc += player_equip( EQ_RINGS, RING_ICE );
-
- return sc;
-}
-
-unsigned char player_spec_earth(void)
-{
- int se = 0;
-
- /* Staves */
- se += player_equip( EQ_STAFF, STAFF_EARTH );
-
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_AIR)
- se--;
-
- return se;
-}
-
-unsigned char player_spec_air(void)
-{
- int sa = 0;
-
- /* Staves */
- sa += player_equip( EQ_STAFF, STAFF_AIR );
-
- //jmf: this was too good
- //if (you.attribute[ATTR_TRANSFORMATION] == TRAN_AIR)
- // sa++;
- return sa;
-}
-
-unsigned char player_spec_conj(void)
-{
- int sc = 0;
-
- /* Staves */
- sc += player_equip( EQ_STAFF, STAFF_CONJURATION );
-
- // armour of the Archmagi
- if (player_equip_ego_type( EQ_BODY_ARMOUR, SPARM_ARCHMAGI ))
- sc++;
-
- return sc;
-}
-
-unsigned char player_spec_ench(void)
-{
- int se = 0;
-
- /* Staves */
- se += player_equip( EQ_STAFF, STAFF_ENCHANTMENT );
-
- // armour of the Archmagi
- if (player_equip_ego_type( EQ_BODY_ARMOUR, SPARM_ARCHMAGI ))
- se++;
-
- return se;
-}
-
-unsigned char player_spec_summ(void)
-{
- int ss = 0;
-
- /* Staves */
- ss += player_equip( EQ_STAFF, STAFF_SUMMONING );
-
- // armour of the Archmagi
- if (player_equip_ego_type( EQ_BODY_ARMOUR, SPARM_ARCHMAGI ))
- ss++;
-
- return ss;
-}
-
-unsigned char player_spec_poison(void)
-{
- int sp = 0;
-
- /* Staves */
- sp += player_equip( EQ_STAFF, STAFF_POISON );
-
- if (you.equip[EQ_WEAPON] != -1
- && you.inv[you.equip[EQ_WEAPON]].base_type == OBJ_WEAPONS
- && you.inv[you.equip[EQ_WEAPON]].special == SPWPN_STAFF_OF_OLGREB)
- {
- sp++;
- }
-
- return sp;
-}
-
-unsigned char player_energy(void)
-{
- unsigned char pe = 0;
-
- // Staves
- pe += player_equip( EQ_STAFF, STAFF_ENERGY );
-
- return pe;
-}
-
-int player_prot_life(bool calc_unid)
-{
- int pl = 0;
-
- // rings
- pl += player_equip( EQ_RINGS, RING_LIFE_PROTECTION, calc_unid );
-
- // armour: (checks body armour only)
- pl += player_equip_ego_type( EQ_ALL_ARMOUR, SPARM_POSITIVE_ENERGY );
-
- if (you.is_undead)
- pl += 3;
-
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_STATUE:
- pl += 1;
- break;
-
- case TRAN_SERPENT_OF_HELL:
- pl += 2;
- break;
-
- case TRAN_LICH:
- pl += 3;
- break;
-
- default:
- break;
- }
-
- // randart wpns
- pl += scan_randarts(RAP_NEGATIVE_ENERGY, calc_unid);
-
- // demonic power
- pl += you.mutation[MUT_NEGATIVE_ENERGY_RESISTANCE];
-
- if (pl > 3)
- pl = 3;
-
- return (pl);
-}
-
-// New player movement speed system... allows for a bit more that
-// "player runs fast" and "player walks slow" in that the speed is
-// actually calculated (allowing for centaurs to get a bonus from
-// swiftness and other such things). Levels of the mutation now
-// also have meaning (before they all just meant fast). Most of
-// this isn't as fast as it used to be (6 for having anything), but
-// even a slight speed advantage is very good... and we certainly don't
-// want to go past 6 (see below). -- bwr
-int player_movement_speed(void)
-{
- int mv = 10;
-
- if (you.species == SP_MERFOLK && player_is_swimming())
- {
- // This is swimming... so it doesn't make sense to really
- // apply the other things (the mutation is "cover ground",
- // swiftness is an air spell, can't wear boots, can't be
- // transformed).
- mv = 6;
- }
- else
- {
- /* transformations */
- if (!player_is_shapechanged())
- {
- // Centaurs and spriggans are only fast in their regular
- // shape (ie untransformed, blade hands, lich form)
- if (you.species == SP_CENTAUR)
- mv = 8;
- else if (you.species == SP_SPRIGGAN)
- mv = 6;
- }
- else if (you.attribute[ATTR_TRANSFORMATION] == TRAN_SPIDER)
- mv = 8;
-
- /* armour */
- if (player_equip_ego_type( EQ_BOOTS, SPARM_RUNNING ))
- mv -= 2;
-
- if (player_equip_ego_type( EQ_BODY_ARMOUR, SPARM_PONDEROUSNESS ))
- mv += 2;
-
- // Swiftness is an Air spell, it doesn't work in water...
- // but levitating players will move faster. -- bwr
- if (you.duration[DUR_SWIFTNESS] > 0 && !player_in_water())
- mv -= (player_is_levitating() ? 4 : 2);
-
- /* Mutations: -2, -3, -4 */
- if (you.mutation[MUT_FAST] > 0)
- mv -= (you.mutation[MUT_FAST] + 1);
-
- // Burden
- if (you.burden_state == BS_ENCUMBERED)
- mv += 1;
- else if (you.burden_state == BS_OVERLOADED)
- mv += 3;
- }
-
- // We'll use the old value of six as a minimum, with haste this could
- // end up as a speed of three, which is about as fast as we want
- // the player to be able to go (since 3 is 3.33x as fast and 2 is 5x,
- // which is a bit of a jump, and a bit too fast) -- bwr
- if (mv < 6)
- mv = 6;
-
- // Nagas move slowly:
- if (you.species == SP_NAGA && !player_is_shapechanged())
- {
- mv *= 14;
- mv /= 10;
- }
-
- return (mv);
-}
-
-// This function differs from the above in that it's used to set the
-// initial time_taken value for the turn. Everything else (movement,
-// spellcasting, combat) applies a ratio to this value.
-int player_speed(void)
-{
- int ps = 10;
-
- if (you.haste)
- ps /= 2;
-
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_STATUE:
- ps *= 15;
- ps /= 10;
- break;
-
- case TRAN_SERPENT_OF_HELL:
- ps *= 12;
- ps /= 10;
- break;
-
- default:
- break;
- }
-
- return ps;
-}
-
-int player_AC(void)
-{
- int AC = 0;
- int i; // loop variable
-
- // get the armour race value that corresponds to the character's race:
- const unsigned long racial_type
- = ((player_genus(GENPC_DWARVEN)) ? ISFLAG_DWARVEN :
- (player_genus(GENPC_ELVEN)) ? ISFLAG_ELVEN :
- (you.species == SP_HILL_ORC) ? ISFLAG_ORCISH
- : 0);
-
- for (i = EQ_CLOAK; i <= EQ_BODY_ARMOUR; i++)
- {
- const int item = you.equip[i];
-
- if (item == -1 || i == EQ_SHIELD)
- continue;
-
- AC += you.inv[ item ].plus;
-
- // Note that helms and boots have a sub-sub classing system
- // which uses "plus2"... since not all members have the same
- // AC value, we use special cases. -- bwr
- if (i == EQ_HELMET
- && (get_helmet_type(you.inv[ item ]) == THELM_CAP
- || get_helmet_type(you.inv[ item ]) == THELM_WIZARD_HAT
- || get_helmet_type(you.inv[ item ]) == THELM_SPECIAL))
- {
- continue;
- }
-
- int racial_bonus = 0; // additional levels of armour skill
- const unsigned long armour_race = get_equip_race( you.inv[ item ] );
- const int ac_value = property( you.inv[ item ], PARM_AC );
-
- // Dwarven armour is universally good -- bwr
- if (armour_race == ISFLAG_DWARVEN)
- racial_bonus += 2;
-
- if (racial_type && armour_race == racial_type)
- {
- // Elven armour is light, but still gives one level
- // to elves. Orcish and Dwarven armour are worth +2
- // to the correct species, plus the plus that anyone
- // gets with dwarven armour. -- bwr
-
- if (racial_type == ISFLAG_ELVEN)
- racial_bonus++;
- else
- racial_bonus += 2;
- }
-
- AC += ac_value * (15 + you.skills[SK_ARMOUR] + racial_bonus) / 15;
-
- /* Nagas/Centaurs/the deformed don't fit into body armour very well */
- if ((you.species == SP_NAGA || you.species == SP_CENTAUR
- || you.mutation[MUT_DEFORMED] > 0) && i == EQ_BODY_ARMOUR)
- {
- AC -= ac_value / 2;
- }
- }
-
- AC += player_equip( EQ_RINGS_PLUS, RING_PROTECTION );
-
- if (player_equip_ego_type( EQ_WEAPON, SPWPN_PROTECTION ))
- AC += 5;
-
- if (player_equip_ego_type( EQ_SHIELD, SPARM_PROTECTION ))
- AC += 3;
-
- AC += scan_randarts(RAP_AC);
-
- if (you.duration[DUR_ICY_ARMOUR])
- AC += 4 + you.skills[SK_ICE_MAGIC] / 3; // max 13
-
- if (you.duration[DUR_STONEMAIL])
- AC += 5 + you.skills[SK_EARTH_MAGIC] / 2; // max 18
-
- if (you.duration[DUR_STONESKIN])
- AC += 2 + you.skills[SK_EARTH_MAGIC] / 5; // max 7
-
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_NONE
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_LICH
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS)
- {
- // Being a lich doesn't preclude the benefits of hide/scales -- bwr
- //
- // Note: Even though necromutation is a high level spell, it does
- // allow the character full armour (so the bonus is low). -- bwr
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_LICH)
- AC += (3 + you.skills[SK_NECROMANCY] / 6); // max 7
-
- //jmf: only give:
- if (player_genus(GENPC_DRACONIAN))
- {
- if (you.experience_level < 8)
- AC += 2;
- else if (you.species == SP_GREY_DRACONIAN)
- AC += 1 + (you.experience_level - 4) / 2; // max 12
- else
- AC += 1 + (you.experience_level / 4); // max 7
- }
- else
- {
- switch (you.species)
- {
- case SP_NAGA:
- AC += you.experience_level / 3; // max 9
- break;
-
- case SP_OGRE:
- AC++;
- break;
-
- case SP_TROLL:
- case SP_CENTAUR:
- AC += 3;
- break;
-
- default:
- break;
- }
- }
-
- // Scales -- some evil uses of the fact that boolean "true" == 1...
- // I'll spell things out with some comments -- bwr
-
- // mutations:
- // these give: +1, +2, +3
- AC += you.mutation[MUT_TOUGH_SKIN];
- AC += you.mutation[MUT_GREY_SCALES];
- AC += you.mutation[MUT_SPECKLED_SCALES];
- AC += you.mutation[MUT_IRIDESCENT_SCALES];
- AC += you.mutation[MUT_PATTERNED_SCALES];
- AC += you.mutation[MUT_BLUE_SCALES];
-
- // these gives: +1, +3, +5
- if (you.mutation[MUT_GREEN_SCALES] > 0)
- AC += (you.mutation[MUT_GREEN_SCALES] * 2) - 1;
- if (you.mutation[MUT_NACREOUS_SCALES] > 0)
- AC += (you.mutation[MUT_NACREOUS_SCALES] * 2) - 1;
- if (you.mutation[MUT_BLACK2_SCALES] > 0)
- AC += (you.mutation[MUT_BLACK2_SCALES] * 2) - 1;
- if (you.mutation[MUT_WHITE_SCALES] > 0)
- AC += (you.mutation[MUT_WHITE_SCALES] * 2) - 1;
-
- // these give: +2, +4, +6
- AC += you.mutation[MUT_GREY2_SCALES] * 2;
- AC += you.mutation[MUT_YELLOW_SCALES] * 2;
- AC += you.mutation[MUT_PURPLE_SCALES] * 2;
-
- // black gives: +3, +6, +9
- AC += you.mutation[MUT_BLACK_SCALES] * 3;
-
- // boney plates give: +2, +3, +4
- if (you.mutation[MUT_BONEY_PLATES] > 0)
- AC += you.mutation[MUT_BONEY_PLATES] + 1;
-
- // red gives +1, +2, +4
- AC += you.mutation[MUT_RED_SCALES]
- + (you.mutation[MUT_RED_SCALES] == 3);
-
- // indigo gives: +2, +3, +5
- if (you.mutation[MUT_INDIGO_SCALES] > 0)
- {
- AC += 1 + you.mutation[MUT_INDIGO_SCALES]
- + (you.mutation[MUT_INDIGO_SCALES] == 3);
- }
-
- // brown gives: +2, +4, +5
- AC += (you.mutation[MUT_BROWN_SCALES] * 2)
- - (you.mutation[MUT_METALLIC_SCALES] == 3);
-
- // orange gives: +1, +3, +4
- AC += you.mutation[MUT_ORANGE_SCALES]
- + (you.mutation[MUT_ORANGE_SCALES] > 1);
-
- // knobbly red gives: +2, +5, +7
- AC += (you.mutation[MUT_RED2_SCALES] * 2)
- + (you.mutation[MUT_RED2_SCALES] > 1);
-
- // metallic gives +3, +7, +10
- AC += you.mutation[MUT_METALLIC_SCALES] * 3
- + (you.mutation[MUT_METALLIC_SCALES] > 1);
- }
- else
- {
- // transformations:
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_NONE:
- case TRAN_BLADE_HANDS:
- case TRAN_LICH: // can wear normal body armour (small bonus)
- break;
-
-
- case TRAN_SPIDER: // low level (small bonus), also gets EV
- AC += (2 + you.skills[SK_POISON_MAGIC] / 6); // max 6
- break;
-
- case TRAN_ICE_BEAST:
- AC += (5 + (you.skills[SK_ICE_MAGIC] + 1) / 4); // max 12
-
- if (you.duration[DUR_ICY_ARMOUR])
- AC += (1 + you.skills[SK_ICE_MAGIC] / 4); // max +7
- break;
-
- case TRAN_DRAGON:
- AC += (7 + you.skills[SK_FIRE_MAGIC] / 3); // max 16
- break;
-
- case TRAN_STATUE: // main ability is armour (high bonus)
- AC += (17 + you.skills[SK_EARTH_MAGIC] / 2); // max 30
-
- if (you.duration[DUR_STONESKIN] || you.duration[DUR_STONEMAIL])
- AC += (1 + you.skills[SK_EARTH_MAGIC] / 4); // max +7
- break;
-
- case TRAN_SERPENT_OF_HELL:
- AC += (10 + you.skills[SK_FIRE_MAGIC] / 3); // max 19
- break;
-
- case TRAN_AIR: // air - scales & species ought to be irrelevent
- AC = (you.skills[SK_AIR_MAGIC] * 3) / 2; // max 40
- break;
-
- default:
- break;
- }
- }
-
- return AC;
-}
-
-bool is_light_armour( const item_def &item )
-{
- if (get_equip_race(item) == ISFLAG_ELVEN)
- return (true);
-
- switch (item.sub_type)
- {
- case ARM_ROBE:
- case ARM_ANIMAL_SKIN:
- case ARM_LEATHER_ARMOUR:
- case ARM_STEAM_DRAGON_HIDE:
- case ARM_STEAM_DRAGON_ARMOUR:
- case ARM_MOTTLED_DRAGON_HIDE:
- case ARM_MOTTLED_DRAGON_ARMOUR:
- //case ARM_TROLL_HIDE: //jmf: these are knobbly and stiff
- //case ARM_TROLL_LEATHER_ARMOUR:
- return (true);
-
- default:
- return (false);
- }
-}
-
-bool player_light_armour(void)
-{
- if (you.equip[EQ_BODY_ARMOUR] == -1)
- return true;
-
- return (is_light_armour( you.inv[you.equip[EQ_BODY_ARMOUR]] ));
-} // end player_light_armour()
-
-//
-// This function returns true if the player has a radically different
-// shape... minor changes like blade hands don't count, also note
-// that lich transformation doesn't change the character's shape
-// (so we end up with Naga-lichs, Spiggan-lichs, Minotaur-lichs)
-// it just makes the character undead (with the benefits that implies). --bwr
-//
-bool player_is_shapechanged(void)
-{
- if (you.attribute[ATTR_TRANSFORMATION] == TRAN_NONE
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_LICH)
- {
- return (false);
- }
-
- return (true);
-}
-
-int player_evasion(void)
-{
- int ev = 10;
-
- int armour_ev_penalty;
-
- if (you.equip[EQ_BODY_ARMOUR] == -1)
- armour_ev_penalty = 0;
- else
- {
- armour_ev_penalty = property( you.inv[you.equip[EQ_BODY_ARMOUR]],
- PARM_EVASION );
- }
-
- // We return 2 here to give the player some chance of not being hit,
- // repulsion fields still work while paralysed
- if (you.paralysis)
- return (2 + you.mutation[MUT_REPULSION_FIELD] * 2);
-
- if (you.species == SP_CENTAUR)
- ev -= 3;
-
- if (you.equip[EQ_BODY_ARMOUR] != -1)
- {
- int ev_change = 0;
-
- ev_change = armour_ev_penalty;
- ev_change += you.skills[SK_ARMOUR] / 3;
-
- if (ev_change > armour_ev_penalty / 3)
- ev_change = armour_ev_penalty / 3;
-
- ev += ev_change; /* remember that it's negative */
- }
-
- ev += player_equip( EQ_RINGS_PLUS, RING_EVASION );
-
- if (player_equip_ego_type( EQ_BODY_ARMOUR, SPARM_PONDEROUSNESS ))
- ev -= 2;
-
- if (you.duration[DUR_STONEMAIL])
- ev -= 2;
-
- if (you.duration[DUR_FORESCRY])
- ev += 8; //jmf: is this a reasonable value?
-
- int emod = 0;
-
- if (!player_light_armour())
- {
- // meaning that the armour evasion modifier is often effectively
- // applied twice, but not if you're wearing elven armour
- emod += (armour_ev_penalty * 14) / 10;
- }
-
- emod += you.skills[SK_DODGING] / 2;
-
- if (emod > 0)
- ev += emod;
-
- if (you.mutation[MUT_REPULSION_FIELD] > 0)
- ev += (you.mutation[MUT_REPULSION_FIELD] * 2) - 1;
-
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_DRAGON:
- ev -= 3;
- break;
-
- case TRAN_STATUE:
- case TRAN_SERPENT_OF_HELL:
- ev -= 5;
- break;
-
- case TRAN_SPIDER:
- ev += 3;
- break;
-
- case TRAN_AIR:
- ev += 20;
- break;
-
- default:
- break;
- }
-
- ev += scan_randarts(RAP_EVASION);
-
- return ev;
-} // end player_evasion()
-
-int player_magical_power( void )
-{
- int ret = 0;
-
- ret += 13 * player_equip( EQ_STAFF, STAFF_POWER );
- ret += 9 * player_equip( EQ_RINGS, RING_MAGICAL_POWER );
-
- return (ret);
-}
-
-int player_mag_abil(bool is_weighted)
-{
- int ma = 0;
-
- ma += 3 * player_equip( EQ_RINGS, RING_WIZARDRY );
-
- /* Staves */
- ma += 4 * player_equip( EQ_STAFF, STAFF_WIZARDRY );
-
- /* armour of the Archmagi (checks body armour only) */
- ma += 2 * player_equip_ego_type( EQ_BODY_ARMOUR, SPARM_ARCHMAGI );
-
- return ((is_weighted) ? ((ma * you.intel) / 10) : ma);
-} // end player_mag_abil()
-
-int player_shield_class(void) //jmf: changes for new spell
-{
- int base_shield = 0;
- const int shield = you.equip[EQ_SHIELD];
-
- if (shield == -1)
- {
- if (!you.fire_shield && you.duration[DUR_CONDENSATION_SHIELD])
- base_shield = 2 + (you.skills[SK_ICE_MAGIC] / 6); // max 6
- else
- return (0);
- }
- else
- {
- switch (you.inv[ shield ].sub_type)
- {
- case ARM_BUCKLER:
- base_shield = 3; // +3/20 per skill level max 7
- break;
- case ARM_SHIELD:
- base_shield = 5; // +5/20 per skill level max 11
- break;
- case ARM_LARGE_SHIELD:
- base_shield = 7; // +7/20 per skill level max 16
- break;
- }
-
- // bonus applied only to base, see above for effect:
- base_shield *= (20 + you.skills[SK_SHIELDS]);
- base_shield /= 20;
-
- base_shield += you.inv[ shield ].plus;
- }
-
- return (base_shield);
-} // end player_shield_class()
-
-unsigned char player_see_invis(bool calc_unid)
-{
- unsigned char si = 0;
-
- si += player_equip( EQ_RINGS, RING_SEE_INVISIBLE, calc_unid );
-
- /* armour: (checks head armour only) */
- si += player_equip_ego_type( EQ_HELMET, SPARM_SEE_INVISIBLE );
-
- /* Nagas & Spriggans have good eyesight */
- if (you.species == SP_NAGA || you.species == SP_SPRIGGAN)
- si++;
-
- if (you.mutation[MUT_ACUTE_VISION] > 0)
- si += you.mutation[MUT_ACUTE_VISION];
-
- //jmf: added see_invisible spell
- if (you.duration[DUR_SEE_INVISIBLE] > 0)
- si++;
-
- /* randart wpns */
- int artefacts = scan_randarts(RAP_EYESIGHT, calc_unid);
-
- if (artefacts > 0)
- si += artefacts;
-
- return si;
-}
-
-// This does NOT do line of sight! It checks the monster's visibility
-// with repect to the players perception, but doesn't do walls or range...
-// to find if the square the monster is in is visible see mons_near().
-bool player_monster_visible( const monsters *mon )
-{
- if (mons_has_ench( mon, ENCH_SUBMERGED )
- || (mons_has_ench( mon, ENCH_INVIS ) && !player_see_invis()))
- {
- return (false);
- }
-
- return (true);
-}
-
-unsigned char player_sust_abil(bool calc_unid)
-{
- unsigned char sa = 0;
-
- sa += player_equip( EQ_RINGS, RING_SUSTAIN_ABILITIES, calc_unid );
-
- return sa;
-} // end player_sust_abil()
-
-int carrying_capacity(void)
-{
- // Originally: 1000 + you.strength * 200 + ( you.levitation ? 1000 : 0 )
- return (3500 + (you.strength * 100) + (player_is_levitating() ? 1000 : 0));
-}
-
-int burden_change(void)
-{
- char old_burdenstate = you.burden_state;
-
- you.burden = 0;
-
- int max_carried = carrying_capacity();
-
- if (you.duration[DUR_STONEMAIL])
- you.burden += 800;
-
- for (unsigned char bu = 0; bu < ENDOFPACK; bu++)
- {
- if (you.inv[bu].quantity < 1)
- continue;
-
- if (you.inv[bu].base_type == OBJ_CORPSES)
- {
- if (you.inv[bu].sub_type == CORPSE_BODY)
- you.burden += mons_weight(you.inv[bu].plus);
- else if (you.inv[bu].sub_type == CORPSE_SKELETON)
- you.burden += mons_weight(you.inv[bu].plus) / 2;
- }
- else
- {
- you.burden += item_mass( you.inv[bu] ) * you.inv[bu].quantity;
- }
- }
-
- you.burden_state = BS_UNENCUMBERED;
- set_redraw_status( REDRAW_BURDEN );
-
- // changed the burdened levels to match the change to max_carried
- if (you.burden < (max_carried * 5) / 6)
- // (you.burden < max_carried - 1000)
- {
- you.burden_state = BS_UNENCUMBERED;
-
- // this message may have to change, just testing {dlb}
- if (old_burdenstate != you.burden_state)
- mpr("Your possessions no longer seem quite so burdensome.");
- }
- else if (you.burden < (max_carried * 11) / 12)
- // (you.burden < max_carried - 500)
- {
- you.burden_state = BS_ENCUMBERED;
-
- if (old_burdenstate != you.burden_state)
- mpr("You are being weighed down by all of your possessions.");
- }
- else
- {
- you.burden_state = BS_OVERLOADED;
-
- if (old_burdenstate != you.burden_state)
- mpr("You are being crushed by all of your possessions.");
- }
-
- // Stop travel if we get burdened (as from potions of might/levitation
- // wearing off).
- if (you.burden_state > old_burdenstate)
- interrupt_activity( AI_BURDEN_CHANGE );
-
- return you.burden;
-} // end burden_change()
-
-bool you_resist_magic(int power)
-{
- int ench_power = stepdown_value( power, 30, 40, 100, 120 );
-
- int mrchance = 100 + player_res_magic();
-
- mrchance -= ench_power;
-
- int mrch2 = random2(100) + random2(101);
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "Power: %d, player's MR: %d, target: %d, roll: %d",
- ench_power, player_res_magic(), mrchance, mrch2 );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (mrch2 < mrchance)
- return true; // ie saved successfully
-
- return false;
-/* if (random2(power) / 3 + random2(power) / 3 + random2(power) / 3 >= player_res_magic()) return 0;
- return 1; */
-}
-
-void forget_map(unsigned char chance_forgotten)
-{
- unsigned char xcount, ycount = 0;
-
- for (xcount = 0; xcount < GXM; xcount++)
- {
- for (ycount = 0; ycount < GYM; ycount++)
- {
- if (random2(100) < chance_forgotten)
- {
- env.map[xcount][ycount] = 0;
- }
- }
- }
-} // end forget_map()
-
-void gain_exp( unsigned int exp_gained )
-{
-
- if (player_equip_ego_type( EQ_BODY_ARMOUR, SPARM_ARCHMAGI )
- && !one_chance_in(20))
- {
- return;
- }
-
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE, "gain_exp: %d", exp_gained );
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif
-
- if (you.experience + exp_gained > 8999999)
- you.experience = 8999999;
- else
- you.experience += exp_gained;
-
- if (you.exp_available + exp_gained > 20000)
- you.exp_available = 20000;
- else
- you.exp_available += exp_gained;
-
- level_change();
-} // end gain_exp()
-
-void level_change(void)
-{
- int hp_adjust = 0;
- int mp_adjust = 0;
-
- // necessary for the time being, as level_change() is called
- // directly sometimes {dlb}
- you.redraw_experience = 1;
-
- while (you.experience_level < 27
- && you.experience > exp_needed(you.experience_level + 2))
- {
- you.experience_level++;
-
- if (you.experience_level <= you.max_level)
- {
- snprintf( info, INFO_SIZE, "Welcome back to level %d!",
- you.experience_level );
-
- mpr(info, MSGCH_INTRINSIC_GAIN);
- more();
-
- // Gain back the hp and mp we lose in lose_level(). -- bwr
- inc_hp( 4, true );
- inc_mp( 1, true );
- }
- else // character has gained a new level
- {
- snprintf( info, INFO_SIZE, "You are now a level %d %s!",
- you.experience_level, you.class_name );
-
- mpr(info, MSGCH_INTRINSIC_GAIN);
- more();
-
- int brek = 0;
-
- if (you.experience_level > 21)
- brek = (coinflip() ? 3 : 2);
- else if (you.experience_level > 12)
- brek = 3 + random2(3); // up from 2 + rand(3) -- bwr
- else
- brek = 4 + random2(4); // up from 3 + rand(4) -- bwr
-
- inc_hp( brek, true );
- inc_mp( 1, true );
-
- if (!(you.experience_level % 3))
- ability_increase();
-
- switch (you.species)
- {
- case SP_HUMAN:
- if (!(you.experience_level % 5))
- modify_stat(STAT_RANDOM, 1, false);
- break;
-
- case SP_ELF:
- if (you.experience_level % 3)
- hp_adjust--;
- else
- mp_adjust++;
-
- if (!(you.experience_level % 4))
- {
- modify_stat( (coinflip() ? STAT_INTELLIGENCE
- : STAT_DEXTERITY), 1, false );
- }
- break;
-
- case SP_HIGH_ELF:
- if (you.experience_level == 15)
- {
- //jmf: got Glamour ability
- mpr("You feel charming!", MSGCH_INTRINSIC_GAIN);
- }
-
- if (you.experience_level % 3)
- hp_adjust--;
-
- if (!(you.experience_level % 2))
- mp_adjust++;
-
- if (!(you.experience_level % 3))
- {
- modify_stat( (coinflip() ? STAT_INTELLIGENCE
- : STAT_DEXTERITY), 1, false );
- }
- break;
-
- case SP_GREY_ELF:
- if (you.experience_level == 5)
- {
- //jmf: got Glamour ability
- mpr("You feel charming!", MSGCH_INTRINSIC_GAIN);
- mp_adjust++;
- }
-
- if (you.experience_level < 14)
- hp_adjust--;
-
- if (you.experience_level % 3)
- mp_adjust++;
-
- if (!(you.experience_level % 4))
- {
- modify_stat( (coinflip() ? STAT_INTELLIGENCE
- : STAT_DEXTERITY), 1, false );
- }
-
- break;
-
- case SP_DEEP_ELF:
- if (you.experience_level < 17)
- hp_adjust--;
- if (!(you.experience_level % 3))
- hp_adjust--;
-
- mp_adjust++;
-
- if (!(you.experience_level % 4))
- modify_stat(STAT_INTELLIGENCE, 1, false);
- break;
-
- case SP_SLUDGE_ELF:
- if (you.experience_level % 3)
- hp_adjust--;
- else
- mp_adjust++;
-
- if (!(you.experience_level % 4))
- {
- modify_stat( (coinflip() ? STAT_INTELLIGENCE
- : STAT_DEXTERITY), 1, false );
- }
- break;
-
- case SP_HILL_DWARF:
- // lowered because of HD raise -- bwr
- // if (you.experience_level < 14)
- // hp_adjust++;
-
- if (you.experience_level % 3)
- hp_adjust++;
-
- if (!(you.experience_level % 2))
- mp_adjust--;
-
- if (!(you.experience_level % 4))
- modify_stat(STAT_STRENGTH, 1, false);
- break;
-
- case SP_MOUNTAIN_DWARF:
- // lowered because of HD raise -- bwr
- // if (you.experience_level < 14)
- // hp_adjust++;
-
- if (!(you.experience_level % 2))
- hp_adjust++;
-
- if (!(you.experience_level % 3))
- mp_adjust--;
-
- if (!(you.experience_level % 4))
- modify_stat(STAT_STRENGTH, 1, false);
- break;
-
- case SP_HALFLING:
- if (!(you.experience_level % 5))
- modify_stat(STAT_DEXTERITY, 1, false);
-
- if (you.experience_level < 17)
- hp_adjust--;
-
- if (!(you.experience_level % 2))
- hp_adjust--;
- break;
-
- case SP_KOBOLD:
- if (!(you.experience_level % 5))
- {
- modify_stat( (coinflip() ? STAT_STRENGTH
- : STAT_DEXTERITY), 1, false );
- }
-
- if (you.experience_level < 17)
- hp_adjust--;
-
- if (!(you.experience_level % 2))
- hp_adjust--;
- break;
-
- case SP_HILL_ORC:
- // lower because of HD raise -- bwr
- // if (you.experience_level < 17)
- // hp_adjust++;
-
- if (!(you.experience_level % 2))
- hp_adjust++;
-
- if (!(you.experience_level % 3))
- mp_adjust--;
-
- if (!(you.experience_level % 5))
- modify_stat(STAT_STRENGTH, 1, false);
- break;
-
- case SP_MUMMY:
- if (you.experience_level == 13 || you.experience_level == 26)
- {
- mpr( "You feel more in touch with the powers of death.",
- MSGCH_INTRINSIC_GAIN );
- }
-
- if (you.experience_level == 13) // level 13 for now -- bwr
- {
- mpr( "You can now infuse your body with magic to restore decomposition.", MSGCH_INTRINSIC_GAIN );
- }
- break;
-
- case SP_NAGA:
- // lower because of HD raise -- bwr
- // if (you.experience_level < 14)
- // hp_adjust++;
-
- hp_adjust++;
-
- if (!(you.experience_level % 4))
- modify_stat(STAT_RANDOM, 1, false);
-
- if (!(you.experience_level % 3))
- {
- mpr("Your skin feels tougher.", MSGCH_INTRINSIC_GAIN);
- you.redraw_armour_class = 1;
- }
- break;
-
- case SP_GNOME:
- if (you.experience_level < 13)
- hp_adjust--;
-
- if (!(you.experience_level % 3))
- hp_adjust--;
-
- if (!(you.experience_level % 4))
- {
- modify_stat( (coinflip() ? STAT_INTELLIGENCE
- : STAT_DEXTERITY), 1, false );
- }
- break;
-
- case SP_OGRE:
- case SP_TROLL:
- hp_adjust++;
-
- // lowered because of HD raise -- bwr
- // if (you.experience_level < 14)
- // hp_adjust++;
-
- if (!(you.experience_level % 2))
- hp_adjust++;
-
- if (you.experience_level % 3)
- mp_adjust--;
-
- if (!(you.experience_level % 3))
- modify_stat(STAT_STRENGTH, 1, false);
- break;
-
- case SP_OGRE_MAGE:
- hp_adjust++;
-
- // lowered because of HD raise -- bwr
- // if (you.experience_level < 14)
- // hp_adjust++;
-
- if (!(you.experience_level % 5))
- {
- modify_stat( (coinflip() ? STAT_INTELLIGENCE
- : STAT_STRENGTH), 1, false );
- }
- break;
-
- case SP_RED_DRACONIAN:
- case SP_WHITE_DRACONIAN:
- case SP_GREEN_DRACONIAN:
- case SP_GOLDEN_DRACONIAN:
-/* Grey is later */
- case SP_BLACK_DRACONIAN:
- case SP_PURPLE_DRACONIAN:
- case SP_MOTTLED_DRACONIAN:
- case SP_PALE_DRACONIAN:
- case SP_UNK0_DRACONIAN:
- case SP_UNK1_DRACONIAN:
- case SP_BASE_DRACONIAN:
- if (you.experience_level == 7)
- {
- switch (you.species)
- {
- case SP_RED_DRACONIAN:
- mpr("Your scales start taking on a fiery red colour.",
- MSGCH_INTRINSIC_GAIN);
- break;
- case SP_WHITE_DRACONIAN:
- mpr("Your scales start taking on an icy white colour.",
- MSGCH_INTRINSIC_GAIN);
- break;
- case SP_GREEN_DRACONIAN:
- mpr("Your scales start taking on a green colour.",
- MSGCH_INTRINSIC_GAIN);
- mpr("You feel resistant to poison.", MSGCH_INTRINSIC_GAIN);
- break;
-
- case SP_GOLDEN_DRACONIAN:
- mpr("Your scales start taking on a golden yellow colour.", MSGCH_INTRINSIC_GAIN);
- break;
- case SP_BLACK_DRACONIAN:
- mpr("Your scales start turning black.", MSGCH_INTRINSIC_GAIN);
- break;
- case SP_PURPLE_DRACONIAN:
- mpr("Your scales start taking on a rich purple colour.", MSGCH_INTRINSIC_GAIN);
- break;
- case SP_MOTTLED_DRACONIAN:
- mpr("Your scales start taking on a weird mottled pattern.", MSGCH_INTRINSIC_GAIN);
- break;
- case SP_PALE_DRACONIAN:
- mpr("Your scales start fading to a pale grey colour.", MSGCH_INTRINSIC_GAIN);
- break;
- case SP_UNK0_DRACONIAN:
- case SP_UNK1_DRACONIAN:
- case SP_BASE_DRACONIAN:
- mpr("");
- break;
- }
- more();
- redraw_screen();
- }
-
- if (you.experience_level == 18)
- {
- switch (you.species)
- {
- case SP_RED_DRACONIAN:
- mpr("You feel resistant to fire.", MSGCH_INTRINSIC_GAIN);
- break;
- case SP_WHITE_DRACONIAN:
- mpr("You feel resistant to cold.", MSGCH_INTRINSIC_GAIN);
- break;
- case SP_BLACK_DRACONIAN:
- mpr("You feel resistant to electrical energy.",
- MSGCH_INTRINSIC_GAIN);
- break;
- }
- }
-
- if (!(you.experience_level % 3))
- hp_adjust++;
-
- if (you.experience_level > 7 && !(you.experience_level % 4))
- {
- mpr("Your scales feel tougher.", MSGCH_INTRINSIC_GAIN);
- you.redraw_armour_class = 1;
- modify_stat(STAT_RANDOM, 1, false);
- }
- break;
-
- case SP_GREY_DRACONIAN:
- if (you.experience_level == 7)
- {
- mpr("Your scales start turning grey.", MSGCH_INTRINSIC_GAIN);
- more();
- redraw_screen();
- }
-
- if (!(you.experience_level % 3))
- {
- hp_adjust++;
- if (you.experience_level > 7)
- hp_adjust++;
- }
-
- if (you.experience_level > 7 && !(you.experience_level % 2))
- {
- mpr("Your scales feel tougher.", MSGCH_INTRINSIC_GAIN);
- you.redraw_armour_class = 1;
- }
-
- if ((you.experience_level > 7 && !(you.experience_level % 3))
- || you.experience_level == 4 || you.experience_level == 7)
- {
- modify_stat(STAT_RANDOM, 1, false);
- }
- break;
-
- case SP_CENTAUR:
- if (!(you.experience_level % 4))
- {
- modify_stat( (coinflip() ? STAT_DEXTERITY
- : STAT_STRENGTH), 1, false );
- }
-
- // lowered because of HD raise -- bwr
- // if (you.experience_level < 17)
- // hp_adjust++;
-
- if (!(you.experience_level % 2))
- hp_adjust++;
-
- if (!(you.experience_level % 3))
- mp_adjust--;
- break;
-
- case SP_DEMIGOD:
- if (!(you.experience_level % 3))
- modify_stat(STAT_RANDOM, 1, false);
-
- // lowered because of HD raise -- bwr
- // if (you.experience_level < 17)
- // hp_adjust++;
-
- if (!(you.experience_level % 2))
- hp_adjust++;
-
- if (you.experience_level % 3)
- mp_adjust++;
- break;
-
- case SP_SPRIGGAN:
- if (you.experience_level < 17)
- hp_adjust--;
-
- if (you.experience_level % 3)
- hp_adjust--;
-
- mp_adjust++;
-
- if (!(you.experience_level % 5))
- {
- modify_stat( (coinflip() ? STAT_INTELLIGENCE
- : STAT_DEXTERITY), 1, false );
- }
- break;
-
- case SP_MINOTAUR:
- // lowered because of HD raise -- bwr
- // if (you.experience_level < 17)
- // hp_adjust++;
-
- if (!(you.experience_level % 2))
- hp_adjust++;
-
- if (!(you.experience_level % 2))
- mp_adjust--;
-
- if (!(you.experience_level % 4))
- {
- modify_stat( (coinflip() ? STAT_DEXTERITY
- : STAT_STRENGTH), 1, false );
- }
- break;
-
- case SP_DEMONSPAWN:
- if (you.attribute[ATTR_NUM_DEMONIC_POWERS] == 0
- && (you.experience_level == 4
- || (you.experience_level < 4 && one_chance_in(3))))
- {
- demonspawn();
- }
-
- if (you.attribute[ATTR_NUM_DEMONIC_POWERS] == 1
- && you.experience_level > 4
- && (you.experience_level == 9
- || (you.experience_level < 9 && one_chance_in(3))))
- {
- demonspawn();
- }
-
- if (you.attribute[ATTR_NUM_DEMONIC_POWERS] == 2
- && you.experience_level > 9
- && (you.experience_level == 14
- || (you.experience_level < 14 && one_chance_in(3))))
- {
- demonspawn();
- }
-
- if (you.attribute[ATTR_NUM_DEMONIC_POWERS] == 3
- && you.experience_level > 14
- && (you.experience_level == 19
- || (you.experience_level < 19 && one_chance_in(3))))
- {
- demonspawn();
- }
-
- if (you.attribute[ATTR_NUM_DEMONIC_POWERS] == 4
- && you.experience_level > 19
- && (you.experience_level == 24
- || (you.experience_level < 24 && one_chance_in(3))))
- {
- demonspawn();
- }
-
- if (you.attribute[ATTR_NUM_DEMONIC_POWERS] == 5
- && you.experience_level == 27)
- {
- demonspawn();
- }
-
-/*if (you.attribute [ATTR_NUM_DEMONIC_POWERS] == 6 && (you.experience_level == 8 || (you.experience_level < 8 && one_chance_in(3) ) )
- demonspawn(); */
- if (!(you.experience_level % 4))
- modify_stat(STAT_RANDOM, 1, false);
- break;
-
- case SP_GHOUL:
- // lowered because of HD raise -- bwr
- // if (you.experience_level < 17)
- // hp_adjust++;
-
- if (!(you.experience_level % 2))
- hp_adjust++;
-
- if (!(you.experience_level % 3))
- mp_adjust--;
-
- if (!(you.experience_level % 5))
- modify_stat(STAT_STRENGTH, 1, false);
- break;
-
- case SP_KENKU:
- if (you.experience_level < 17)
- hp_adjust--;
-
- if (!(you.experience_level % 3))
- hp_adjust--;
-
- if (!(you.experience_level % 4))
- modify_stat(STAT_RANDOM, 1, false);
-
- if (you.experience_level == 5)
- mpr("You have gained the ability to fly.", MSGCH_INTRINSIC_GAIN);
- else if (you.experience_level == 15)
- mpr("You can now fly continuously.", MSGCH_INTRINSIC_GAIN);
- break;
-
- case SP_MERFOLK:
- if (you.experience_level % 3)
- hp_adjust++;
-
- if (!(you.experience_level % 5))
- modify_stat(STAT_RANDOM, 1, false);
- break;
- }
- }
-
- // add hp and mp adjustments - GDL
- inc_max_hp( hp_adjust );
- inc_max_mp( mp_adjust );
-
- deflate_hp( you.hp_max, false );
-
- if (you.magic_points < 0)
- you.magic_points = 0;
-
- calc_hp();
- calc_mp();
-
- if (you.experience_level > you.max_level)
- you.max_level = you.experience_level;
-
- if (you.religion == GOD_XOM)
- Xom_acts(true, you.experience_level, true);
- }
-
- redraw_skill( you.your_name, player_title() );
-} // end level_change()
-
-// here's a question for you: does the ordering of mods make a difference?
-// (yes) -- are these things in the right order of application to stealth?
-// - 12mar2000 {dlb}
-int check_stealth(void)
-{
- if (you.special_wield == SPWLD_SHADOW)
- return (0);
-
- int stealth = you.dex * 3;
-
- if (you.skills[SK_STEALTH])
- {
- if (player_genus(GENPC_DRACONIAN))
- stealth += (you.skills[SK_STEALTH] * 12);
- else
- {
- switch (you.species)
- {
- case SP_TROLL:
- case SP_OGRE:
- case SP_OGRE_MAGE:
- case SP_CENTAUR:
- stealth += (you.skills[SK_STEALTH] * 9);
- break;
- case SP_MINOTAUR:
- stealth += (you.skills[SK_STEALTH] * 12);
- break;
- case SP_GNOME:
- case SP_HALFLING:
- case SP_KOBOLD:
- case SP_SPRIGGAN:
- case SP_NAGA: // not small but very good at stealth
- stealth += (you.skills[SK_STEALTH] * 18);
- break;
- default:
- stealth += (you.skills[SK_STEALTH] * 15);
- break;
- }
- }
- }
-
- if (you.burden_state == BS_ENCUMBERED)
- stealth /= 2;
- else if (you.burden_state == BS_OVERLOADED)
- stealth /= 5;
-
- if (you.conf)
- stealth /= 3;
-
- const int arm = you.equip[EQ_BODY_ARMOUR];
- const int cloak = you.equip[EQ_CLOAK];
- const int boots = you.equip[EQ_BOOTS];
-
- if (arm != -1 && !player_light_armour())
- stealth -= (item_mass( you.inv[arm] ) / 10);
-
- if (cloak != -1 && get_equip_race(you.inv[cloak]) == ISFLAG_ELVEN)
- stealth += 20;
-
- if (boots != -1)
- {
- if (get_armour_ego_type( you.inv[boots] ) == SPARM_STEALTH)
- stealth += 50;
-
- if (get_equip_race(you.inv[boots]) == ISFLAG_ELVEN)
- stealth += 20;
- }
-
- stealth += scan_randarts( RAP_STEALTH );
-
- if (player_is_levitating())
- stealth += 10;
- else if (player_in_water())
- {
- // Merfolk can sneak up on monsters underwater -- bwr
- if (you.species == SP_MERFOLK)
- stealth += 50;
- else
- stealth /= 2; // splashy-splashy
- }
-
- // Radiating silence is the negative compliment of shouting all the
- // time... a sudden change from background noise to no noise is going
- // to clue anything in to the fact that something is very wrong...
- // a personal silence spell would naturally be different, but this
- // silence radiates for a distance and prevents monster spellcasting,
- // which pretty much gives away the stealth game.
- if (you.duration[DUR_SILENCE])
- stealth -= 50;
-
- if (stealth < 0)
- stealth = 0;
-
- return (stealth);
-} // end check_stealth()
-
-void ability_increase(void)
-{
- unsigned char keyin;
-
- mpr("Your experience leads to an increase in your attributes!",
- MSGCH_INTRINSIC_GAIN);
-
- more();
- mesclr();
-
- mpr("Increase (S)trength, (I)ntelligence, or (D)exterity? ", MSGCH_PROMPT);
-
- get_key:
- keyin = getch();
- if (keyin == 0)
- {
- getch();
- goto get_key;
- }
-
- switch (keyin)
- {
- case 's':
- case 'S':
- modify_stat(STAT_STRENGTH, 1, false);
- return;
-
- case 'i':
- case 'I':
- modify_stat(STAT_INTELLIGENCE, 1, false);
- return;
-
- case 'd':
- case 'D':
- modify_stat(STAT_DEXTERITY, 1, false);
- return;
- }
-
- goto get_key;
-/* this is an infinite loop because it is reasonable to assume that you're not going to want to leave it prematurely. */
-} // end ability_increase()
-
-void display_char_status(void)
-{
- if (you.is_undead)
- mpr( "You are undead." );
- else if (you.deaths_door)
- mpr( "You are standing in death's doorway." );
- else
- mpr( "You are alive." );
-
- switch (you.attribute[ATTR_TRANSFORMATION])
- {
- case TRAN_SPIDER:
- mpr( "You are in spider-form." );
- break;
- case TRAN_BLADE_HANDS:
- mpr( "You have blades for hands." );
- break;
- case TRAN_STATUE:
- mpr( "You are a statue." );
- break;
- case TRAN_ICE_BEAST:
- mpr( "You are an ice creature." );
- break;
- case TRAN_DRAGON:
- mpr( "You are in dragon-form." );
- break;
- case TRAN_LICH:
- mpr( "You are in lich-form." );
- break;
- case TRAN_SERPENT_OF_HELL:
- mpr( "You are a huge demonic serpent." );
- break;
- case TRAN_AIR:
- mpr( "You are a cloud of diffuse gas." );
- break;
- }
-
- if (you.duration[DUR_BREATH_WEAPON])
- mpr( "You are short of breath." );
-
- if (you.duration[DUR_REPEL_UNDEAD])
- mpr( "You have a holy aura protecting you from undead." );
-
- if (you.duration[DUR_LIQUID_FLAMES])
- mpr( "You are covered in liquid flames." );
-
- if (you.duration[DUR_ICY_ARMOUR])
- mpr( "You are protected by an icy shield." );
-
- if (you.duration[DUR_REPEL_MISSILES])
- mpr( "You are protected from missiles." );
-
- if (you.duration[DUR_DEFLECT_MISSILES])
- mpr( "You deflect missiles." );
-
- if (you.duration[DUR_PRAYER])
- mpr( "You are praying." );
-
- if (you.duration[DUR_REGENERATION])
- mpr( "You are regenerating." );
-
- if (you.duration[DUR_SWIFTNESS])
- mpr( "You can move swiftly." );
-
- if (you.duration[DUR_INSULATION])
- mpr( "You are insulated." );
-
- if (you.duration[DUR_STONEMAIL])
- mpr( "You are covered in scales of stone." );
-
- if (you.duration[DUR_CONTROLLED_FLIGHT])
- mpr( "You can control your flight." );
-
- if (you.duration[DUR_TELEPORT])
- mpr( "You are about to teleport." );
-
- if (you.duration[DUR_CONTROL_TELEPORT])
- mpr( "You can control teleportation." );
-
- if (you.duration[DUR_DEATH_CHANNEL])
- mpr( "You are channeling the dead." );
-
- if (you.duration[DUR_FORESCRY]) //jmf: added 19mar2000
- mpr( "You are forewarned." );
-
- if (you.duration[DUR_SILENCE]) //jmf: added 27mar2000
- mpr( "You radiate silence." );
-
- if (you.duration[DUR_STONESKIN])
- mpr( "Your skin is tough as stone." );
-
- if (you.duration[DUR_SEE_INVISIBLE])
- mpr( "You can see invisible." );
-
- if (you.invis)
- mpr( "You are invisible." );
-
- if (you.conf)
- mpr( "You are confused." );
-
- if (you.paralysis)
- mpr( "You are paralysed." );
-
- if (you.exhausted)
- mpr( "You are exhausted." );
-
- if (you.slow && you.haste)
- mpr( "You are under both slowing and hasting effects." );
- else if (you.slow)
- mpr( "You are moving very slowly." );
- else if (you.haste)
- mpr( "You are moving very quickly." );
-
- if (you.might)
- mpr( "You are mighty." );
-
- if (you.berserker)
- mpr( "You are possessed by a berserker rage." );
-
- if (player_is_levitating())
- mpr( "You are hovering above the floor." );
-
- if (you.poison)
- {
- snprintf( info, INFO_SIZE, "You are %s poisoned.",
- (you.poison > 10) ? "extremely" :
- (you.poison > 5) ? "very" :
- (you.poison > 3) ? "quite"
- : "mildly" );
- mpr(info);
- }
-
- if (you.disease)
- {
- snprintf( info, INFO_SIZE, "You are %sdiseased.",
- (you.disease > 120) ? "badly " :
- (you.disease > 40) ? ""
- : "mildly " );
- mpr(info);
- }
-
- if (you.rotting || you.species == SP_GHOUL)
- {
- // I apologize in advance for the horrendous ugliness about to
- // transpire. Avert your eyes!
- snprintf( info, INFO_SIZE, "Your flesh is rotting%s",
- (you.rotting > 15) ? " before your eyes!":
- (you.rotting > 8) ? " away quickly.":
- (you.rotting > 4) ? " badly."
- : ((you.species == SP_GHOUL && you.rotting > 0)
- ? " faster than usual." : ".") );
- mpr(info);
- }
-
- contaminate_player( 0, true );
-
- if (you.confusing_touch)
- {
- snprintf( info, INFO_SIZE, "Your hands are glowing %s red.",
- (you.confusing_touch > 40) ? "an extremely bright" :
- (you.confusing_touch > 20) ? "bright"
- : "a soft" );
- mpr(info);
- }
-
- if (you.sure_blade)
- {
- snprintf( info, INFO_SIZE, "You have a %sbond with your blade.",
- (you.sure_blade > 15) ? "strong " :
- (you.sure_blade > 5) ? ""
- : "weak " );
- mpr(info);
- }
-} // end display_char_status()
-
-void redraw_skill(const char your_name[kNameLen], const char class_name[80])
-{
- char print_it[80];
-
- memset( print_it, ' ', sizeof(print_it) );
- snprintf( print_it, sizeof(print_it), "%s the %s", your_name, class_name );
-
- int in_len = strlen( print_it );
- if (in_len > 40)
- {
- in_len -= 3; // what we're getting back from removing "the"
-
- const int name_len = strlen(your_name);
- char name_buff[kNameLen];
- strncpy( name_buff, your_name, kNameLen );
-
- // squeeze name if required, the "- 8" is too not squueze too much
- if (in_len > 40 && (name_len - 8) > (in_len - 40))
- name_buff[ name_len - (in_len - 40) - 1 ] = '\0';
- else
- name_buff[ kNameLen - 1 ] = '\0';
-
- snprintf( print_it, sizeof(print_it), "%s, %s", name_buff, class_name );
- }
-
- for (int i = strlen(print_it); i < 41; i++)
- print_it[i] = ' ';
-
- print_it[40] = '\0';
-
-#ifdef DOS_TERM
- window(1, 1, 80, 25);
-#endif
- gotoxy(40, 1);
-
- textcolor( LIGHTGREY );
- cprintf( print_it );
-} // end redraw_skill()
-
-// Note that this function only has the one static buffer, so if you
-// want to use the results, you'll want to make a copy.
-char *species_name( int speci, int level, bool genus, bool adj, bool cap )
-// defaults: false false true
-{
- static char species_buff[80];
-
- if (player_genus( GENPC_DRACONIAN, speci ))
- {
- if (adj || genus) // adj doesn't care about exact species
- strcpy( species_buff, "Draconian" );
- else
- {
- // No longer have problems with ghosts here -- Sharp Aug2002
- if (level < 7)
- strcpy( species_buff, "Draconian" );
- else
- {
- switch (speci)
- {
- case SP_RED_DRACONIAN:
- strcpy( species_buff, "Red Draconian" );
- break;
- case SP_WHITE_DRACONIAN:
- strcpy( species_buff, "White Draconian" );
- break;
- case SP_GREEN_DRACONIAN:
- strcpy( species_buff, "Green Draconian" );
- break;
- case SP_GOLDEN_DRACONIAN:
- strcpy( species_buff, "Yellow Draconian" );
- break;
- case SP_GREY_DRACONIAN:
- strcpy( species_buff, "Grey Draconian" );
- break;
- case SP_BLACK_DRACONIAN:
- strcpy( species_buff, "Black Draconian" );
- break;
- case SP_PURPLE_DRACONIAN:
- strcpy( species_buff, "Purple Draconian" );
- break;
- case SP_MOTTLED_DRACONIAN:
- strcpy( species_buff, "Mottled Draconian" );
- break;
- case SP_PALE_DRACONIAN:
- strcpy( species_buff, "Pale Draconian" );
- break;
- case SP_UNK0_DRACONIAN:
- case SP_UNK1_DRACONIAN:
- case SP_BASE_DRACONIAN:
- default:
- strcpy( species_buff, "Draconian" );
- break;
- }
- }
- }
- }
- else if (player_genus( GENPC_ELVEN, speci ))
- {
- if (adj) // doesn't care about species/genus
- strcpy( species_buff, "Elven" );
- else if (genus)
- strcpy( species_buff, "Elf" );
- else
- {
- switch (speci)
- {
- case SP_ELF:
- default:
- strcpy( species_buff, "Elf" );
- break;
- case SP_HIGH_ELF:
- strcpy( species_buff, "High Elf" );
- break;
- case SP_GREY_ELF:
- strcpy( species_buff, "Grey Elf" );
- break;
- case SP_DEEP_ELF:
- strcpy( species_buff, "Deep Elf" );
- break;
- case SP_SLUDGE_ELF:
- strcpy( species_buff, "Sludge Elf" );
- break;
- }
- }
- }
- else if (player_genus( GENPC_DWARVEN, speci ))
- {
- if (adj) // doesn't care about species/genus
- strcpy( species_buff, "Dwarven" );
- else if (genus)
- strcpy( species_buff, "Dwarf" );
- else
- {
- switch (speci)
- {
- case SP_HILL_DWARF:
- strcpy( species_buff, "Hill Dwarf" );
- break;
- case SP_MOUNTAIN_DWARF:
- strcpy( species_buff, "Mountain Dwarf" );
- break;
- default:
- strcpy( species_buff, "Dwarf" );
- break;
- }
- }
- }
- else
- {
- switch (speci)
- {
- case SP_HUMAN:
- strcpy( species_buff, "Human" );
- break;
- case SP_HALFLING:
- strcpy( species_buff, "Halfling" );
- break;
- case SP_HILL_ORC:
- strcpy( species_buff, (adj) ? "Orcish" : (genus) ? "Orc"
- : "Hill Orc" );
- break;
- case SP_KOBOLD:
- strcpy( species_buff, "Kobold" );
- break;
- case SP_MUMMY:
- strcpy( species_buff, "Mummy" );
- break;
- case SP_NAGA:
- strcpy( species_buff, "Naga" );
- break;
- case SP_GNOME:
- strcpy( species_buff, (adj) ? "Gnomish" : "Gnome" );
- break;
- case SP_OGRE:
- strcpy( species_buff, (adj) ? "Ogreish" : "Ogre" );
- break;
- case SP_TROLL:
- strcpy( species_buff, (adj) ? "Trollish" : "Troll" );
- break;
- case SP_OGRE_MAGE:
- // We've previously declared that these are radically
- // different from Ogres... so we're not going to
- // refer to them as Ogres. -- bwr
- strcpy( species_buff, "Ogre-Mage" );
- break;
- case SP_CENTAUR:
- strcpy( species_buff, "Centaur" );
- break;
- case SP_DEMIGOD:
- strcpy( species_buff, (adj) ? "Divine" : "Demigod" );
- break;
- case SP_SPRIGGAN:
- strcpy( species_buff, "Spriggan" );
- break;
- case SP_MINOTAUR:
- strcpy( species_buff, "Minotaur" );
- break;
- case SP_DEMONSPAWN:
- strcpy( species_buff, (adj) ? "Demonic" : "Demonspawn" );
- break;
- case SP_GHOUL:
- strcpy( species_buff, (adj) ? "Ghoulish" : "Ghoul" );
- break;
- case SP_KENKU:
- strcpy( species_buff, "Kenku" );
- break;
- case SP_MERFOLK:
- strcpy( species_buff, (adj) ? "Merfolkian" : "Merfolk" );
- break;
- default:
- strcpy( species_buff, (adj) ? "Yakish" : "Yak" );
- break;
- }
- }
-
- if (!cap)
- strlwr( species_buff );
-
- return (species_buff);
-} // end species_name()
-
-bool wearing_amulet(char amulet, bool calc_unid)
-{
- if (amulet == AMU_CONTROLLED_FLIGHT
- && (you.duration[DUR_CONTROLLED_FLIGHT]
- || player_genus(GENPC_DRACONIAN)
- || you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON))
- {
- return true;
- }
-
- if (amulet == AMU_CLARITY && you.mutation[MUT_CLARITY])
- return true;
-
- if (amulet == AMU_RESIST_CORROSION || amulet == AMU_CONSERVATION)
- {
- // this is hackish {dlb}
- if (player_equip_ego_type( EQ_CLOAK, SPARM_PRESERVATION ))
- return true;
- }
-
- if (you.equip[EQ_AMULET] == -1)
- return false;
-
- if (you.inv[you.equip[EQ_AMULET]].sub_type == amulet
- && (calc_unid ||
- item_type_known(you.inv[you.equip[EQ_AMULET]])))
- return true;
-
- return false;
-} // end wearing_amulet()
-
-bool player_is_levitating(void)
-{
- return (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON || you.levitation);
-}
-
-bool player_has_spell( int spell )
-{
- for (int i = 0; i < 25; i++)
- {
- if (you.spells[i] == spell)
- return (true);
- }
-
- return (false);
-}
-
-int species_exp_mod(char species)
-{
-
- if (player_genus(GENPC_DRACONIAN))
- return 14;
- else if (player_genus(GENPC_DWARVEN))
- return 13;
- {
- switch (species)
- {
- case SP_HUMAN:
- case SP_HALFLING:
- case SP_HILL_ORC:
- case SP_KOBOLD:
- return 10;
- case SP_GNOME:
- return 11;
- case SP_ELF:
- case SP_SLUDGE_ELF:
- case SP_NAGA:
- case SP_GHOUL:
- case SP_MERFOLK:
- return 12;
- case SP_SPRIGGAN:
- case SP_KENKU:
- return 13;
- case SP_GREY_ELF:
- case SP_DEEP_ELF:
- case SP_OGRE:
- case SP_CENTAUR:
- case SP_MINOTAUR:
- case SP_DEMONSPAWN:
- return 14;
- case SP_HIGH_ELF:
- case SP_MUMMY:
- case SP_TROLL:
- case SP_OGRE_MAGE:
- return 15;
- case SP_DEMIGOD:
- return 16;
- default:
- return 0;
- }
- }
-} // end species_exp_mod()
-
-unsigned long exp_needed(int lev)
-{
- lev--;
-
- unsigned long level = 0;
-
-#if 0
- case 1: level = 1;
- case 2: level = 10;
- case 3: level = 35;
- case 4: level = 70;
- case 5: level = 120;
- case 6: level = 250;
- case 7: level = 510;
- case 8: level = 900;
- case 9: level = 1700;
- case 10: level = 3500;
- case 11: level = 8000;
- case 12: level = 20000;
-
- default: //return 14000 * (lev - 11);
- level = 20000 * (lev - 11) + ((lev - 11) * (lev - 11) * (lev - 11)) * 130;
- break;
-#endif
-
- // This is a better behaved function than the above. The above looks
- // really ugly when you consider the second derivative, its not smooth
- // and has a horrible bump at level 12 followed by comparitively easy
- // teen levels. This tries to sort out those issues.
- //
- // Basic plan:
- // Section 1: levels 1- 5, second derivative goes 10-10-20-30.
- // Section 2: levels 6-13, second derivative is exponential/doubling.
- // Section 3: levels 14-27, second derivative is constant at 6000.
- //
- // Section three is constant so we end up with high levels at about
- // their old values (level 27 at 850k), without delta2 ever decreasing.
- // The values that are considerably different (ie level 13 is now 29000,
- // down from 41040 are because the second derivative goes from 9040 to
- // 1430 at that point in the original, and then slowly builds back
- // up again). This function smoothes out the old level 10-15 area
- // considerably.
-
- // Here's a table:
- //
- // level xp delta delta2
- // ===== ======= ===== ======
- // 1 0 0 0
- // 2 10 10 10
- // 3 30 20 10
- // 4 70 40 20
- // 5 140 70 30
- // 6 270 130 60
- // 7 520 250 120
- // 8 1010 490 240
- // 9 1980 970 480
- // 10 3910 1930 960
- // 11 7760 3850 1920
- // 12 15450 7690 3840
- // 13 29000 13550 5860
- // 14 48500 19500 5950
- // 15 74000 25500 6000
- // 16 105500 31500 6000
- // 17 143000 37500 6000
- // 18 186500 43500 6000
- // 19 236000 49500 6000
- // 20 291500 55500 6000
- // 21 353000 61500 6000
- // 22 420500 67500 6000
- // 23 494000 73500 6000
- // 24 573500 79500 6000
- // 25 659000 85500 6000
- // 26 750500 91500 6000
- // 27 848000 97500 6000
-
-
- switch (lev)
- {
- case 1:
- level = 1;
- break;
- case 2:
- level = 10;
- break;
- case 3:
- level = 30;
- break;
- case 4:
- level = 70;
- break;
-
- default:
- if (lev < 13)
- {
- lev -= 4;
- level = 10 + 10 * lev
- + 30 * (static_cast<int>(pow( 2.0, lev + 1 )));
- }
- else
- {
- lev -= 12;
- level = 15500 + 10500 * lev + 3000 * lev * lev;
- }
- break;
- }
-
- return ((level - 1) * species_exp_mod(you.species) / 10);
-} // end exp_needed()
-
-// returns bonuses from rings of slaying, etc.
-int slaying_bonus(char which_affected)
-{
- int ret = 0;
-
- if (which_affected == PWPN_HIT)
- {
- ret += player_equip( EQ_RINGS_PLUS, RING_SLAYING );
- ret += scan_randarts(RAP_ACCURACY);
- }
- else if (which_affected == PWPN_DAMAGE)
- {
- ret += player_equip( EQ_RINGS_PLUS2, RING_SLAYING );
- ret += scan_randarts(RAP_DAMAGE);
- }
-
- return (ret);
-} // end slaying_bonus()
-
-/* Checks each equip slot for a randart, and adds up all of those with
- a given property. Slow if any randarts are worn, so avoid where possible. */
-int scan_randarts(char which_property, bool calc_unid)
-{
- int i = 0;
- int retval = 0;
-
- for (i = EQ_WEAPON; i < NUM_EQUIP; i++)
- {
- const int eq = you.equip[i];
-
- if (eq == -1)
- continue;
-
- // only weapons give their effects when in our hands
- if (i == EQ_WEAPON && you.inv[ eq ].base_type != OBJ_WEAPONS)
- continue;
-
- if (!is_random_artefact( you.inv[ eq ] ))
- continue;
-
- // Ignore unidentified items [TileCrawl dump enhancements].
- if (!item_ident(you.inv[ eq ], ISFLAG_KNOW_PROPERTIES) &&
- !calc_unid)
- continue;
-
- retval += randart_wpn_property( you.inv[ eq ], which_property );
- }
-
- return (retval);
-} // end scan_randarts()
-
-void modify_stat(unsigned char which_stat, char amount, bool suppress_msg)
-{
- char *ptr_stat = NULL;
- char *ptr_stat_max = NULL;
- char *ptr_redraw = NULL;
-
- // sanity - is non-zero amount?
- if (amount == 0)
- return;
-
- // Stop running/travel if a stat drops.
- if (amount < 0)
- interrupt_activity( AI_STAT_CHANGE );
-
- if (!suppress_msg)
- strcpy(info, "You feel ");
-
- if (which_stat == STAT_RANDOM)
- which_stat = random2(NUM_STATS);
-
- switch (which_stat)
- {
- case STAT_STRENGTH:
- ptr_stat = &you.strength;
- ptr_stat_max = &you.max_strength;
- ptr_redraw = &you.redraw_strength;
- if (!suppress_msg)
- strcat(info, (amount > 0) ? "stronger." : "weaker.");
- break;
-
- case STAT_DEXTERITY:
- ptr_stat = &you.dex;
- ptr_stat_max = &you.max_dex;
- ptr_redraw = &you.redraw_dexterity;
- if (!suppress_msg)
- strcat(info, (amount > 0) ? "agile." : "clumsy.");
- break;
-
- case STAT_INTELLIGENCE:
- ptr_stat = &you.intel;
- ptr_stat_max = &you.max_intel;
- ptr_redraw = &you.redraw_intelligence;
- if (!suppress_msg)
- strcat(info, (amount > 0) ? "clever." : "stupid.");
- break;
- }
-
- if (!suppress_msg)
- mpr( info, (amount > 0) ? MSGCH_INTRINSIC_GAIN : MSGCH_WARN );
-
- *ptr_stat += amount;
- *ptr_stat_max += amount;
- *ptr_redraw = 1;
-
- if (ptr_stat == &you.strength)
- burden_change();
-
- return;
-} // end modify_stat()
-
-void dec_hp(int hp_loss, bool fatal)
-{
- if (hp_loss < 1)
- return;
-
- you.hp -= hp_loss;
-
- if (!fatal && you.hp < 1)
- you.hp = 1;
-
- you.redraw_hit_points = 1;
-
- return;
-} // end dec_hp()
-
-void dec_mp(int mp_loss)
-{
- if (mp_loss < 1)
- return;
-
- you.magic_points -= mp_loss;
-
- if (you.magic_points < 0)
- you.magic_points = 0;
-
- you.redraw_magic_points = 1;
-
- return;
-} // end dec_mp()
-
-bool enough_hp(int minimum, bool suppress_msg)
-{
- // We want to at least keep 1 HP -- bwr
- if (you.hp < minimum + 1)
- {
- if (!suppress_msg)
- mpr("You haven't enough vitality at the moment.");
-
- return false;
- }
-
- return true;
-} // end enough_hp()
-
-bool enough_mp(int minimum, bool suppress_msg)
-{
- if (you.magic_points < minimum)
- {
- if (!suppress_msg)
- mpr("You haven't enough magic at the moment.");
-
- return false;
- }
-
- return true;
-} // end enough_mp()
-
-// Note that "max_too" refers to the base potential, the actual
-// resulting max value is subject to penalties, bonuses, and scalings.
-void inc_mp(int mp_gain, bool max_too)
-{
- if (mp_gain < 1)
- return;
-
- you.magic_points += mp_gain;
-
- if (max_too)
- inc_max_mp( mp_gain );
-
- if (you.magic_points > you.max_magic_points)
- you.magic_points = you.max_magic_points;
-
- you.redraw_magic_points = 1;
-
- return;
-} // end inc_mp()
-
-// Note that "max_too" refers to the base potential, the actual
-// resulting max value is subject to penalties, bonuses, and scalings.
-void inc_hp(int hp_gain, bool max_too)
-{
- if (hp_gain < 1)
- return;
-
- you.hp += hp_gain;
-
- if (max_too)
- inc_max_hp( hp_gain );
-
- if (you.hp > you.hp_max)
- you.hp = you.hp_max;
-
- you.redraw_hit_points = 1;
-} // end inc_hp()
-
-void rot_hp( int hp_loss )
-{
- you.base_hp -= hp_loss;
- calc_hp();
-
- you.redraw_hit_points = 1;
-}
-
-void unrot_hp( int hp_recovered )
-{
- if (hp_recovered >= 5000 - you.base_hp)
- you.base_hp = 5000;
- else
- you.base_hp += hp_recovered;
-
- calc_hp();
-
- you.redraw_hit_points = 1;
-}
-
-int player_rotted( void )
-{
- return (5000 - you.base_hp);
-}
-
-void rot_mp( int mp_loss )
-{
- you.base_magic_points -= mp_loss;
- calc_mp();
-
- you.redraw_magic_points = 1;
-}
-
-void inc_max_hp( int hp_gain )
-{
- you.base_hp2 += hp_gain;
- calc_hp();
-
- you.redraw_hit_points = 1;
-}
-
-void dec_max_hp( int hp_loss )
-{
- you.base_hp2 -= hp_loss;
- calc_hp();
-
- you.redraw_hit_points = 1;
-}
-
-void inc_max_mp( int mp_gain )
-{
- you.base_magic_points2 += mp_gain;
- calc_mp();
-
- you.redraw_magic_points = 1;
-}
-
-void dec_max_mp( int mp_loss )
-{
- you.base_magic_points2 -= mp_loss;
- calc_mp();
-
- you.redraw_magic_points = 1;
-}
-
-// use of floor: false = hp max, true = hp min {dlb}
-void deflate_hp(int new_level, bool floor)
-{
- if (floor && you.hp < new_level)
- you.hp = new_level;
- else if (!floor && you.hp > new_level)
- you.hp = new_level;
-
- // must remain outside conditional, given code usage {dlb}
- you.redraw_hit_points = 1;
-
- return;
-} // end deflate_hp()
-
-// Note that "max_too" refers to the base potential, the actual
-// resulting max value is subject to penalties, bonuses, and scalings.
-void set_hp(int new_amount, bool max_too)
-{
- if (you.hp != new_amount)
- you.hp = new_amount;
-
- if (max_too && you.hp_max != new_amount)
- {
- you.base_hp2 = 5000 + new_amount;
- calc_hp();
- }
-
- if (you.hp > you.hp_max)
- you.hp = you.hp_max;
-
- // must remain outside conditional, given code usage {dlb}
- you.redraw_hit_points = 1;
-
- return;
-} // end set_hp()
-
-// Note that "max_too" refers to the base potential, the actual
-// resulting max value is subject to penalties, bonuses, and scalings.
-void set_mp(int new_amount, bool max_too)
-{
- if (you.magic_points != new_amount)
- you.magic_points = new_amount;
-
- if (max_too && you.max_magic_points != new_amount)
- {
- // note that this gets scaled down for values > 18
- you.base_magic_points2 = 5000 + new_amount;
- calc_mp();
- }
-
- if (you.magic_points > you.max_magic_points)
- you.magic_points = you.max_magic_points;
-
- // must remain outside conditional, given code usage {dlb}
- you.redraw_magic_points = 1;
-
- return;
-} // end set_mp()
-
-
-static const char * Species_Abbrev_List[ NUM_SPECIES ] =
- { "XX", "Hu", "El", "HE", "GE", "DE", "SE", "HD", "MD", "Ha",
- "HO", "Ko", "Mu", "Na", "Gn", "Og", "Tr", "OM", "Dr", "Dr",
- "Dr", "Dr", "Dr", "Dr", "Dr", "Dr", "Dr", "Dr", "Dr", "Dr",
- "Ce", "DG", "Sp", "Mi", "DS", "Gh", "Ke", "Mf" };
-
-int get_species_index_by_abbrev( const char *abbrev )
-{
- int i;
- for (i = SP_HUMAN; i < NUM_SPECIES; i++)
- {
- if (tolower( abbrev[0] ) == tolower( Species_Abbrev_List[i][0] )
- && tolower( abbrev[1] ) == tolower( Species_Abbrev_List[i][1] ))
- {
- break;
- }
- }
-
- return ((i < NUM_SPECIES) ? i : -1);
-}
-
-int get_species_index_by_name( const char *name )
-{
- int i;
- int sp = -1;
-
- char *ptr;
- char lowered_buff[80];
-
- strncpy( lowered_buff, name, sizeof( lowered_buff ) );
- strlwr( lowered_buff );
-
- for (i = SP_HUMAN; i < NUM_SPECIES; i++)
- {
- char *lowered_species = species_name( i, 0, false, false, false );
- ptr = strstr( lowered_species, lowered_buff );
- if (ptr != NULL)
- {
- sp = i;
- if (ptr == lowered_species) // prefix takes preference
- break;
- }
- }
-
- return (sp);
-}
-
-const char *get_species_abbrev( int which_species )
-{
- ASSERT( which_species > 0 && which_species < NUM_SPECIES );
-
- return (Species_Abbrev_List[ which_species ]);
-}
-
-
-static const char * Class_Abbrev_List[ NUM_JOBS ] =
- { "Fi", "Wz", "Pr", "Th", "Gl", "Ne", "Pa", "As", "Be", "Hu",
- "Cj", "En", "FE", "IE", "Su", "AE", "EE", "Cr", "DK", "VM",
- "CK", "Tm", "He", "XX", "Re", "St", "Mo", "Wr", "Wn" };
-
-static const char * Class_Name_List[ NUM_JOBS ] =
- { "Fighter", "Wizard", "Priest", "Thief", "Gladiator", "Necromancer",
- "Paladin", "Assassin", "Berserker", "Hunter", "Conjurer", "Enchanter",
- "Fire Elementalist", "Ice Elementalist", "Summoner", "Air Elementalist",
- "Earth Elementalist", "Crusader", "Death Knight", "Venom Mage",
- "Chaos Knight", "Transmuter", "Healer", "Quitter", "Reaver", "Stalker",
- "Monk", "Warper", "Wanderer" };
-
-int get_class_index_by_abbrev( const char *abbrev )
-{
- int i;
-
- for (i = 0; i < NUM_JOBS; i++)
- {
- if (i == JOB_QUITTER)
- continue;
-
- if (tolower( abbrev[0] ) == tolower( Class_Abbrev_List[i][0] )
- && tolower( abbrev[1] ) == tolower( Class_Abbrev_List[i][1] ))
- {
- break;
- }
- }
-
- return ((i < NUM_JOBS) ? i : -1);
-}
-
-const char *get_class_abbrev( int which_job )
-{
- ASSERT( which_job < NUM_JOBS && which_job != JOB_QUITTER );
-
- return (Class_Abbrev_List[ which_job ]);
-}
-
-int get_class_index_by_name( const char *name )
-{
- int i;
- int cl = -1;
-
- char *ptr;
- char lowered_buff[80];
- char lowered_class[80];
-
- strncpy( lowered_buff, name, sizeof( lowered_buff ) );
- strlwr( lowered_buff );
-
- for (i = 0; i < NUM_JOBS; i++)
- {
- if (i == JOB_QUITTER)
- continue;
-
- strncpy( lowered_class, Class_Name_List[i], sizeof( lowered_class ) );
- strlwr( lowered_class );
-
- ptr = strstr( lowered_class, lowered_buff );
- if (ptr != NULL)
- {
- cl = i;
- if (ptr == lowered_class) // prefix takes preference
- break;
- }
- }
-
- return (cl);
-}
-
-const char *get_class_name( int which_job )
-{
- ASSERT( which_job < NUM_JOBS && which_job != JOB_QUITTER );
-
- return (Class_Name_List[ which_job ]);
-}
-
-/* ******************************************************************
-
-// this function is solely called by a commented out portion of
-// player::level_change() and is a bit outta whack with the
-// current codebase - probably should be struck as well 19may2000 {dlb}
-
-void priest_spells( int priest_pass[10], char religious )
-{
-
- switch ( religious )
- {
- case GOD_ZIN:
- priest_pass[1] = SPELL_LESSER_HEALING;
- priest_pass[2] = SPELL_REPEL_UNDEAD;
- priest_pass[3] = SPELL_HEAL_OTHER;
- priest_pass[4] = SPELL_PURIFICATION;
- priest_pass[5] = SPELL_GREATER_HEALING;
- priest_pass[6] = SPELL_SMITING;
- priest_pass[7] = SPELL_HOLY_WORD;
- priest_pass[8] = SPELL_REMOVE_CURSE;
- priest_pass[9] = SPELL_GUARDIAN;
- break;
-
- case GOD_SHINING_ONE:
- priest_pass[1] = SPELL_REPEL_UNDEAD;
- priest_pass[2] = SPELL_LESSER_HEALING;
- priest_pass[3] = SPELL_HEAL_OTHER;
- priest_pass[4] = SPELL_PURIFICATION;
- priest_pass[5] = SPELL_ABJURATION_II;
- priest_pass[6] = SPELL_THUNDERBOLT;
- priest_pass[7] = SPELL_SHINING_LIGHT;
- priest_pass[8] = SPELL_SUMMON_DAEVA;
- priest_pass[9] = SPELL_FLAME_OF_CLEANSING;
- break;
-
- case GOD_ELYVILON:
- priest_pass[1] = SPELL_LESSER_HEALING;
- priest_pass[2] = SPELL_HEAL_OTHER;
- priest_pass[3] = SPELL_PURIFICATION;
- priest_pass[4] = 93; // restore abilities
- priest_pass[5] = SPELL_GREATER_HEALING;
- priest_pass[6] = 94; // another healing spell
- priest_pass[7] = 95; // something else
- priest_pass[8] = -1; //
- priest_pass[9] = -1; //
- break;
- }
-
-}
-
-// Spells to be added: (+ renamed!)
-// holy berserker
-// 87 Pestilence
-// 93 Restore Abilities
-// 94 something else healing
-// 95 something else
-
-****************************************************************** */
-
-void contaminate_player(int change, bool statusOnly)
-{
- // get current contamination level
- int old_level;
- int new_level;
-
-
-#if DEBUG_DIAGNOSTICS
- if (change > 0 || (change < 0 && you.magic_contamination))
- {
- snprintf( info, INFO_SIZE, "change: %d radiation: %d",
- change, change + you.magic_contamination );
-
- mpr( info, MSGCH_DIAGNOSTICS );
- }
-#endif
-
- old_level = (you.magic_contamination > 60)?(you.magic_contamination / 20 + 2) :
- (you.magic_contamination > 40)?4 :
- (you.magic_contamination > 25)?3 :
- (you.magic_contamination > 15)?2 :
- (you.magic_contamination > 5)?1 : 0;
-
- // make the change
- if (change + you.magic_contamination < 0)
- you.magic_contamination = 0;
- else
- {
- if (change + you.magic_contamination > 250)
- you.magic_contamination = 250;
- else
- you.magic_contamination += change;
- }
-
- // figure out new level
- new_level = (you.magic_contamination > 60)?(you.magic_contamination / 20 + 2) :
- (you.magic_contamination > 40)?4 :
- (you.magic_contamination > 25)?3 :
- (you.magic_contamination > 15)?2 :
- (you.magic_contamination > 5)?1 : 0;
-
- if (statusOnly)
- {
- if (new_level > 0)
- {
- if (new_level > 3)
- {
- strcpy(info, (new_level == 4) ?
- "Your entire body has taken on an eerie glow!" :
- "You are engulfed in a nimbus of crackling magics!");
- }
- else
- {
- snprintf( info, INFO_SIZE, "You are %s with residual magics%c",
- (new_level == 3) ? "practically glowing" :
- (new_level == 2) ? "heavily infused"
- : "contaminated",
- (new_level == 3) ? '!' : '.');
- }
-
- mpr(info);
- }
- return;
- }
-
- if (new_level == old_level)
- return;
-
- snprintf( info, INFO_SIZE, "You feel %s contaminated with magical energies.",
- (change < 0) ? "less" : "more" );
-
- mpr( info, (change > 0) ? MSGCH_WARN : MSGCH_RECOVERY );
-}
-
-void poison_player( int amount, bool force )
-{
- if ((!force && player_res_poison()) || amount <= 0)
- return;
-
- const int old_value = you.poison;
- you.poison += amount;
-
- if (you.poison > 40)
- you.poison = 40;
-
- if (you.poison > old_value)
- {
- snprintf( info, INFO_SIZE, "You are %spoisoned.",
- (old_value > 0) ? "more " : "" );
-
- // XXX: which message channel for this message?
- mpr( info );
- }
-}
-
-void reduce_poison_player( int amount )
-{
- if (you.poison == 0 || amount <= 0)
- return;
-
- you.poison -= amount;
-
- if (you.poison <= 0)
- {
- you.poison = 0;
- mpr( "You feel better.", MSGCH_RECOVERY );
- }
- else
- {
- mpr( "You feel a little better.", MSGCH_RECOVERY );
- }
-}
-
-void confuse_player( int amount, bool resistable )
-{
- if (amount <= 0)
- return;
-
- if (resistable && wearing_amulet(AMU_CLARITY))
- {
- mpr( "You feel momentarily confused." );
- return;
- }
-
- const int old_value = you.conf;
- you.conf += amount;
-
- if (you.conf > 40)
- you.conf = 40;
-
- if (you.conf > old_value)
- {
- snprintf( info, INFO_SIZE, "You are %sconfused.",
- (old_value > 0) ? "more " : "" );
-
- // XXX: which message channel for this message?
- mpr( info );
- }
-}
-
-void reduce_confuse_player( int amount )
-{
- if (you.conf == 0 || amount <= 0)
- return;
-
- you.conf -= amount;
-
- if (you.conf <= 0)
- {
- you.conf = 0;
- mpr( "You feel less confused." );
- }
-}
-
-void slow_player( int amount )
-{
- if (amount <= 0)
- return;
-
- if (wearing_amulet( AMU_RESIST_SLOW ))
- mpr("You feel momentarily lethargic.");
- else if (you.slow >= 100)
- mpr( "You already are as slow as you could be." );
- else
- {
- if (you.slow == 0)
- mpr( "You feel yourself slow down." );
- else
- mpr( "You feel as though you will be slow longer." );
-
- you.slow += amount;
-
- if (you.slow > 100)
- you.slow = 100;
- }
-}
-
-void dec_slow_player( void )
-{
- if (you.slow > 1)
- {
- // BCR - Amulet of resist slow affects slow counter
- if (wearing_amulet(AMU_RESIST_SLOW))
- {
- you.slow -= 5;
- if (you.slow < 1)
- you.slow = 1;
- }
- else
- you.slow--;
- }
- else if (you.slow == 1)
- {
- mpr("You feel yourself speed up.", MSGCH_DURATION);
- you.slow = 0;
- }
-}
-
-void haste_player( int amount )
-{
- bool amu_eff = wearing_amulet( AMU_RESIST_SLOW );
-
- if (amount <= 0)
- return;
-
- if (amu_eff)
- mpr( "Your amulet glows brightly." );
-
- if (you.haste == 0)
- mpr( "You feel yourself speed up." );
- else if (you.haste > 80 + 20 * amu_eff)
- mpr( "You already have as much speed as you can handle." );
- else
- {
- mpr( "You feel as though your hastened speed will last longer." );
- contaminate_player(1);
- }
-
- you.haste += amount;
-
- if (you.haste > 80 + 20 * amu_eff)
- you.haste = 80 + 20 * amu_eff;
-
- did_god_conduct( DID_STIMULANTS, 4 + random2(4) );
-}
-
-void dec_haste_player( void )
-{
- if (you.haste > 1)
- {
- // BCR - Amulet of resist slow affects haste counter
- if (!wearing_amulet(AMU_RESIST_SLOW) || coinflip())
- you.haste--;
-
- if (you.haste == 6)
- {
- mpr( "Your extra speed is starting to run out.", MSGCH_DURATION );
- if (coinflip())
- you.haste--;
- }
- }
- else if (you.haste == 1)
- {
- mpr( "You feel yourself slow down.", MSGCH_DURATION );
- you.haste = 0;
- }
-}
-
-void disease_player( int amount )
-{
- if (you.is_undead || amount <= 0)
- return;
-
- mpr( "You feel ill." );
-
- const int tmp = you.disease + amount;
- you.disease = (tmp > 210) ? 210 : tmp;
-}
-
-void dec_disease_player( void )
-{
- if (you.disease > 0)
- {
- you.disease--;
-
- if (you.disease > 5
- && (you.species == SP_KOBOLD
- || you.duration[ DUR_REGENERATION ]
- || you.mutation[ MUT_REGENERATION ] == 3))
- {
- you.disease -= 2;
- }
-
- if (!you.disease)
- mpr("You feel your health improve.", MSGCH_RECOVERY);
- }
-}
-
-void rot_player( int amount )
-{
- if (amount <= 0)
- return;
-
- if (you.rotting < 40)
- {
- // Either this, or the actual rotting message should probably
- // be changed so that they're easier to tell apart. -- bwr
- snprintf( info, INFO_SIZE, "You feel your flesh %s away!",
- (you.rotting) ? "rotting" : "start to rot" );
- mpr( info, MSGCH_WARN );
-
- you.rotting += amount;
- }
-}
-
-void run_macro(const char *macroname)
-{
- if (you.activity != ACT_NONE && you.activity != ACT_MACRO)
- return;
-
-#ifdef CLUA_BINDINGS
- if (!clua)
- {
- mpr("Lua not initialized", MSGCH_DIAGNOSTICS);
- you.activity = ACT_NONE;
- return;
- }
-
- if (!clua.callbooleanfn(false, "c_macro", "s", macroname))
- {
- if (clua.error.length())
- mpr(clua.error.c_str());
- you.activity = ACT_NONE;
- }
- else
- {
- you.activity = ACT_MACRO;
- }
-#else
- you.activity = ACT_NONE;
-#endif
-}
-
-void perform_activity()
-{
- switch (you.activity)
- {
- case ACT_MULTIDROP:
- drop();
- break;
- case ACT_MACRO:
- run_macro();
- break;
- default:
- break;
- }
-}
-
-#ifdef CLUA_BINDINGS
-static const char *activity_interrupt_name(activity_interrupt_type ai)
-{
- switch (ai)
- {
- case AI_FORCE_INTERRUPT: return "force";
- case AI_KEYPRESS: return "keypress";
- case AI_FULL_HP: return "full_hp";
- case AI_FULL_MP: return "full_mp";
- case AI_STATUE: return "statue";
- case AI_HUNGRY: return "hungry";
- case AI_MESSAGE: return "message";
- case AI_HP_LOSS: return "hp_loss";
- case AI_BURDEN_CHANGE: return "burden";
- case AI_STAT_CHANGE: return "stat";
- case AI_SEE_MONSTER: return "monster";
- case AI_TELEPORT: return "teleport";
- default: return "unknown";
- }
-}
-
-static const char *activity_names[] = {
- "",
- "multidrop",
- "run",
- "travel",
- "macro"
-};
-
-static const char *activity_name(int act)
-{
- if (act < ACT_NONE || act >= ACT_ACTIVITY_COUNT)
- return NULL;
- return activity_names[act];
-}
-#endif
-
-static void kill_activity()
-{
- if (you.running)
- stop_running();
- you.activity = ACT_NONE;
-}
-
-static bool userdef_interrupt_activity( activity_interrupt_type ai,
- const activity_interrupt_data &at )
-{
-#ifdef CLUA_BINDINGS
- lua_State *ls = clua.state();
- if (!ls || ai == AI_FORCE_INTERRUPT)
- {
- if (ai == AI_FORCE_INTERRUPT || you.activity == ACT_MACRO)
- kill_activity();
- return true;
- }
-
- const char *interrupt_name = activity_interrupt_name(ai);
- const char *act_name = activity_name(you.activity);
-
- bool ran = clua.callfn("c_interrupt_activity", "1:ssA",
- act_name, interrupt_name, &at);
- if (ran)
- {
- // If the function returned nil, we want to cease processing.
- if (lua_isnil(ls, -1))
- {
- lua_pop(ls, 1);
- return false;
- }
-
- bool stopact = lua_toboolean(ls, -1);
- lua_pop(ls, 1);
- if (stopact)
- {
- kill_activity();
- return true;
- }
- }
-
- if (you.activity == ACT_MACRO &&
- clua.callbooleanfn(true, "c_interrupt_macro",
- "sA", interrupt_name, &at))
- {
- kill_activity();
- }
-
-#else
- if (you.activity == ACT_MACRO)
- kill_activity();
-#endif
- return true;
-}
-
-void interrupt_activity( activity_interrupt_type ai,
- const activity_interrupt_data &at )
-{
- if (you.running && !you.activity)
- you.activity = you.running > 0? ACT_RUNNING : ACT_TRAVELING;
-
- if (!you.activity)
- return;
-
- if (!userdef_interrupt_activity(ai, at) || !you.activity)
- {
- if (you.activity == ACT_RUNNING || you.activity == ACT_TRAVELING)
- you.activity = ACT_NONE;
- return;
- }
-
- if (!ai || (Options.activity_interrupts[ you.activity ] & ai)) {
- kill_activity();
- }
-
- if (you.activity == ACT_RUNNING || you.activity == ACT_TRAVELING)
- you.activity = ACT_NONE;
-}