summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/mon-util.cc49
-rw-r--r--crawl-ref/source/monstuff.cc169
2 files changed, 71 insertions, 147 deletions
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index 8428a4f0a7..ed5f52174d 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -3896,28 +3896,20 @@ void monsters::add_enchantment_effect(const mon_enchant &ench, bool quiet)
break;
case ENCH_HASTE:
- {
- int old_speed = speed;
if (speed >= 100)
speed = 100 + ((speed - 100) * 2);
else
speed *= 2;
- ench_countdown = div_rand_round(ench_countdown * speed, old_speed);
break;
- }
case ENCH_SLOW:
- {
- int old_speed = speed;
if (speed >= 100)
speed = 100 + ((speed - 100) / 2);
else
speed /= 2;
- ench_countdown = div_rand_round(ench_countdown * speed, old_speed);
break;
- }
case ENCH_SUBMERGED:
if (type == MONS_AIR_ELEMENTAL && mons_near(this) && !quiet)
@@ -3952,28 +3944,20 @@ void monsters::remove_enchantment_effect(const mon_enchant &me, bool quiet)
break;
case ENCH_HASTE:
- {
- int old_speed = speed;
if (speed >= 100)
speed = 100 + ((speed - 100) / 2);
else
speed /= 2;
- ench_countdown = div_rand_round(ench_countdown * speed, old_speed);
break;
- }
case ENCH_SLOW:
- {
- int old_speed = speed;
if (speed >= 100)
speed = 100 + ((speed - 100) * 2);
else
speed *= 2;
- ench_countdown = div_rand_round(ench_countdown * speed, old_speed);
break;
- }
case ENCH_PARALYSIS:
if (!quiet)
@@ -4235,11 +4219,11 @@ std::string monsters::describe_enchantments() const
return (oss.str());
}
-// used to adjust time durations in handle_enchantment() for monster speed
+// used to adjust time durations in calc_duration() for monster speed
static inline int mod_speed( int val, int speed )
{
if (!speed)
- speed = you.time_taken;
+ speed = 10;
const int modded = (speed ? (val * 10) / speed : val);
return (modded? modded : 1);
}
@@ -4247,9 +4231,8 @@ static inline int mod_speed( int val, int speed )
bool monsters::decay_enchantment(const mon_enchant &me, bool decay_degree)
{
// Faster monsters can wiggle out of the net more quickly.
- const int spd = (speed == 0) ? you.time_taken :
- (me.ench == ENCH_HELD) ? speed :
- 10;
+ const int spd = (me.ench == ENCH_HELD) ? speed :
+ 10;
const int actdur = speed_to_duration(spd);
if (lose_ench_duration(me, actdur))
return (true);
@@ -4284,7 +4267,7 @@ bool monsters::decay_enchantment(const mon_enchant &me, bool decay_degree)
void monsters::apply_enchantment(const mon_enchant &me)
{
- const int spd = speed == 0? you.time_taken : 10;
+ const int spd = 10;
switch (me.ench)
{
case ENCH_BERSERK:
@@ -4485,11 +4468,11 @@ void monsters::apply_enchantment(const mon_enchant &me)
break;
else if (((type == MONS_ELECTRICAL_EEL
|| type == MONS_LAVA_SNAKE)
- && (random2(1000) < mod_speed( 20, spd )
+ && (random2(1000) < 20
|| (mons_near(this)
&& hit_points == max_hit_points
&& !one_chance_in(10))))
- || random2(2000) < mod_speed(10, spd)
+ || random2(2000) < 10
|| (mons_near(this)
&& hit_points == max_hit_points
&& !one_chance_in(5)))
@@ -4509,12 +4492,6 @@ void monsters::apply_enchantment(const mon_enchant &me)
if (mons_res_poison(this) < 0)
dam += roll_dice( 2, poisonval ) - 1;
- // We adjust damage for monster speed (since this is applied
- // only when the monster moves), and we handle the factional
- // part as well (so that speed 30 creatures will take damage).
- dam *= 10;
- dam = (dam / spd) + ((random2(spd) < (dam % spd)) ? 1 : 0);
-
if (dam > 0)
{
hurt_monster( this, dam );
@@ -4539,7 +4516,7 @@ void monsters::apply_enchantment(const mon_enchant &me)
case ENCH_ROT:
{
if (hit_points > 1
- && random2(1000) < mod_speed( 333, spd ))
+ && random2(1000) < 333)
{
hurt_monster(this, 1);
if (hit_points < max_hit_points && coinflip())
@@ -4558,12 +4535,6 @@ void monsters::apply_enchantment(const mon_enchant &me)
if (mons_res_fire( this ) < 0)
dam += roll_dice( 2, 5 ) - 1;
- // We adjust damage for monster speed (since this is applied
- // only when the monster moves), and we handle the factional
- // part as well (so that speed 30 creatures will take damage).
- dam *= 10;
- dam = (dam / spd) + ((random2(spd) < (dam % spd)) ? 1 : 0);
-
if (dam > 0)
{
hurt_monster( this, dam );
@@ -4593,7 +4564,7 @@ void monsters::apply_enchantment(const mon_enchant &me)
case ENCH_GLOWING_SHAPESHIFTER: // this ench never runs out
// number of actions is fine for shapeshifters
if (type == MONS_GLOWING_SHAPESHIFTER
- || random2(1000) < mod_speed( 250, spd ))
+ || random2(1000) < 250)
{
monster_polymorph(this, RANDOM_MONSTER, PPT_SAME);
}
@@ -4601,7 +4572,7 @@ void monsters::apply_enchantment(const mon_enchant &me)
case ENCH_SHAPESHIFTER: // this ench never runs out
if (type == MONS_SHAPESHIFTER
- || random2(1000) < mod_speed( 1000 / ((15 * hit_dice) / 5), spd ))
+ || random2(1000) < ( 1000 / ((15 * hit_dice) / 5)))
{
monster_polymorph(this, RANDOM_MONSTER, PPT_SAME);
}
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index b3a2eb4995..15efbd4177 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -1171,7 +1171,6 @@ bool monster_polymorph( monsters *monster, monster_type targetc,
const int old_hp_max = monster->max_hit_points;
const bool old_mon_caught = mons_is_caught(monster);
const char old_ench_countdown = monster->ench_countdown;
- const int old_speed = monster->speed;
/* deal with mons_sec */
monster->type = targetc;
@@ -1187,8 +1186,7 @@ bool monster_polymorph( monsters *monster, monster_type targetc,
monster->add_ench(abj);
monster->add_ench(shifter);
- monster->ench_countdown = old_ench_countdown * old_speed
- / monster->speed;
+ monster->ench_countdown = old_ench_countdown;
if (mons_class_flag( monster->type, M_INVIS ))
monster->add_ench(ENCH_INVIS);
@@ -2139,40 +2137,6 @@ bool simple_monster_message(const monsters *monster, const char *event,
return (false);
} // end simple_monster_message()
-static bool handle_enchantment(monsters *monster)
-{
- // Yes, this is the speed we want. This function will be called in
- // two circumstances: (1) the monster can move and has enough energy,
- // and (2) the monster cannot move (speed == 0) and the monster loop
- // is running.
- //
- // In the first case we in the player's time by keeping track of
- // how much energy the monster has expended since the last time
- // apply_enchantments() was called, and calling it each time that
- // it equals or exceeds the monsters speed. For example, a bat
- // gets 30 energy points for every 10 the player gets, and each
- // time it spends 30 energy points apply_enchantments() is called.
- //
- // In the second case, we're hacking things so that plants can suffer
- // from sticky flame. The rate of call in this case is once every
- // player action... so the time_taken by the player is the ratio to
- // the absolute time frame.
- //
- // -- bwr
- if (monster->speed == 0)
- monster->apply_enchantments();
- else
- {
- while (monster->ench_countdown <= 0)
- {
- monster->apply_enchantments();
- monster->ench_countdown += monster->speed;
- }
- }
-
- return (!monster->alive());
-} // end handle_enchantment()
-
//---------------------------------------------------------------
//
// handle_movement
@@ -3930,34 +3894,17 @@ static void monster_regenerate(monsters *monster)
}
}
-static void handle_ench_countdown(monsters *monster, int &old_energy)
+static void swim_or_move_energy(monsters *mon)
{
- // Paranoia
- if (monster->speed_increment >= old_energy)
+ monsterentry *entry = get_monster_data(mon->type);
+ dungeon_feature_type feat = grd[mon->x][mon->y];
+ if (feat >= DNGN_LAVA && feat <= DNGN_SHALLOW_WATER
+ && !mon->airborne())
{
-#if DEBUG
- if (monster->speed_increment == old_energy)
- mprf(MSGCH_DIAGNOSTICS,
- "Monster '%s' has same energy as last iteration.",
- monster->name(DESC_PLAIN).c_str(), true);
- else
- mprf(MSGCH_DIAGNOSTICS,
- "Monster '%s' has MORE energy than last iteration.",
- monster->name(DESC_PLAIN).c_str(), true);
-#endif
-
- monster->speed_increment = old_energy - 10;
- monster->ench_countdown -= 10;
+ mon->speed_increment -= entry->energy_usage.swim;
}
else
- {
- if (old_energy != INT_MAX)
- {
- int energy_spent = old_energy - monster->speed_increment;
- monster->ench_countdown -= energy_spent;
- }
- }
- old_energy = monster->speed_increment;
+ mon->speed_increment -= entry->energy_usage.move;
}
#if DEBUG
@@ -3988,7 +3935,7 @@ static void handle_monster_move(int i, monsters *monster)
monster_add_energy(monster);
- // Handle enchantments and clouds on nonmoving monsters:
+ // Handle clouds on nonmoving monsters:
if (monster->speed == 0)
{
if (env.cgrid[monster->x][monster->y] != EMPTY_CLOUD
@@ -3996,9 +3943,23 @@ static void handle_monster_move(int i, monsters *monster)
{
mons_in_cloud( monster );
}
+ }
- if (handle_enchantment( monster ))
- return;
+ // Apply monster enchantments once for every normal-speed
+ // player turn.
+ monster->ench_countdown -= you.time_taken;
+ if (you.duration[DUR_SLOW] > 0)
+ monster->ench_countdown -= you.time_taken;
+ while (monster->ench_countdown < 0)
+ {
+ monster->ench_countdown += 10;
+ monster->apply_enchantments();
+
+ // Don't return if the monster died, since we have to deal
+ // with giant spores and ball lightning exploding at the
+ // end of the function.
+ if (!monster->alive())
+ break;
}
// memory is decremented here for a reason -- we only want it
@@ -4029,18 +3990,29 @@ static void handle_monster_move(int i, monsters *monster)
monsterentry* entry = get_monster_data(monster->type);
int old_energy = INT_MAX;
- int non_move_energy = std::min(entry->energy_usage.move,
- entry->energy_usage.swim);
+ int non_move_energy = std::min(entry->energy_usage.move,
+ entry->energy_usage.swim);
while (monster->has_action_energy())
{ // The continues & breaks are WRT this.
if (!monster->alive())
break;
- if (handle_enchantment(monster))
- break;
-
- handle_ench_countdown(monster, old_energy);
+ if (monster->speed_increment >= old_energy)
+ {
+#if DEBUG
+ if (monster->speed_increment == old_energy)
+ mprf(MSGCH_DIAGNOSTICS, "'%s' has same energy as last loop",
+ monster->name(DESC_PLAIN, true).c_str());
+ else
+ mprf(MSGCH_DIAGNOSTICS, "'%s' has MORE energy than last loop",
+ monster->name(DESC_PLAIN, true).c_str());
+#endif
+ monster->speed_increment = old_energy - 10;
+ old_energy = monster->speed_increment;
+ continue;
+ }
+ old_energy = monster->speed_increment;
if (env.cgrid[monster->x][monster->y] != EMPTY_CLOUD)
{
@@ -4119,7 +4091,10 @@ static void handle_monster_move(int i, monsters *monster)
}
}
- if (!mons_is_caught(monster))
+ if (mons_is_caught(monster))
+ // Struggling against the net takes time.
+ swim_or_move_energy(monster);
+ else
{
// calculates mmov_x, mmov_y based on monster target.
handle_movement(monster);
@@ -4341,28 +4316,22 @@ static void handle_monster_move(int i, monsters *monster)
} // end while
-
- if (monster->type != -1)
+ if (monster->type != -1 && monster->hit_points < 1)
{
- if ( monster->hit_points >= 1)
- handle_ench_countdown(monster, old_energy);
- else
+ if (monster->type == MONS_GIANT_SPORE
+ || monster->type == MONS_BALL_LIGHTNING)
{
- if (monster->type == MONS_GIANT_SPORE
- || monster->type == MONS_BALL_LIGHTNING)
- {
- // detach monster from the grid first, so it
- // doesn't get hit by its own explosion (GDL)
- mgrd[monster->x][monster->y] = NON_MONSTER;
+ // detach monster from the grid first, so it
+ // doesn't get hit by its own explosion (GDL)
+ mgrd[monster->x][monster->y] = NON_MONSTER;
- spore_goes_pop( monster );
- monster_cleanup( monster );
- return;
- }
- else
- {
- monster_die( monster, KILL_MISC, 0 );
- }
+ spore_goes_pop( monster );
+ monster_cleanup( monster );
+ return;
+ }
+ else
+ {
+ monster_die( monster, KILL_MISC, 0 );
}
}
}
@@ -4658,15 +4627,7 @@ static bool monster_swaps_places( monsters *mon, int mx, int my )
return (false);
// Okay, do the swap!
- monsterentry *entry = get_monster_data(mon->type);
- dungeon_feature_type feat = grd[mon->x][mon->y];
- if (feat >= DNGN_LAVA && feat <= DNGN_SHALLOW_WATER
- && !mon->airborne())
- {
- mon->speed_increment -= entry->energy_usage.swim;
- }
- else
- mon->speed_increment -= entry->energy_usage.move;
+ swim_or_move_energy(mon);
mon->x = nx;
mon->y = ny;
@@ -4717,15 +4678,7 @@ static bool do_move_monster(monsters *monster, int xi, int yi)
return false;
/* this appears to be the real one, ie where the movement occurs: */
- monsterentry *entry = get_monster_data(monster->type);
- dungeon_feature_type feat = grd[monster->x][monster->y];
- if (feat >= DNGN_LAVA && feat <= DNGN_SHALLOW_WATER
- && !monster->airborne())
- {
- monster->speed_increment -= entry->energy_usage.swim;
- }
- else
- monster->speed_increment -= entry->energy_usage.move;
+ swim_or_move_energy(monster);
mgrd[monster->x][monster->y] = NON_MONSTER;