summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-12-30 13:37:01 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-12-30 13:37:01 +0000
commite07b2622e22fa66566f3e18427e2bb2f9012682e (patch)
treecfd6490ec619d26cc968f09f64cdf204fb11363e /crawl-ref/source
parent5468ad7e219db69ad3b32c129a008986e038a1b7 (diff)
downloadcrawl-ref-e07b2622e22fa66566f3e18427e2bb2f9012682e.tar.gz
crawl-ref-e07b2622e22fa66566f3e18427e2bb2f9012682e.zip
Moved handle_time and friends to effects.cc.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3157 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/beam.cc2
-rw-r--r--crawl-ref/source/effects.cc808
-rw-r--r--crawl-ref/source/effects.h4
-rw-r--r--crawl-ref/source/files.cc1
-rw-r--r--crawl-ref/source/items.cc805
-rw-r--r--crawl-ref/source/items.h15
6 files changed, 815 insertions, 820 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index 86a40920ee..bd6ffba766 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -3352,7 +3352,7 @@ static int affect_player( bolt &beam )
mpr("You are blasted!");
if (beam.aux_source.empty())
- beam.aux_source = "disintegration bolt";
+ beam.aux_source = "a disintegration bolt";
beam_ouch( roll_dice( beam.damage ), beam );
beam.obvious_effect = true;
diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc
index 4159e7e0ee..0aa101bf09 100644
--- a/crawl-ref/source/effects.cc
+++ b/crawl-ref/source/effects.cc
@@ -20,8 +20,11 @@
#include "externs.h"
#include "beam.h"
+#include "cloud.h"
#include "decks.h"
+#include "delay.h"
#include "direct.h"
+#include "dgnevent.h"
#include "food.h"
#include "hiscores.h"
#include "it_use2.h"
@@ -41,15 +44,19 @@
#include "ouch.h"
#include "player.h"
#include "randart.h"
+#include "religion.h"
+#include "skills.h"
#include "skills2.h"
#include "spells3.h"
#include "spells4.h"
#include "spl-book.h"
+#include "spl-cast.h"
#include "spl-util.h"
#include "state.h"
#include "stuff.h"
#include "terrain.h"
#include "traps.h"
+#include "tutorial.h"
#include "view.h"
#include "xom.h"
@@ -1870,3 +1877,804 @@ bool forget_inventory(bool quiet)
return (items_forgotten > 0);
}
+
+///////////////////////////////////////////////////////////////////////
+
+static void hell_effects()
+{
+ int temp_rand = random2(17);
+ spschool_flag_type which_miscast = SPTYP_RANDOM;
+ bool summon_instead = false;
+ monster_type which_beastie = MONS_PROGRAM_BUG;
+
+ mpr((temp_rand == 0) ? "\"You will not leave this place.\"" :
+ (temp_rand == 1) ? "\"Die, mortal!\"" :
+ (temp_rand == 2) ? "\"We do not forgive those who trespass against us!\"" :
+ (temp_rand == 3) ? "\"Trespassers are not welcome here!\"" :
+ (temp_rand == 4) ? "\"You do not belong in this place!\"" :
+ (temp_rand == 5) ? "\"Leave now, before it is too late!\"" :
+ (temp_rand == 6) ? "\"We have you now!\"" :
+ // plain messages
+ (temp_rand == 7) ? (player_can_smell()) ? "You smell brimstone." :
+ "Brimstone rains from above." :
+ (temp_rand == 8) ? "You feel lost and a long, long way from home..." :
+ (temp_rand == 9) ? "You shiver with fear." :
+ // warning
+ (temp_rand == 10) ? "You feel a terrible foreboding..." :
+ (temp_rand == 11) ? "Something frightening happens." :
+ (temp_rand == 12) ? "You sense an ancient evil watching you..." :
+ (temp_rand == 13) ? "You suddenly feel all small and vulnerable." :
+ (temp_rand == 14) ? "You sense a hostile presence." :
+ // sounds
+ (temp_rand == 15) ? "A gut-wrenching scream fills the air!" :
+ (temp_rand == 16) ? "You hear words spoken in a strange and terrible language..."
+ : "You hear diabolical laughter!",
+ (temp_rand < 7 ? MSGCH_TALK :
+ temp_rand < 10 ? MSGCH_PLAIN :
+ temp_rand < 15 ? MSGCH_WARN
+ : MSGCH_SOUND) );
+
+ temp_rand = random2(27);
+
+ if (temp_rand > 17) // 9 in 27 odds {dlb}
+ {
+ temp_rand = random2(8);
+
+ if (temp_rand > 3) // 4 in 8 odds {dlb}
+ which_miscast = SPTYP_NECROMANCY;
+ else if (temp_rand > 1) // 2 in 8 odds {dlb}
+ which_miscast = SPTYP_SUMMONING;
+ else if (temp_rand > 0) // 1 in 8 odds {dlb}
+ which_miscast = SPTYP_CONJURATION;
+ else // 1 in 8 odds {dlb}
+ which_miscast = SPTYP_ENCHANTMENT;
+
+ miscast_effect( which_miscast, 4 + random2(6), random2avg(97, 3),
+ 100, "the effects of Hell" );
+ }
+ else if (temp_rand > 7) // 10 in 27 odds {dlb}
+ {
+ // 60:40 miscast:summon split {dlb}
+ summon_instead = (random2(5) > 2);
+
+ switch (you.where_are_you)
+ {
+ case BRANCH_DIS:
+ if (summon_instead)
+ which_beastie = summon_any_demon(DEMON_GREATER);
+ else
+ which_miscast = SPTYP_EARTH;
+ break;
+ case BRANCH_GEHENNA:
+ if (summon_instead)
+ which_beastie = MONS_FIEND;
+ else
+ which_miscast = SPTYP_FIRE;
+ break;
+ case BRANCH_COCYTUS:
+ if (summon_instead)
+ which_beastie = MONS_ICE_FIEND;
+ else
+ which_miscast = SPTYP_ICE;
+ break;
+ case BRANCH_TARTARUS:
+ if (summon_instead)
+ which_beastie = MONS_SHADOW_FIEND;
+ else
+ which_miscast = SPTYP_NECROMANCY;
+ break;
+ default: // this is to silence gcc compiler warnings {dlb}
+ if (summon_instead)
+ which_beastie = MONS_FIEND;
+ else
+ which_miscast = SPTYP_NECROMANCY;
+ break;
+ }
+
+ if (summon_instead)
+ {
+ create_monster( which_beastie, 0, BEH_HOSTILE, you.x_pos,
+ you.y_pos, MHITYOU, 250 );
+ }
+ else
+ {
+ miscast_effect( which_miscast, 4 + random2(6),
+ random2avg(97, 3), 100, "the effects of Hell" );
+ }
+ }
+
+ // NB: no "else" - 8 in 27 odds that nothing happens through
+ // first chain {dlb}
+ // also note that the following is distinct from and in
+ // addition to the above chain:
+
+ // try to summon at least one and up to five random monsters {dlb}
+ if (one_chance_in(3))
+ {
+ create_monster( RANDOM_MONSTER, 0, BEH_HOSTILE,
+ you.x_pos, you.y_pos, MHITYOU, 250 );
+
+ for (int i = 0; i < 4; i++)
+ {
+ if (one_chance_in(3))
+ {
+ create_monster( RANDOM_MONSTER, 0, BEH_HOSTILE,
+ you.x_pos, you.y_pos, MHITYOU, 250 );
+ }
+ }
+ }
+}
+
+static void rot_inventory_food(long time_delta)
+{
+ // Update all of the corpses and food chunks in the player's
+ // inventory {should be moved elsewhere - dlb}
+
+ bool burden_changed_by_rot = false;
+ bool new_rotting_item = false;
+ for (int i = 0; i < ENDOFPACK; i++)
+ {
+ if (you.inv[i].quantity < 1)
+ continue;
+
+ if (you.inv[i].base_type != OBJ_CORPSES && you.inv[i].base_type != OBJ_FOOD)
+ continue;
+
+ if (you.inv[i].base_type == OBJ_CORPSES
+ && you.inv[i].sub_type > CORPSE_SKELETON)
+ {
+ continue;
+ }
+
+ if (you.inv[i].base_type == OBJ_FOOD && you.inv[i].sub_type != FOOD_CHUNK)
+ continue;
+
+ if ((time_delta / 20) >= you.inv[i].special)
+ {
+ if (you.inv[i].base_type == OBJ_FOOD)
+ {
+ if (you.equip[EQ_WEAPON] == i)
+ unwield_item();
+
+ destroy_item(you.inv[i]);
+ burden_changed_by_rot = true;
+ continue;
+ }
+
+ if (you.inv[i].sub_type == CORPSE_SKELETON)
+ continue; // carried skeletons are not destroyed
+
+ if (!mons_skeleton( you.inv[i].plus ))
+ {
+ if (you.equip[EQ_WEAPON] == i)
+ unwield_item();
+
+ destroy_item(you.inv[i]);
+ burden_changed_by_rot = true;
+ continue;
+ }
+
+ you.inv[i].sub_type = CORPSE_SKELETON;
+ you.inv[i].special = 0;
+ you.inv[i].colour = LIGHTGREY;
+ you.wield_change = true;
+ burden_changed_by_rot = true;
+ continue;
+ }
+
+ you.inv[i].special -= (time_delta / 20);
+
+ if (you.inv[i].special < 100 && (you.inv[i].special + (time_delta / 20)>=100))
+ {
+ new_rotting_item = true;
+ }
+ }
+
+ //mv: messages when chunks/corpses become rotten
+ if (new_rotting_item)
+ {
+ // XXX: should probably still notice?
+ // Races that can't smell don't care, and trolls are stupid and
+ // don't care.
+ if (player_can_smell() && you.species != SP_TROLL)
+ {
+ int temp_rand = 0; // Grr.
+ switch (you.mutation[MUT_SAPROVOROUS])
+ {
+ // level 1 and level 2 saprovores aren't so touchy
+ case 1:
+ case 2:
+ temp_rand = random2(8);
+ mpr( ((temp_rand < 5) ? "You smell something rotten." :
+ (temp_rand == 5) ? "You smell rotting flesh." :
+ (temp_rand == 6) ? "You smell decay."
+ : "There is something rotten in your inventory."),
+ MSGCH_ROTTEN_MEAT );
+ break;
+
+ // level 3 saprovores like it
+ case 3:
+ temp_rand = random2(8);
+ mpr( ((temp_rand < 5) ? "You smell something rotten." :
+ (temp_rand == 5) ? "The smell of rotting flesh makes you hungry." :
+ (temp_rand == 6) ? "You smell decay. Yum-yum."
+ : "Wow! There is something tasty in your inventory."),
+ MSGCH_ROTTEN_MEAT );
+ break;
+
+ default:
+ temp_rand = random2(8);
+ mpr( ((temp_rand < 5) ? "You smell something rotten." :
+ (temp_rand == 5) ? "The smell of rotting flesh makes you sick." :
+ (temp_rand == 6) ? "You smell decay. Yuck!"
+ : "Ugh! There is something really disgusting in your inventory."),
+ MSGCH_ROTTEN_MEAT );
+ break;
+ }
+ }
+ learned_something_new(TUT_ROTTEN_FOOD);
+ }
+ if (burden_changed_by_rot)
+ {
+ mpr("Your equipment suddenly weighs less.", MSGCH_ROTTEN_MEAT);
+ burden_change();
+ }
+}
+
+//---------------------------------------------------------------
+//
+// handle_time
+//
+// Do various time related actions...
+// This function is called about every 20 turns.
+//
+//---------------------------------------------------------------
+void handle_time( long time_delta )
+{
+ // BEGIN - Nasty things happen to people who spend too long in Hell:
+ if (player_in_hell() && coinflip())
+ hell_effects();
+
+ // Adjust the player's stats if s/he's diseased (or recovering).
+ if (!you.disease)
+ {
+ if (you.strength < you.max_strength && one_chance_in(100))
+ {
+ mpr("You feel your strength returning.", MSGCH_RECOVERY);
+ you.strength++;
+ you.redraw_strength = 1;
+ }
+
+ if (you.dex < you.max_dex && one_chance_in(100))
+ {
+ mpr("You feel your dexterity returning.", MSGCH_RECOVERY);
+ you.dex++;
+ you.redraw_dexterity = 1;
+ }
+
+ if (you.intel < you.max_intel && one_chance_in(100))
+ {
+ mpr("You feel your intelligence returning.", MSGCH_RECOVERY);
+ you.intel++;
+ you.redraw_intelligence = 1;
+ }
+ }
+ else
+ {
+ if (one_chance_in(30))
+ {
+ mpr("Your disease is taking its toll.", MSGCH_WARN);
+ lose_stat(STAT_RANDOM, 1, false, "disease");
+ }
+ }
+
+ // Adjust the player's stats if s/he has the deterioration mutation
+ if (you.mutation[MUT_DETERIORATION]
+ && random2(200) <= you.mutation[MUT_DETERIORATION] * 5 - 2)
+ {
+ lose_stat(STAT_RANDOM, 1, false, "deterioration mutation");
+ }
+
+ int added_contamination = 0;
+
+ // Account for mutagenic radiation. Invis and haste will give the
+ // player about .1 points per turn, mutagenic randarts will give
+ // about 1.5 points on average, so they can corrupt the player
+ // quite quickly. Wielding one for a short battle is OK, which is
+ // as things should be. -- GDL
+ if (you.duration[DUR_INVIS] && random2(10) < 6)
+ added_contamination++;
+
+ if (you.duration[DUR_HASTE] && !you.duration[DUR_BERSERKER]
+ && random2(10) < 6)
+ {
+ added_contamination++;
+ }
+
+ if (const int randart_glow = scan_randarts(RAP_MUTAGENIC))
+ {
+ // Reduced randart glow. Note that one randart will contribute
+ // 2 - 5 units of glow to randart_glow. A randart with a mutagen
+ // index of 2 does about 0.58 points of contamination per turn.
+ // A randart with a mutagen index of 5 does about 0.7 points of
+ // contamination per turn.
+
+ const int mean_glow = 500 + randart_glow * 40;
+ const int actual_glow = mean_glow / 2 + random2(mean_glow);
+ added_contamination += div_rand_round(actual_glow, 1000);
+ }
+
+ // we take off about .5 points per turn
+ if (!you.duration[DUR_INVIS] && !you.duration[DUR_HASTE] && coinflip())
+ added_contamination -= 1;
+
+ contaminate_player( added_contamination );
+
+ // only check for badness once every other turn
+ if (coinflip())
+ {
+ // [ds] Be less harsh with glow mutation; Brent and Mark Mackey note
+ // that the commented out random2(X) <= MC check was a bug. I've
+ // uncommented it but dropped the roll sharply from 150. (Brent used
+ // the original roll of 150 for 4.1.2, but I think players are
+ // sufficiently used to beta 26's unkindness that we can use a lower
+ // roll.)
+ if (you.magic_contamination >= 5
+ && random2(25) <= you.magic_contamination)
+ {
+ mpr("Your body shudders with the violent release of wild energies!", MSGCH_WARN);
+
+ // for particularly violent releases, make a little boom
+ if (you.magic_contamination >= 10 && coinflip())
+ {
+ struct bolt boom;
+ boom.type = dchar_glyph(DCHAR_FIRED_BURST);
+ boom.colour = BLACK;
+ boom.flavour = BEAM_RANDOM;
+ boom.target_x = you.x_pos;
+ boom.target_y = you.y_pos;
+ // Undead enjoy extra contamination explosion damage because
+ // the magical contamination has a harder time dissipating
+ // through non-living flesh. :-)
+ boom.damage =
+ dice_def( 3,
+ you.magic_contamination
+ * (you.is_undead? 4 : 2)
+ / 4 );
+ boom.thrower = KILL_MISC;
+ boom.aux_source = "a magical explosion";
+ boom.beam_source = NON_MONSTER;
+ boom.is_beam = false;
+ boom.is_tracer = false;
+ boom.is_explosion = true;
+ boom.name = "magical storm";
+
+ boom.ench_power = (you.magic_contamination * 5);
+ boom.ex_size = (you.magic_contamination / 15);
+ if (boom.ex_size > 9)
+ boom.ex_size = 9;
+
+ explosion(boom);
+ }
+
+ // we want to warp the player, not do good stuff!
+ if (one_chance_in(5))
+ mutate(RANDOM_MUTATION);
+ else
+ give_bad_mutation(coinflip());
+
+ // we're meaner now, what with explosions and whatnot, but
+ // we dial down the contamination a little faster if its actually
+ // mutating you. -- GDL
+ contaminate_player( -(random2(you.magic_contamination / 4) + 1) );
+ }
+ }
+
+ // Random chance to identify staff in hand based off of Spellcasting
+ // and an appropriate other spell skill... is 1/20 too fast?
+ if (you.equip[EQ_WEAPON] != -1
+ && you.inv[you.equip[EQ_WEAPON]].base_type == OBJ_STAVES
+ && !item_type_known( you.inv[you.equip[EQ_WEAPON]] )
+ && one_chance_in(20))
+ {
+ int total_skill = you.skills[SK_SPELLCASTING];
+
+ switch (you.inv[you.equip[EQ_WEAPON]].sub_type)
+ {
+ case STAFF_WIZARDRY:
+ case STAFF_ENERGY:
+ total_skill += you.skills[SK_SPELLCASTING];
+ break;
+ case STAFF_FIRE:
+ if (you.skills[SK_FIRE_MAGIC] > you.skills[SK_ICE_MAGIC])
+ total_skill += you.skills[SK_FIRE_MAGIC];
+ else
+ total_skill += you.skills[SK_ICE_MAGIC];
+ break;
+ case STAFF_COLD:
+ if (you.skills[SK_ICE_MAGIC] > you.skills[SK_FIRE_MAGIC])
+ total_skill += you.skills[SK_ICE_MAGIC];
+ else
+ total_skill += you.skills[SK_FIRE_MAGIC];
+ break;
+ case STAFF_AIR:
+ if (you.skills[SK_AIR_MAGIC] > you.skills[SK_EARTH_MAGIC])
+ total_skill += you.skills[SK_AIR_MAGIC];
+ else
+ total_skill += you.skills[SK_EARTH_MAGIC];
+ break;
+ case STAFF_EARTH:
+ if (you.skills[SK_EARTH_MAGIC] > you.skills[SK_AIR_MAGIC])
+ total_skill += you.skills[SK_EARTH_MAGIC];
+ else
+ total_skill += you.skills[SK_AIR_MAGIC];
+ break;
+ case STAFF_POISON:
+ total_skill += you.skills[SK_POISON_MAGIC];
+ break;
+ case STAFF_DEATH:
+ total_skill += you.skills[SK_NECROMANCY];
+ break;
+ case STAFF_CONJURATION:
+ total_skill += you.skills[SK_CONJURATIONS];
+ break;
+ case STAFF_ENCHANTMENT:
+ total_skill += you.skills[SK_ENCHANTMENTS];
+ break;
+ case STAFF_SUMMONING:
+ total_skill += you.skills[SK_SUMMONINGS];
+ break;
+ }
+
+ if (random2(100) < total_skill)
+ {
+ item_def& item = you.inv[you.equip[EQ_WEAPON]];
+ set_ident_flags( item, ISFLAG_IDENT_MASK );
+
+ mprf("You are wielding %s.", item.name(DESC_NOCAP_A).c_str());
+ more();
+
+ you.wield_change = true;
+ }
+ }
+
+ // Check to see if an upset god wants to do something to the player
+ // jmf: moved huge thing to religion.cc
+ handle_god_time();
+
+ if (you.mutation[MUT_SCREAM]
+ && (random2(100) <= 2 + you.mutation[MUT_SCREAM] * 3) )
+ {
+ yell(true);
+ }
+ else if (you.mutation[MUT_SLEEPINESS]
+ && random2(100) < you.mutation[MUT_SLEEPINESS] * 5)
+ {
+ you.put_to_sleep();
+ }
+
+ // Update all of the corpses and food chunks on the floor
+ update_corpses(time_delta);
+
+ rot_inventory_food(time_delta);
+
+ // exercise armour *xor* stealth skill: {dlb}
+ if (!player_light_armour(true))
+ {
+ if (random2(1000) <= item_mass( you.inv[you.equip[EQ_BODY_ARMOUR]] ))
+ return;
+
+ if (one_chance_in(6)) // lowered random roll from 7 to 6 -- bwross
+ exercise(SK_ARMOUR, 1);
+ }
+ else // exercise stealth skill:
+ {
+ if (you.burden_state != BS_UNENCUMBERED || you.duration[DUR_BERSERKER])
+ return;
+
+ if (you.special_wield == SPWLD_SHADOW)
+ return;
+
+ if (you.equip[EQ_BODY_ARMOUR] != -1
+ && random2( item_mass( you.inv[you.equip[EQ_BODY_ARMOUR]] )) >= 100)
+ {
+ return;
+ }
+
+ if (one_chance_in(18))
+ exercise(SK_STEALTH, 1);
+ }
+}
+
+//---------------------------------------------------------------
+//
+// update_level
+//
+// Update the level when the player returns to it.
+//
+//---------------------------------------------------------------
+void update_level( double elapsedTime )
+{
+ int m, i;
+ const int turns = static_cast<int>(elapsedTime / 10.0);
+
+#if DEBUG_DIAGNOSTICS
+ int mons_total = 0;
+
+ mprf(MSGCH_DIAGNOSTICS, "turns: %d", turns );
+#endif
+
+ update_corpses( elapsedTime );
+
+ dungeon_events.fire_event(
+ dgn_event(DET_TURN_ELAPSED, coord_def(0, 0), turns * 10));
+
+ for (m = 0; m < MAX_MONSTERS; m++)
+ {
+ struct monsters *mon = &menv[m];
+
+ if (mon->type == -1)
+ continue;
+
+#if DEBUG_DIAGNOSTICS
+ mons_total++;
+#endif
+
+ // following monsters don't get movement
+ if (mon->flags & MF_JUST_SUMMONED)
+ continue;
+
+ // XXX: Allow some spellcasting (like Healing and Teleport)? -- bwr
+ // const bool healthy = (mon->hit_points * 2 > mon->max_hit_points);
+
+ // This is the monster healing code, moved here from tag.cc:
+ if (monster_descriptor( mon->type, MDSC_REGENERATES )
+ || mon->type == MONS_PLAYER_GHOST)
+ {
+ heal_monster( mon, turns, false );
+ }
+ else
+ {
+ heal_monster( mon, (turns / 10), false );
+ }
+
+ if (turns >= 10)
+ mon->timeout_enchantments( turns / 10 );
+
+ // Don't move water, lava, or stationary monsters around
+ if (monster_habitat( mon->type ) != DNGN_FLOOR
+ || mons_is_stationary( mon ))
+ {
+ continue;
+ }
+
+ // Let sleeping monsters lie
+ if (mon->behaviour == BEH_SLEEP || mons_is_paralysed(mon))
+ continue;
+
+ const int range = (turns * mon->speed) / 10;
+ const int moves = (range > 50) ? 50 : range;
+
+ // const bool short_time = (range >= 5 + random2(10));
+ const bool long_time = (range >= (500 + roll_dice( 2, 500 )));
+
+ const bool ranged_attack = (mons_has_ranged_spell( mon )
+ || mons_has_ranged_attack( mon ));
+
+#if DEBUG_DIAGNOSTICS
+ // probably too annoying even for DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS,
+ "mon #%d: range %d; long %d; "
+ "pos (%d,%d); targ %d(%d,%d); flags %ld",
+ m, range, long_time, mon->x, mon->y,
+ mon->foe, mon->target_x, mon->target_y, mon->flags );
+#endif
+
+ if (range <= 0)
+ continue;
+
+ if (long_time
+ && (mon->behaviour == BEH_FLEE
+ || mon->behaviour == BEH_CORNERED
+ || testbits( mon->flags, MF_BATTY )
+ || ranged_attack
+ || coinflip()))
+ {
+ if (mon->behaviour != BEH_WANDER)
+ {
+ mon->behaviour = BEH_WANDER;
+ mon->foe = MHITNOT;
+ mon->target_x = 10 + random2( GXM - 10 );
+ mon->target_y = 10 + random2( GYM - 10 );
+ }
+ else
+ {
+ // monster will be sleeping after we move it
+ mon->behaviour = BEH_SLEEP;
+ }
+ }
+ else if (ranged_attack)
+ {
+ // if we're doing short time movement and the monster has a
+ // ranged attack (missile or spell), then the monster will
+ // flee to gain distance if its "too close", else it will
+ // just shift its position rather than charge the player. -- bwr
+ if (grid_distance(mon->x, mon->y, mon->target_x, mon->target_y) < 3)
+ {
+ mon->behaviour = BEH_FLEE;
+
+ // if the monster is on the target square, fleeing won't work
+ if (mon->x == mon->target_x && mon->y == mon->target_y)
+ {
+ if (you.x_pos != mon->x || you.y_pos != mon->y)
+ {
+ // flee from player's position if different
+ mon->target_x = you.x_pos;
+ mon->target_y = you.y_pos;
+ }
+ else
+ {
+ // randomize the target so we have a direction to flee
+ mon->target_x += (random2(3) - 1);
+ mon->target_y += (random2(3) - 1);
+ }
+ }
+
+#if DEBUG_DIAGNOSTICS
+ mpr( "backing off...", MSGCH_DIAGNOSTICS );
+#endif
+ }
+ else
+ {
+ shift_monster( mon, mon->x, mon->y );
+
+#if DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS, "shifted to (%d,%d)", mon->x, mon->y);
+#endif
+ continue;
+ }
+ }
+
+ coord_def pos(mon->pos());
+ // dirt simple movement:
+ for (i = 0; i < moves; i++)
+ {
+ coord_def inc(mon->target_pos() - pos);
+ inc = coord_def(sgn(inc.x), sgn(inc.y));
+
+ if (mon->behaviour == BEH_FLEE)
+ inc *= -1;
+
+ if (pos.x + inc.x < 0 || pos.x + inc.x >= GXM)
+ inc.x = 0;
+
+ if (pos.y + inc.y < 0 || pos.y + inc.y >= GYM)
+ inc.y = 0;
+
+ if (inc.origin())
+ break;
+
+ const coord_def next(pos + inc);
+ const dungeon_feature_type feat = grd(next);
+ if (grid_is_solid(feat)
+ || mgrd(next) != NON_MONSTER
+ || !monster_habitable_grid(mon, feat))
+ break;
+
+ pos = next;
+ }
+
+ if (!shift_monster( mon, pos.x, pos.y ))
+ shift_monster( mon, mon->x, mon->y );
+
+#if DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS, "moved to (%d,%d)", mon->x, mon->y );
+#endif
+ }
+
+#if DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS, "total monsters on level = %d", mons_total );
+#endif
+
+ for (i = 0; i < MAX_CLOUDS; i++)
+ delete_cloud( i );
+}
+
+//---------------------------------------------------------------
+//
+// update_corpses
+//
+// Update all of the corpses and food chunks on the floor. (The
+// elapsed time is a double because this is called when we re-
+// enter a level and a *long* time may have elapsed).
+//
+//---------------------------------------------------------------
+void update_corpses(double elapsedTime)
+{
+ int cx, cy;
+
+ if (elapsedTime <= 0.0)
+ return;
+
+ const long rot_time = static_cast<long>(elapsedTime / 20.0);
+
+ for (int c = 0; c < MAX_ITEMS; c++)
+ {
+ item_def &it = mitm[c];
+
+ if (!is_valid_item(it))
+ continue;
+
+ if (it.base_type != OBJ_CORPSES && it.base_type != OBJ_FOOD)
+ {
+ continue;
+ }
+
+ if (it.base_type == OBJ_CORPSES
+ && it.sub_type > CORPSE_SKELETON)
+ {
+ continue;
+ }
+
+ if (it.base_type == OBJ_FOOD && it.sub_type != FOOD_CHUNK)
+ {
+ continue;
+ }
+
+ if (rot_time >= it.special && !is_being_butchered(it))
+ {
+ if (it.base_type == OBJ_FOOD)
+ {
+ destroy_item(c);
+ }
+ else
+ {
+ if (it.sub_type == CORPSE_SKELETON
+ || !mons_skeleton( it.plus ))
+ {
+ destroy_item(c);
+ }
+ else
+ {
+ it.sub_type = CORPSE_SKELETON;
+ it.special = 200;
+ it.colour = LIGHTGREY;
+ }
+ }
+ }
+ else
+ {
+ ASSERT(rot_time < 256);
+ it.special -= rot_time;
+ }
+ }
+
+ int fountain_checks = static_cast<int>(elapsedTime / 1000.0);
+ if (random2(1000) < static_cast<int>(elapsedTime) % 1000)
+ fountain_checks += 1;
+
+ // dry fountains may start flowing again
+ if (fountain_checks > 0)
+ {
+ for (cx=0; cx<GXM; cx++)
+ {
+ for (cy=0; cy<GYM; cy++)
+ {
+ if (grd[cx][cy] > DNGN_SPARKLING_FOUNTAIN
+ && grd[cx][cy] < DNGN_PERMADRY_FOUNTAIN)
+ {
+ for (int i=0; i<fountain_checks; i++)
+ {
+ if (one_chance_in(100))
+ {
+ if (grd[cx][cy] > DNGN_SPARKLING_FOUNTAIN)
+ grd[cx][cy] =
+ static_cast<dungeon_feature_type>(
+ grd[cx][cy] - 1);
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/crawl-ref/source/effects.h b/crawl-ref/source/effects.h
index 0cdf176ad1..8078b5d50c 100644
--- a/crawl-ref/source/effects.h
+++ b/crawl-ref/source/effects.h
@@ -107,4 +107,8 @@ int torment_monsters(int x, int y, int pow, int caster);
bool forget_inventory(bool quiet = false);
+void update_corpses(double elapsedTime);
+void update_level(double elapsedTime);
+void handle_time( long time_delta );
+
#endif
diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc
index 049f410a39..442d166183 100644
--- a/crawl-ref/source/files.cc
+++ b/crawl-ref/source/files.cc
@@ -62,6 +62,7 @@
#include "debug.h"
#include "direct.h"
#include "dungeon.h"
+#include "effects.h"
#include "initfile.h"
#include "itemname.h"
#include "itemprop.h"
diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc
index e240a435ad..184a24eecc 100644
--- a/crawl-ref/source/items.cc
+++ b/crawl-ref/source/items.cc
@@ -38,8 +38,8 @@
#include "cloud.h"
#include "debug.h"
#include "delay.h"
-#include "direct.h"
#include "dgnevent.h"
+#include "direct.h"
#include "effects.h"
#include "food.h"
#include "hiscores.h"
@@ -63,8 +63,6 @@
#include "randart.h"
#include "religion.h"
#include "shopping.h"
-#include "skills.h"
-#include "spl-cast.h"
#include "spl-book.h"
#include "spl-util.h"
#include "stuff.h"
@@ -2029,807 +2027,6 @@ void drop(void)
start_delay( DELAY_MULTIDROP, items_for_multidrop.size() );
}
-//---------------------------------------------------------------
-//
-// update_corpses
-//
-// Update all of the corpses and food chunks on the floor. (The
-// elapsed time is a double because this is called when we re-
-// enter a level and a *long* time may have elapsed).
-//
-//---------------------------------------------------------------
-void update_corpses(double elapsedTime)
-{
- int cx, cy;
-
- if (elapsedTime <= 0.0)
- return;
-
- const long rot_time = static_cast<long>(elapsedTime / 20.0);
-
- for (int c = 0; c < MAX_ITEMS; c++)
- {
- item_def &it = mitm[c];
-
- if (!is_valid_item(it))
- continue;
-
- if (it.base_type != OBJ_CORPSES && it.base_type != OBJ_FOOD)
- {
- continue;
- }
-
- if (it.base_type == OBJ_CORPSES
- && it.sub_type > CORPSE_SKELETON)
- {
- continue;
- }
-
- if (it.base_type == OBJ_FOOD && it.sub_type != FOOD_CHUNK)
- {
- continue;
- }
-
- if (rot_time >= it.special && !is_being_butchered(it))
- {
- if (it.base_type == OBJ_FOOD)
- {
- destroy_item(c);
- }
- else
- {
- if (it.sub_type == CORPSE_SKELETON
- || !mons_skeleton( it.plus ))
- {
- destroy_item(c);
- }
- else
- {
- it.sub_type = CORPSE_SKELETON;
- it.special = 200;
- it.colour = LIGHTGREY;
- }
- }
- }
- else
- {
- ASSERT(rot_time < 256);
- it.special -= rot_time;
- }
- }
-
- int fountain_checks = static_cast<int>(elapsedTime / 1000.0);
- if (random2(1000) < static_cast<int>(elapsedTime) % 1000)
- fountain_checks += 1;
-
- // dry fountains may start flowing again
- if (fountain_checks > 0)
- {
- for (cx=0; cx<GXM; cx++)
- {
- for (cy=0; cy<GYM; cy++)
- {
- if (grd[cx][cy] > DNGN_SPARKLING_FOUNTAIN
- && grd[cx][cy] < DNGN_PERMADRY_FOUNTAIN)
- {
- for (int i=0; i<fountain_checks; i++)
- {
- if (one_chance_in(100))
- {
- if (grd[cx][cy] > DNGN_SPARKLING_FOUNTAIN)
- grd[cx][cy] =
- static_cast<dungeon_feature_type>(
- grd[cx][cy] - 1);
- }
- }
- }
- }
- }
- }
-}
-
-//---------------------------------------------------------------
-//
-// update_level
-//
-// Update the level when the player returns to it.
-//
-//---------------------------------------------------------------
-void update_level( double elapsedTime )
-{
- int m, i;
- const int turns = static_cast<int>(elapsedTime / 10.0);
-
-#if DEBUG_DIAGNOSTICS
- int mons_total = 0;
-
- mprf(MSGCH_DIAGNOSTICS, "turns: %d", turns );
-#endif
-
- update_corpses( elapsedTime );
-
- dungeon_events.fire_event(
- dgn_event(DET_TURN_ELAPSED, coord_def(0, 0), turns * 10));
-
- for (m = 0; m < MAX_MONSTERS; m++)
- {
- struct monsters *mon = &menv[m];
-
- if (mon->type == -1)
- continue;
-
-#if DEBUG_DIAGNOSTICS
- mons_total++;
-#endif
-
- // following monsters don't get movement
- if (mon->flags & MF_JUST_SUMMONED)
- continue;
-
- // XXX: Allow some spellcasting (like Healing and Teleport)? -- bwr
- // const bool healthy = (mon->hit_points * 2 > mon->max_hit_points);
-
- // This is the monster healing code, moved here from tag.cc:
- if (monster_descriptor( mon->type, MDSC_REGENERATES )
- || mon->type == MONS_PLAYER_GHOST)
- {
- heal_monster( mon, turns, false );
- }
- else
- {
- heal_monster( mon, (turns / 10), false );
- }
-
- if (turns >= 10)
- mon->timeout_enchantments( turns / 10 );
-
- // Don't move water, lava, or stationary monsters around
- if (monster_habitat( mon->type ) != DNGN_FLOOR
- || mons_is_stationary( mon ))
- {
- continue;
- }
-
- // Let sleeping monsters lie
- if (mon->behaviour == BEH_SLEEP || mons_is_paralysed(mon))
- continue;
-
- const int range = (turns * mon->speed) / 10;
- const int moves = (range > 50) ? 50 : range;
-
- // const bool short_time = (range >= 5 + random2(10));
- const bool long_time = (range >= (500 + roll_dice( 2, 500 )));
-
- const bool ranged_attack = (mons_has_ranged_spell( mon )
- || mons_has_ranged_attack( mon ));
-
-#if DEBUG_DIAGNOSTICS
- // probably too annoying even for DEBUG_DIAGNOSTICS
- mprf(MSGCH_DIAGNOSTICS,
- "mon #%d: range %d; long %d; "
- "pos (%d,%d); targ %d(%d,%d); flags %ld",
- m, range, long_time, mon->x, mon->y,
- mon->foe, mon->target_x, mon->target_y, mon->flags );
-#endif
-
- if (range <= 0)
- continue;
-
- if (long_time
- && (mon->behaviour == BEH_FLEE
- || mon->behaviour == BEH_CORNERED
- || testbits( mon->flags, MF_BATTY )
- || ranged_attack
- || coinflip()))
- {
- if (mon->behaviour != BEH_WANDER)
- {
- mon->behaviour = BEH_WANDER;
- mon->foe = MHITNOT;
- mon->target_x = 10 + random2( GXM - 10 );
- mon->target_y = 10 + random2( GYM - 10 );
- }
- else
- {
- // monster will be sleeping after we move it
- mon->behaviour = BEH_SLEEP;
- }
- }
- else if (ranged_attack)
- {
- // if we're doing short time movement and the monster has a
- // ranged attack (missile or spell), then the monster will
- // flee to gain distance if its "too close", else it will
- // just shift its position rather than charge the player. -- bwr
- if (grid_distance(mon->x, mon->y, mon->target_x, mon->target_y) < 3)
- {
- mon->behaviour = BEH_FLEE;
-
- // if the monster is on the target square, fleeing won't work
- if (mon->x == mon->target_x && mon->y == mon->target_y)
- {
- if (you.x_pos != mon->x || you.y_pos != mon->y)
- {
- // flee from player's position if different
- mon->target_x = you.x_pos;
- mon->target_y = you.y_pos;
- }
- else
- {
- // randomize the target so we have a direction to flee
- mon->target_x += (random2(3) - 1);
- mon->target_y += (random2(3) - 1);
- }
- }
-
-#if DEBUG_DIAGNOSTICS
- mpr( "backing off...", MSGCH_DIAGNOSTICS );
-#endif
- }
- else
- {
- shift_monster( mon, mon->x, mon->y );
-
-#if DEBUG_DIAGNOSTICS
- mprf(MSGCH_DIAGNOSTICS, "shifted to (%d,%d)", mon->x, mon->y);
-#endif
- continue;
- }
- }
-
- coord_def pos(mon->pos());
- // dirt simple movement:
- for (i = 0; i < moves; i++)
- {
- coord_def inc(mon->target_pos() - pos);
- inc = coord_def(sgn(inc.x), sgn(inc.y));
-
- if (mon->behaviour == BEH_FLEE)
- inc *= -1;
-
- if (pos.x + inc.x < 0 || pos.x + inc.x >= GXM)
- inc.x = 0;
-
- if (pos.y + inc.y < 0 || pos.y + inc.y >= GYM)
- inc.y = 0;
-
- if (inc.origin())
- break;
-
- const coord_def next(pos + inc);
- const dungeon_feature_type feat = grd(next);
- if (grid_is_solid(feat)
- || mgrd(next) != NON_MONSTER
- || !monster_habitable_grid(mon, feat))
- break;
-
- pos = next;
- }
-
- if (!shift_monster( mon, pos.x, pos.y ))
- shift_monster( mon, mon->x, mon->y );
-
-#if DEBUG_DIAGNOSTICS
- mprf(MSGCH_DIAGNOSTICS, "moved to (%d,%d)", mon->x, mon->y );
-#endif
- }
-
-#if DEBUG_DIAGNOSTICS
- mprf(MSGCH_DIAGNOSTICS, "total monsters on level = %d", mons_total );
-#endif
-
- for (i = 0; i < MAX_CLOUDS; i++)
- delete_cloud( i );
-}
-
-static void hell_effects()
-{
- int temp_rand = random2(17);
- spschool_flag_type which_miscast = SPTYP_RANDOM;
- bool summon_instead = false;
- monster_type which_beastie = MONS_PROGRAM_BUG;
-
- mpr((temp_rand == 0) ? "\"You will not leave this place.\"" :
- (temp_rand == 1) ? "\"Die, mortal!\"" :
- (temp_rand == 2) ? "\"We do not forgive those who trespass against us!\"" :
- (temp_rand == 3) ? "\"Trespassers are not welcome here!\"" :
- (temp_rand == 4) ? "\"You do not belong in this place!\"" :
- (temp_rand == 5) ? "\"Leave now, before it is too late!\"" :
- (temp_rand == 6) ? "\"We have you now!\"" :
- // plain messages
- (temp_rand == 7) ? (player_can_smell()) ? "You smell brimstone." :
- "Brimstone rains from above." :
- (temp_rand == 8) ? "You feel lost and a long, long way from home..." :
- (temp_rand == 9) ? "You shiver with fear." :
- // warning
- (temp_rand == 10) ? "You feel a terrible foreboding..." :
- (temp_rand == 11) ? "Something frightening happens." :
- (temp_rand == 12) ? "You sense an ancient evil watching you..." :
- (temp_rand == 13) ? "You suddenly feel all small and vulnerable." :
- (temp_rand == 14) ? "You sense a hostile presence." :
- // sounds
- (temp_rand == 15) ? "A gut-wrenching scream fills the air!" :
- (temp_rand == 16) ? "You hear words spoken in a strange and terrible language..."
- : "You hear diabolical laughter!",
- (temp_rand < 7 ? MSGCH_TALK :
- temp_rand < 10 ? MSGCH_PLAIN :
- temp_rand < 15 ? MSGCH_WARN
- : MSGCH_SOUND) );
-
- temp_rand = random2(27);
-
- if (temp_rand > 17) // 9 in 27 odds {dlb}
- {
- temp_rand = random2(8);
-
- if (temp_rand > 3) // 4 in 8 odds {dlb}
- which_miscast = SPTYP_NECROMANCY;
- else if (temp_rand > 1) // 2 in 8 odds {dlb}
- which_miscast = SPTYP_SUMMONING;
- else if (temp_rand > 0) // 1 in 8 odds {dlb}
- which_miscast = SPTYP_CONJURATION;
- else // 1 in 8 odds {dlb}
- which_miscast = SPTYP_ENCHANTMENT;
-
- miscast_effect( which_miscast, 4 + random2(6), random2avg(97, 3),
- 100, "the effects of Hell" );
- }
- else if (temp_rand > 7) // 10 in 27 odds {dlb}
- {
- // 60:40 miscast:summon split {dlb}
- summon_instead = (random2(5) > 2);
-
- switch (you.where_are_you)
- {
- case BRANCH_DIS:
- if (summon_instead)
- which_beastie = summon_any_demon(DEMON_GREATER);
- else
- which_miscast = SPTYP_EARTH;
- break;
- case BRANCH_GEHENNA:
- if (summon_instead)
- which_beastie = MONS_FIEND;
- else
- which_miscast = SPTYP_FIRE;
- break;
- case BRANCH_COCYTUS:
- if (summon_instead)
- which_beastie = MONS_ICE_FIEND;
- else
- which_miscast = SPTYP_ICE;
- break;
- case BRANCH_TARTARUS:
- if (summon_instead)
- which_beastie = MONS_SHADOW_FIEND;
- else
- which_miscast = SPTYP_NECROMANCY;
- break;
- default: // this is to silence gcc compiler warnings {dlb}
- if (summon_instead)
- which_beastie = MONS_FIEND;
- else
- which_miscast = SPTYP_NECROMANCY;
- break;
- }
-
- if (summon_instead)
- {
- create_monster( which_beastie, 0, BEH_HOSTILE, you.x_pos,
- you.y_pos, MHITYOU, 250 );
- }
- else
- {
- miscast_effect( which_miscast, 4 + random2(6),
- random2avg(97, 3), 100, "the effects of Hell" );
- }
- }
-
- // NB: no "else" - 8 in 27 odds that nothing happens through
- // first chain {dlb}
- // also note that the following is distinct from and in
- // addition to the above chain:
-
- // try to summon at least one and up to five random monsters {dlb}
- if (one_chance_in(3))
- {
- create_monster( RANDOM_MONSTER, 0, BEH_HOSTILE,
- you.x_pos, you.y_pos, MHITYOU, 250 );
-
- for (int i = 0; i < 4; i++)
- {
- if (one_chance_in(3))
- {
- create_monster( RANDOM_MONSTER, 0, BEH_HOSTILE,
- you.x_pos, you.y_pos, MHITYOU, 250 );
- }
- }
- }
-}
-
-static void rot_inventory_food(long time_delta)
-{
- // Update all of the corpses and food chunks in the player's
- // inventory {should be moved elsewhere - dlb}
-
- bool burden_changed_by_rot = false;
- bool new_rotting_item = false;
- for (int i = 0; i < ENDOFPACK; i++)
- {
- if (you.inv[i].quantity < 1)
- continue;
-
- if (you.inv[i].base_type != OBJ_CORPSES && you.inv[i].base_type != OBJ_FOOD)
- continue;
-
- if (you.inv[i].base_type == OBJ_CORPSES
- && you.inv[i].sub_type > CORPSE_SKELETON)
- {
- continue;
- }
-
- if (you.inv[i].base_type == OBJ_FOOD && you.inv[i].sub_type != FOOD_CHUNK)
- continue;
-
- if ((time_delta / 20) >= you.inv[i].special)
- {
- if (you.inv[i].base_type == OBJ_FOOD)
- {
- if (you.equip[EQ_WEAPON] == i)
- unwield_item();
-
- destroy_item(you.inv[i]);
- burden_changed_by_rot = true;
- continue;
- }
-
- if (you.inv[i].sub_type == CORPSE_SKELETON)
- continue; // carried skeletons are not destroyed
-
- if (!mons_skeleton( you.inv[i].plus ))
- {
- if (you.equip[EQ_WEAPON] == i)
- unwield_item();
-
- destroy_item(you.inv[i]);
- burden_changed_by_rot = true;
- continue;
- }
-
- you.inv[i].sub_type = CORPSE_SKELETON;
- you.inv[i].special = 0;
- you.inv[i].colour = LIGHTGREY;
- you.wield_change = true;
- burden_changed_by_rot = true;
- continue;
- }
-
- you.inv[i].special -= (time_delta / 20);
-
- if (you.inv[i].special < 100 && (you.inv[i].special + (time_delta / 20)>=100))
- {
- new_rotting_item = true;
- }
- }
-
- //mv: messages when chunks/corpses become rotten
- if (new_rotting_item)
- {
- // XXX: should probably still notice?
- // Races that can't smell don't care, and trolls are stupid and
- // don't care.
- if (player_can_smell() && you.species != SP_TROLL)
- {
- int temp_rand = 0; // Grr.
- switch (you.mutation[MUT_SAPROVOROUS])
- {
- // level 1 and level 2 saprovores aren't so touchy
- case 1:
- case 2:
- temp_rand = random2(8);
- mpr( ((temp_rand < 5) ? "You smell something rotten." :
- (temp_rand == 5) ? "You smell rotting flesh." :
- (temp_rand == 6) ? "You smell decay."
- : "There is something rotten in your inventory."),
- MSGCH_ROTTEN_MEAT );
- break;
-
- // level 3 saprovores like it
- case 3:
- temp_rand = random2(8);
- mpr( ((temp_rand < 5) ? "You smell something rotten." :
- (temp_rand == 5) ? "The smell of rotting flesh makes you hungry." :
- (temp_rand == 6) ? "You smell decay. Yum-yum."
- : "Wow! There is something tasty in your inventory."),
- MSGCH_ROTTEN_MEAT );
- break;
-
- default:
- temp_rand = random2(8);
- mpr( ((temp_rand < 5) ? "You smell something rotten." :
- (temp_rand == 5) ? "The smell of rotting flesh makes you sick." :
- (temp_rand == 6) ? "You smell decay. Yuck!"
- : "Ugh! There is something really disgusting in your inventory."),
- MSGCH_ROTTEN_MEAT );
- break;
- }
- }
- learned_something_new(TUT_ROTTEN_FOOD);
- }
- if (burden_changed_by_rot)
- {
- mpr("Your equipment suddenly weighs less.", MSGCH_ROTTEN_MEAT);
- burden_change();
- }
-}
-
-//---------------------------------------------------------------
-//
-// handle_time
-//
-// Do various time related actions...
-// This function is called about every 20 turns.
-//
-//---------------------------------------------------------------
-void handle_time( long time_delta )
-{
- // BEGIN - Nasty things happen to people who spend too long in Hell:
- if (player_in_hell() && coinflip())
- hell_effects();
-
- // Adjust the player's stats if s/he's diseased (or recovering).
- if (!you.disease)
- {
- if (you.strength < you.max_strength && one_chance_in(100))
- {
- mpr("You feel your strength returning.", MSGCH_RECOVERY);
- you.strength++;
- you.redraw_strength = 1;
- }
-
- if (you.dex < you.max_dex && one_chance_in(100))
- {
- mpr("You feel your dexterity returning.", MSGCH_RECOVERY);
- you.dex++;
- you.redraw_dexterity = 1;
- }
-
- if (you.intel < you.max_intel && one_chance_in(100))
- {
- mpr("You feel your intelligence returning.", MSGCH_RECOVERY);
- you.intel++;
- you.redraw_intelligence = 1;
- }
- }
- else
- {
- if (one_chance_in(30))
- {
- mpr("Your disease is taking its toll.", MSGCH_WARN);
- lose_stat(STAT_RANDOM, 1, false, "disease");
- }
- }
-
- // Adjust the player's stats if s/he has the deterioration mutation
- if (you.mutation[MUT_DETERIORATION]
- && random2(200) <= you.mutation[MUT_DETERIORATION] * 5 - 2)
- {
- lose_stat(STAT_RANDOM, 1, false, "deterioration mutation");
- }
-
- int added_contamination = 0;
-
- // Account for mutagenic radiation. Invis and haste will give the
- // player about .1 points per turn, mutagenic randarts will give
- // about 1.5 points on average, so they can corrupt the player
- // quite quickly. Wielding one for a short battle is OK, which is
- // as things should be. -- GDL
- if (you.duration[DUR_INVIS] && random2(10) < 6)
- added_contamination++;
-
- if (you.duration[DUR_HASTE] && !you.duration[DUR_BERSERKER]
- && random2(10) < 6)
- {
- added_contamination++;
- }
-
- if (const int randart_glow = scan_randarts(RAP_MUTAGENIC))
- {
- // Reduced randart glow. Note that one randart will contribute
- // 2 - 5 units of glow to randart_glow. A randart with a mutagen
- // index of 2 does about 0.58 points of contamination per turn.
- // A randart with a mutagen index of 5 does about 0.7 points of
- // contamination per turn.
-
- const int mean_glow = 500 + randart_glow * 40;
- const int actual_glow = mean_glow / 2 + random2(mean_glow);
- added_contamination += div_rand_round(actual_glow, 1000);
- }
-
- // we take off about .5 points per turn
- if (!you.duration[DUR_INVIS] && !you.duration[DUR_HASTE] && coinflip())
- added_contamination -= 1;
-
- contaminate_player( added_contamination );
-
- // only check for badness once every other turn
- if (coinflip())
- {
- // [ds] Be less harsh with glow mutation; Brent and Mark Mackey note
- // that the commented out random2(X) <= MC check was a bug. I've
- // uncommented it but dropped the roll sharply from 150. (Brent used
- // the original roll of 150 for 4.1.2, but I think players are
- // sufficiently used to beta 26's unkindness that we can use a lower
- // roll.)
- if (you.magic_contamination >= 5
- && random2(25) <= you.magic_contamination)
- {
- mpr("Your body shudders with the violent release of wild energies!", MSGCH_WARN);
-
- // for particularly violent releases, make a little boom
- if (you.magic_contamination >= 10 && coinflip())
- {
- struct bolt boom;
- boom.type = dchar_glyph(DCHAR_FIRED_BURST);
- boom.colour = BLACK;
- boom.flavour = BEAM_RANDOM;
- boom.target_x = you.x_pos;
- boom.target_y = you.y_pos;
- // Undead enjoy extra contamination explosion damage because
- // the magical contamination has a harder time dissipating
- // through non-living flesh. :-)
- boom.damage =
- dice_def( 3,
- you.magic_contamination
- * (you.is_undead? 4 : 2)
- / 4 );
- boom.thrower = KILL_MISC;
- boom.aux_source = "a magical explosion";
- boom.beam_source = NON_MONSTER;
- boom.is_beam = false;
- boom.is_tracer = false;
- boom.is_explosion = true;
- boom.name = "magical storm";
-
- boom.ench_power = (you.magic_contamination * 5);
- boom.ex_size = (you.magic_contamination / 15);
- if (boom.ex_size > 9)
- boom.ex_size = 9;
-
- explosion(boom);
- }
-
- // we want to warp the player, not do good stuff!
- if (one_chance_in(5))
- mutate(RANDOM_MUTATION);
- else
- give_bad_mutation(coinflip());
-
- // we're meaner now, what with explosions and whatnot, but
- // we dial down the contamination a little faster if its actually
- // mutating you. -- GDL
- contaminate_player( -(random2(you.magic_contamination / 4) + 1) );
- }
- }
-
- // Random chance to identify staff in hand based off of Spellcasting
- // and an appropriate other spell skill... is 1/20 too fast?
- if (you.equip[EQ_WEAPON] != -1
- && you.inv[you.equip[EQ_WEAPON]].base_type == OBJ_STAVES
- && !item_type_known( you.inv[you.equip[EQ_WEAPON]] )
- && one_chance_in(20))
- {
- int total_skill = you.skills[SK_SPELLCASTING];
-
- switch (you.inv[you.equip[EQ_WEAPON]].sub_type)
- {
- case STAFF_WIZARDRY:
- case STAFF_ENERGY:
- total_skill += you.skills[SK_SPELLCASTING];
- break;
- case STAFF_FIRE:
- if (you.skills[SK_FIRE_MAGIC] > you.skills[SK_ICE_MAGIC])
- total_skill += you.skills[SK_FIRE_MAGIC];
- else
- total_skill += you.skills[SK_ICE_MAGIC];
- break;
- case STAFF_COLD:
- if (you.skills[SK_ICE_MAGIC] > you.skills[SK_FIRE_MAGIC])
- total_skill += you.skills[SK_ICE_MAGIC];
- else
- total_skill += you.skills[SK_FIRE_MAGIC];
- break;
- case STAFF_AIR:
- if (you.skills[SK_AIR_MAGIC] > you.skills[SK_EARTH_MAGIC])
- total_skill += you.skills[SK_AIR_MAGIC];
- else
- total_skill += you.skills[SK_EARTH_MAGIC];
- break;
- case STAFF_EARTH:
- if (you.skills[SK_EARTH_MAGIC] > you.skills[SK_AIR_MAGIC])
- total_skill += you.skills[SK_EARTH_MAGIC];
- else
- total_skill += you.skills[SK_AIR_MAGIC];
- break;
- case STAFF_POISON:
- total_skill += you.skills[SK_POISON_MAGIC];
- break;
- case STAFF_DEATH:
- total_skill += you.skills[SK_NECROMANCY];
- break;
- case STAFF_CONJURATION:
- total_skill += you.skills[SK_CONJURATIONS];
- break;
- case STAFF_ENCHANTMENT:
- total_skill += you.skills[SK_ENCHANTMENTS];
- break;
- case STAFF_SUMMONING:
- total_skill += you.skills[SK_SUMMONINGS];
- break;
- }
-
- if (random2(100) < total_skill)
- {
- item_def& item = you.inv[you.equip[EQ_WEAPON]];
- set_ident_flags( item, ISFLAG_IDENT_MASK );
-
- mprf("You are wielding %s.", item.name(DESC_NOCAP_A).c_str());
- more();
-
- you.wield_change = true;
- }
- }
-
- // Check to see if an upset god wants to do something to the player
- // jmf: moved huge thing to religion.cc
- handle_god_time();
-
- if (you.mutation[MUT_SCREAM]
- && (random2(100) <= 2 + you.mutation[MUT_SCREAM] * 3) )
- {
- yell(true);
- }
- else if (you.mutation[MUT_SLEEPINESS]
- && random2(100) < you.mutation[MUT_SLEEPINESS] * 5)
- {
- you.put_to_sleep();
- }
-
- // Update all of the corpses and food chunks on the floor
- update_corpses(time_delta);
-
- rot_inventory_food(time_delta);
-
- // exercise armour *xor* stealth skill: {dlb}
- if (!player_light_armour(true))
- {
- if (random2(1000) <= item_mass( you.inv[you.equip[EQ_BODY_ARMOUR]] ))
- return;
-
- if (one_chance_in(6)) // lowered random roll from 7 to 6 -- bwross
- exercise(SK_ARMOUR, 1);
- }
- else // exercise stealth skill:
- {
- if (you.burden_state != BS_UNENCUMBERED || you.duration[DUR_BERSERKER])
- return;
-
- if (you.special_wield == SPWLD_SHADOW)
- return;
-
- if (you.equip[EQ_BODY_ARMOUR] != -1
- && random2( item_mass( you.inv[you.equip[EQ_BODY_ARMOUR]] )) >= 100)
- {
- return;
- }
-
- if (one_chance_in(18))
- exercise(SK_STEALTH, 1);
- }
-
- return;
-} // end handle_time()
-
static void autoinscribe_item( item_def& item )
{
std::string iname = item.name(DESC_INVENTORY);
diff --git a/crawl-ref/source/items.h b/crawl-ref/source/items.h
index 550acb5461..e448383694 100644
--- a/crawl-ref/source/items.h
+++ b/crawl-ref/source/items.h
@@ -115,21 +115,6 @@ bool move_top_item( int src_x, int src_y, int dest_x, int dest_y );
* *********************************************************************** */
void drop(void);
-
-// last updated: 08jun2000 {dlb}
-/* ***********************************************************************
- * called from: files - items
- * *********************************************************************** */
-void update_corpses(double elapsedTime);
-void update_level(double elapsedTime);
-
-
-// last updated: 08jun2000 {dlb}
-/* ***********************************************************************
- * called from: acr
- * *********************************************************************** */
-void handle_time( long time_delta );
-
// last updated: 08jun2000 {dlb}
/* ***********************************************************************
* called from: command food item_use shopping spl-book transfor