diff options
-rw-r--r-- | crawl-ref/source/mon-util.cc | 49 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 169 |
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; |