apply_enchantments(), since a monster could have apply_enchantments() not called for a normal-speed player turn, and then get called twice in a row during the next turn. This fix also makes zero-speed monsters like plants have apply_enchantments() be handled the same way as other monsters, so enchantments are now allways processed in time increments of 10 energy units (cloud processing for zero speed monsters is still handled separately, though).
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2456 c06c8d41-db1a-0410-9941-cceddc491573
UIRWVLX5LDNWURTZOG7EFLXE5OOEL4XBPSLSUHUQSKHC4A7WCVLQC OSGS3PH2L5CBTDVZCZS6OCFQNA4A7RMEXBYJQB7DDZBYYJW7QSSAC JPMNAPRVTMOIM62AD56L6MRBGJGNEF6GNLUXDFVOSZG3KU7BUGEQC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC T2AYVN57EFJQLFUFLAZDXKDAFDGTDLQIEQWQZNYFWJZBYSTYH4QQC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC 5XSXMOBGXFLTIQE6WDXWWFVDOTUPZSIQ2FWT3YI5QMVU6D76IUYQC X5WLJCJVW55SXZVP7IKP7ADCJIGNKN4PKAXFECVR6TNK7XSMZR7QC AOAJ6D3OKSELEYKAT55XCVU5LYJ7SMCZKC6DIEGLLB3TF2LEENWQC NFOXLH722RGWYY5D63VV6SF2XEJBEOQEFQME6FSA4HZRK3CPLSRQC VYDMJSFXD2E2CWOJEFFVLRBLHDFINBSVL2X6YE6456IQIRGVZIYQC 4UXFU3FZOCBSLDQ4S7MJKAE2H7VUHCNRDQMIY6NJ3PHYXWNGISDQC NNG27Y5ZQAZX6UD7F7M4F6KEZBEDFXPEEC3LFUSX4ESKT7K6UJQAC OP6CTAKWCAU64JXQ3USQYR5E5IFHQHNCACII5UMVRXUTZXJQOAZAC GTXKQTORYHZ7XB2VIH6372UM5GMWAN7IVRXWY5FGBCHFGBV6D6NAC 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.//// -- bwrif (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()
#if DEBUGif (monster->speed_increment == old_energy)mprf(MSGCH_DIAGNOSTICS,"Monster '%s' has same energy as last iteration.",monster->name(DESC_PLAIN).c_str(), true);elsemprf(MSGCH_DIAGNOSTICS,"Monster '%s' has MORE energy than last iteration.",monster->name(DESC_PLAIN).c_str(), true);#endifmonster->speed_increment = old_energy - 10;monster->ench_countdown -= 10;
mon->speed_increment -= entry->energy_usage.swim;
{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 (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;
if (handle_enchantment(monster))break;handle_ench_countdown(monster, old_energy);
if (monster->speed_increment >= old_energy){#if DEBUGif (monster->speed_increment == old_energy)mprf(MSGCH_DIAGNOSTICS, "'%s' has same energy as last loop",monster->name(DESC_PLAIN, true).c_str());elsemprf(MSGCH_DIAGNOSTICS, "'%s' has MORE energy than last loop",monster->name(DESC_PLAIN, true).c_str());#endifmonster->speed_increment = old_energy - 10;old_energy = monster->speed_increment;continue;}old_energy = monster->speed_increment;
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;
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;}elsemon->speed_increment -= entry->energy_usage.move;
swim_or_move_energy(mon);
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;}elsemonster->speed_increment -= entry->energy_usage.move;
swim_or_move_energy(monster);