diff options
-rw-r--r-- | crawl-ref/source/effects.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/enum.h | 5 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 7 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.h | 1 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 329 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.h | 4 | ||||
-rw-r--r-- | crawl-ref/source/stuff.cc | 2 |
7 files changed, 108 insertions, 244 deletions
diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc index cb370633a8..dc7ed52ea4 100644 --- a/crawl-ref/source/effects.cc +++ b/crawl-ref/source/effects.cc @@ -2854,8 +2854,8 @@ void update_level(double elapsedTime) mons_total++; #endif - // Monsters that are leaving the level often do so now. - if (mons_is_leaving(mon) && turns > random2(40) + 21) + // Pacified monsters often leave the level now. + if (mons_is_pacified(mon) && turns > random2(40) + 21) { make_mons_leave_level(mon); continue; diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index ba418d6027..877adf562f 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -2798,10 +2798,7 @@ enum montravel_target_type MTRAV_NONE = 0, MTRAV_PLAYER, // Travelling to reach the player. MTRAV_PATROL, // Travelling to reach the patrol point. - MTRAV_UNREACHABLE, // Not travelling because target is unreachable. - MTRAV_STAIR, // Travelling to reach a stair. - MTRAV_TRAP, // Travelling to reach a trap. - MTRAV_SUBMERSIBLE // Travelling to reach a submersible place. + MTRAV_UNREACHABLE // Not travelling because target is unreachable. }; #ifndef USE_TILE diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 26141dde8a..8973f43299 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -2206,11 +2206,6 @@ bool mons_is_cornered(const monsters *m) return (m->behaviour == BEH_CORNERED); } -bool mons_is_leaving(const monsters *m) -{ - return (m->behaviour == BEH_LEAVE); -} - bool mons_is_lurking(const monsters *m) { return (m->behaviour == BEH_LURK); @@ -2264,7 +2259,7 @@ void mons_pacify(monsters *mon) mon->flags |= MF_GOT_HALF_XP; } - // Make the monster leave the level. + // Make the monster begin leaving the level. behaviour_event(mon, ME_EVAL); } diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h index 8f87ebd267..f5189ca2a6 100644 --- a/crawl-ref/source/mon-util.h +++ b/crawl-ref/source/mon-util.h @@ -657,7 +657,6 @@ bool mons_is_seeking(const monsters *m); bool mons_is_fleeing(const monsters *m); bool mons_is_panicking(const monsters *m); bool mons_is_cornered(const monsters *m); -bool mons_is_leaving(const monsters *m); bool mons_is_lurking(const monsters *m); bool mons_is_batty(const monsters *m); bool mons_was_seen(const monsters *m); diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 73b1c75982..890b388c13 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -1188,7 +1188,7 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent) in_transit = true; monster->destroy_inventory(); // Make monster stop patrolling and/or travelling. - monster->patrol_point = coord_def(0,0); + monster->patrol_point = coord_def(0, 0); monster->travel_path.clear(); monster->travel_target = MTRAV_NONE; break; @@ -2032,8 +2032,11 @@ void behaviour_event(monsters *mon, int event, int src, break; case ME_ALERT: - if (mons_friendly(mon) && mon->is_patrolling()) + if ((mons_friendly(mon) || mons_is_pacified(mon)) + && mon->is_patrolling()) + { break; + } // Will alert monster to <src> and turn them // against them, unless they have a current foe. @@ -2113,14 +2116,13 @@ void behaviour_event(monsters *mon, int event, int src, const bool wasLurking = (old_behaviour == BEH_LURK && !mons_is_lurking(mon)); - const bool wasLeaving = - (old_behaviour == BEH_LEAVE && !mons_is_leaving(mon)); + const bool isPacified = mons_is_pacified(mon); - if ((wasLurking || wasLeaving) + if ((wasLurking || isPacified) && (event == ME_DISTURB || event == ME_ALERT || event == ME_EVAL)) { - // Lurking monsters or monsters leaving the level won't stop - // doing so just because they noticed something. + // Lurking monsters or pacified monsters leaving the level won't + // stop doing so just because they noticed something. mon->behaviour = old_behaviour; } else if (wasLurking && mon->has_ench(ENCH_SUBMERGED) @@ -2384,22 +2386,18 @@ static void _mons_find_all_level_exits(const monsters *mon, // All types of stairs. if (is_stair(gridc)) - { - e.push_back(level_exit(coord_def(x, y), MTRAV_STAIR, - false)); - } + e.push_back(level_exit(coord_def(x, y), false)); // Shaft traps. - trap_type tt = trap_type_at_xy(x, y); - if (tt == TRAP_SHAFT && _is_trap_safe(mon, x, y)) - e.push_back(level_exit(coord_def(x, y), MTRAV_TRAP, false)); + if (trap_type_at_xy(x, y) == TRAP_SHAFT + && _is_trap_safe(mon, x, y)) + { + e.push_back(level_exit(coord_def(x, y), false)); + } // Any place the monster can submerge. if (monster_can_submerge(mon, gridc)) - { - e.push_back(level_exit(coord_def(x, y), MTRAV_SUBMERSIBLE, - false)); - } + e.push_back(level_exit(coord_def(x, y), false)); } } } @@ -2437,56 +2435,44 @@ static int _mons_find_nearest_level_exit(const monsters *mon, // types, this should be expanded along with it. static void _mons_indicate_level_exit(const monsters *mon, int x, int y) { - switch (mon->travel_target) - { - case MTRAV_STAIR: + // All types of stairs. + if (is_travelable_stair(grd[x][y])) { - if (is_travelable_stair(grd[x][y])) - { - command_type dir = grid_stair_direction(grd[x][y]); - simple_monster_message(mon, - make_stringf(" %s the stairs.", - dir == CMD_GO_UPSTAIRS ? "goes up" : - dir == CMD_GO_DOWNSTAIRS ? "goes down" - : "takes").c_str()); - } - else if (is_gate(grd[x][y])) - simple_monster_message(mon, " passes through the gate."); - break; + command_type dir = grid_stair_direction(grd[x][y]); + simple_monster_message(mon, + make_stringf(" %s the stairs.", + dir == CMD_GO_UPSTAIRS ? "goes up" : + dir == CMD_GO_DOWNSTAIRS ? "goes down" + : "takes").c_str()); } - - case MTRAV_TRAP: + else if (is_gate(grd[x][y])) + simple_monster_message(mon, " passes through the gate."); + // Shaft traps. + else if (trap_type_at_xy(x, y) == TRAP_SHAFT) { - trap_type tt = trap_type_at_xy(x, y); - if (tt == TRAP_SHAFT) - { - simple_monster_message(mon, " falls through a shaft!"); - grd[x][y] = trap_category(tt); - } - break; + simple_monster_message(mon, " falls through a shaft!"); + grd[x][y] = trap_category(trap_type_at_xy(x, y)); } - - case MTRAV_SUBMERSIBLE: + // Any place the monster can submerge. + else if (monster_can_submerge(mon, grd[x][y])) + { simple_monster_message(mon, make_stringf(" disappears into %s!", mons_habitat(mon) == HT_LAVA ? "the lava" : mons_habitat(mon) == HT_WATER ? "the water" : "thin air").c_str()); - break; - - default: - break; } } void make_mons_leave_level(monsters *mon) { - if (mons_is_leaving(mon)) + if (mons_is_pacified(mon)) { if (mons_near(mon) && player_monster_visible(mon)) _mons_indicate_level_exit(mon, mon->target_x, mon->target_y); - // Monsters leaving the level take their stuff with them. + // Pacified monsters leaving the level take their stuff with + // them. mon->flags |= MF_HARD_RESET; monster_die(mon, KILL_DISMISSED, 0); } @@ -3027,11 +3013,46 @@ static void _handle_behaviour(monsters *mon) break; case BEH_WANDER: - // Monsters that have been pacified begin leaving the level. if (isPacified) { - new_beh = BEH_LEAVE; - break; + // If a pacified monster is far enough away from the + // player, make it leave the level. + if (grid_distance(mon->x, mon->y, you.x_pos, you.y_pos) + >= LOS_RADIUS * LOS_RADIUS * 4) + { + make_mons_leave_level(mon); + return; + } + + // If a pacified monster isn't travelling toward + // someplace from which it can leave the level, make it + // start doing so. + if (mon->travel_target != MTRAV_PATROL + && mon->travel_target != MTRAV_UNREACHABLE) + { + e_index = _mons_find_nearest_level_exit(mon, e); + + if (e_index != -1) + { + mon->foe = MHITNOT; + + patrolling = true; + mon->patrol_point = e[e_index].target; + + mon->target_x = e[e_index].target.x; + mon->target_y = e[e_index].target.y; + + mon->travel_target = MTRAV_PATROL; + mon->travel_path.clear(); + } + } + + // If the level exit is unreachable, find a new one. + if (mon->travel_target == MTRAV_UNREACHABLE) + { + e[e_index].unreachable = true; + mon->travel_target = MTRAV_NONE; + } } // Is our foe in LOS? @@ -3064,6 +3085,7 @@ static void _handle_behaviour(monsters *mon) mon->name(DESC_PLAIN).c_str(), mon->target_x, mon->target_y); #endif + need_target = false; if (mon->x == mon->travel_path[0].x && mon->y == mon->travel_path[0].y) @@ -3079,6 +3101,18 @@ static void _handle_behaviour(monsters *mon) mpr("We reached the end of our path: stop " "travelling."); #endif + + // If a pacified monster is leaving the + // level via something other than a trap, + // and has reached its goal, handle it here. + if (isPacified + && mon->x == e[e_index].target.x + && mon->y == e[e_index].target.y) + { + make_mons_leave_level(mon); + return; + } + mon->travel_target = MTRAV_NONE; need_target = true; } @@ -3293,164 +3327,6 @@ static void _handle_behaviour(monsters *mon) break; case BEH_LEAVE: - // If the monster is far enough away from the player, make - // it leave the level. - if (grid_distance(mon->x, mon->y, you.x_pos, you.y_pos) - >= LOS_RADIUS * LOS_RADIUS * 4) - { - make_mons_leave_level(mon); - return; - } - - // If the monster isn't travelling toward someplace from - // which it can leave the level, and it can move (or at - // least teleport, as a mimic can), make it start doing so. - if (mon->travel_target == MTRAV_NONE) - { - e_index = _mons_find_nearest_level_exit(mon, e); - - if (e_index != -1) - { - mon->foe = MHITNOT; - mon->target_x = e[e_index].target.x; - mon->target_y = e[e_index].target.y; - mon->travel_target = e[e_index].target_type; - if (travelling) - mon->travel_path.clear(); - } - } - else if (mon->travel_target != MTRAV_UNREACHABLE - || one_chance_in(12)) - { -#ifdef DEBUG_PATHFIND - mprf("%s: Level exit out of reach! What now?", - mon->name(DESC_PLAIN).c_str()); -#endif - // If we're already on our way, do nothing. - if (travelling) - { - // Current target still valid? - if (mon->x == mon->travel_path[0].x - && mon->y == mon->travel_path[0].y) - { - // Get next waypoint. - mon->travel_path.erase( - mon->travel_path.begin() ); - - if (!mon->travel_path.empty()) - { - mon->target_x = mon->travel_path[0].x; - mon->target_y = mon->travel_path[0].y; - break; - } - } - } - } - else - { - // Use pathfinding to find a (new) path to the level exit. - const int dist = grid_distance(mon->x, mon->y, - e[e_index].target.x, - e[e_index].target.y); - -#ifdef DEBUG_PATHFIND - mprf("Need to calculate a path... (dist = %d)", dist); -#endif - const bool native = mons_is_native_in_branch(mon); - - int range = 0; - switch (mons_intel(mon->type)) - { - case I_PLANT: - range = 2; - break; - case I_INSECT: - range = 3; - break; - case I_ANIMAL: - range = 4; - break; - case I_NORMAL: - range = 8; - break; - default: - // Highly intelligent monsters can find their way - // anywhere. (range == 0 means no restriction.) - break; - } - - if (range && native) - range += 3; - - if (range > 0 && dist > range) - { - mon->travel_target = MTRAV_UNREACHABLE; -#ifdef DEBUG_PATHFIND - mprf("Distance too great, don't attempt pathfinding! (%s)", - mon->name(DESC_PLAIN).c_str()); -#endif - } - else - { -#ifdef DEBUG_PATHFIND - mprf("Need a path for %s from (%d, %d) to (%d, %d), " - "max. dist = %d", - mon->name(DESC_PLAIN).c_str(), mon->x, mon->y, - e[e_index].target.x, e[e_index].target.y, range); -#endif - monster_pathfind mp; - if (range > 0) - mp.set_range(range); - - if (mp.start_pathfind(mon, e[e_index].target)) - { - mon->travel_path = mp.calc_waypoints(); - if (!mon->travel_path.empty()) - { - // Okay then, we found a path. Let's use it! - mon->target_x = mon->travel_path[0].x; - mon->target_y = mon->travel_path[0].y; - break; - } - else - { -#ifdef DEBUG_PATHFIND - mpr("No path found!"); -#endif - mon->travel_target = MTRAV_UNREACHABLE; - // Pass information on to nearby monsters. - _mark_neighbours_target_unreachable(mon); - } - } - else - { -#ifdef DEBUG_PATHFIND - mpr("No path found!"); -#endif - mon->travel_target = MTRAV_UNREACHABLE; - // Pass information on to nearby monsters. - _mark_neighbours_target_unreachable(mon); - } - } - } - - // If the level exit is unreachable, find a new one. - if (mon->travel_target == MTRAV_UNREACHABLE) - { - e[e_index].unreachable = true; - mon->travel_target = MTRAV_NONE; - } - - // If the monster is leaving the level via a stair or - // submersion, and has reached its goal, handle it here. - if ((mon->travel_target == MTRAV_STAIR - || mon->travel_target == MTRAV_SUBMERSIBLE) - && mon->x == e[e_index].target.x - && mon->y == e[e_index].target.y) - { - make_mons_leave_level(mon); - return; - } break; case BEH_FLEE: @@ -3933,7 +3809,7 @@ static void _handle_nearby_ability(monsters *monster) if (coinflip() && !mons_friendly(monster) && !mons_is_wandering(monster) && !mons_is_fleeing(monster) - && !mons_is_leaving(monster) + && !mons_is_pacified(monster) && !_is_player_or_mon_sanct(monster)) { simple_monster_message(monster, " stares at you."); @@ -3948,7 +3824,7 @@ static void _handle_nearby_ability(monsters *monster) if (coinflip() && !mons_friendly(monster) && !mons_is_wandering(monster) && !mons_is_fleeing(monster) - && !mons_is_leaving(monster) + && !mons_is_pacified(monster) && !_is_player_or_mon_sanct(monster)) { simple_monster_message(monster, " stares at you."); @@ -4369,7 +4245,7 @@ static bool _handle_special_ability(monsters *monster, bolt & beem) // confused, fleeing, or leaving the level. if (monster->has_ench(ENCH_CONFUSION) || mons_is_fleeing(monster) - || mons_is_leaving(monster) + || mons_is_pacified(monster) || mons_friendly(monster) || silenced(monster->x, monster->y) || silenced(you.x_pos, you.y_pos)) @@ -4674,7 +4550,7 @@ static bool _handle_scroll(monsters *monster) if (!monster->has_ench(ENCH_TP)) { if (mons_is_caught(monster) || mons_is_fleeing(monster) - || mons_is_leaving(monster)) + || mons_is_pacified(monster)) { simple_monster_message(monster, " reads a scroll."); monster_teleport(monster, false); @@ -4686,7 +4562,7 @@ static bool _handle_scroll(monsters *monster) case SCR_BLINKING: if (mons_is_caught(monster) || mons_is_fleeing(monster) - || mons_is_leaving(monster)) + || mons_is_pacified(monster)) { if (mons_near(monster)) { @@ -5218,7 +5094,7 @@ static bool _handle_spell(monsters *monster, bolt &beem) SPELL_GREATER_HEALING : SPELL_LESSER_HEALING; finalAnswer = true; } - else if (mons_is_fleeing(monster) || mons_is_leaving(monster)) + else if (mons_is_fleeing(monster) || mons_is_pacified(monster)) { // Since the player isn't around, we'll extend the monster's // normal choices to include the self-enchant slot. @@ -5262,7 +5138,7 @@ static bool _handle_spell(monsters *monster, bolt &beem) // get here... even if the monster is on its last HP. That // way we don't have to worry about monsters infinitely casting // Healing on themselves (e.g. orc high priests). - if ((mons_is_fleeing(monster) || mons_is_leaving(monster)) + if ((mons_is_fleeing(monster) || mons_is_pacified(monster)) && ms_low_hitpoint_cast(monster, hspell_pass[5])) { spell_cast = hspell_pass[5]; @@ -5326,7 +5202,7 @@ static bool _handle_spell(monsters *monster, bolt &beem) // Setup spell - monsters that are fleeing or leaving // the level will always try to choose their emergency // spell. - if (mons_is_fleeing(monster) || mons_is_leaving(monster)) + if (mons_is_fleeing(monster) || mons_is_pacified(monster)) { spell_cast = (one_chance_in(5) ? SPELL_NO_SPELL : hspell_pass[5]); @@ -5584,9 +5460,9 @@ static bool _handle_throw(monsters *monster, bolt & beem) return (false); } - // Greatly lowered chances if the monster is fleeing or leaving the - // level. - if ((mons_is_fleeing(monster) || mons_is_leaving(monster)) + // Greatly lowered chances if the monster is fleeing or pacified and + // leaving the level. + if ((mons_is_fleeing(monster) || mons_is_pacified(monster)) && !one_chance_in(8)) { return (false); @@ -6120,10 +5996,9 @@ static void _handle_monster_move(int i, monsters *monster) if (!mons_is_caught(monster)) { - // If the monster is leaving the level via a trap, and is - // about to reach its goal, handle it here. - if (mons_is_leaving(monster) - && monster->travel_target == MTRAV_TRAP + // If a pacified monster is leaving the level via a trap, + // and is about to reach its goal, handle it here. + if (mons_is_pacified(monster) && monster->x + mmov_x == monster->target_x && monster->y + mmov_y == monster->target_y) { @@ -6715,7 +6590,7 @@ static bool _is_trap_safe(const monsters *monster, const int trap_x, if (trap.type == TRAP_SHAFT && monster->will_trigger_shaft()) { - if ((mons_is_fleeing(monster) || mons_is_leaving(monster)) + if ((mons_is_fleeing(monster) || mons_is_pacified(monster)) && intel >= I_NORMAL) { return (true); diff --git a/crawl-ref/source/monstuff.h b/crawl-ref/source/monstuff.h index ec523aca6d..5aee3f67e0 100644 --- a/crawl-ref/source/monstuff.h +++ b/crawl-ref/source/monstuff.h @@ -37,15 +37,13 @@ enum mon_desc_type // things that cross categorical lines {dlb} struct level_exit { coord_def target; - montravel_target_type target_type; bool unreachable; public: level_exit(coord_def c = coord_def(-1, -1), - montravel_target_type m = MTRAV_NONE, bool u = true) - : target(c), target_type(m), unreachable(u) + : target(c), unreachable(u) { } }; diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc index 8461fb0f4a..16b2f8e4e3 100644 --- a/crawl-ref/source/stuff.cc +++ b/crawl-ref/source/stuff.cc @@ -329,7 +329,7 @@ static bool tag_follower_at(const coord_def &pos) fmenv->flags |= MF_TAKING_STAIRS; // Clear patrolling/travel markers. - fmenv->patrol_point = coord_def(0,0); + fmenv->patrol_point = coord_def(0, 0); fmenv->travel_path.clear(); fmenv->travel_target = MTRAV_NONE; |