diff options
Diffstat (limited to 'crawl-ref')
-rw-r--r-- | crawl-ref/source/debug.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/fight.cc | 9 | ||||
-rw-r--r-- | crawl-ref/source/fight.h | 35 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 154 |
4 files changed, 74 insertions, 126 deletions
diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc index 845d9c3ca3..e354a56700 100644 --- a/crawl-ref/source/debug.cc +++ b/crawl-ref/source/debug.cc @@ -4189,7 +4189,7 @@ static bool _fsim_mon_melee(FILE *out, int dodge, int armour, int mi) for (long i = 0; i < Options.fsim_rounds; ++i) { you.hp = you.hp_max = 5000; - monster_attack(mi); + monster_attack(&menv[mi]); const int damage = you.hp_max - you.hp; if (damage) hits++; diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc index 01d0998523..dde811e58e 100644 --- a/crawl-ref/source/fight.cc +++ b/crawl-ref/source/fight.cc @@ -4966,12 +4966,10 @@ static void mons_lose_attack_energy(monsters *attacker, int wpn_speed, } // A monster attacking the player. -bool monster_attack(int monster_attacking, bool allow_unarmed) +bool monster_attack(monsters* attacker, bool allow_unarmed) { ASSERT(!crawl_state.arena); - monsters *attacker = &menv[monster_attacking]; - // Friendly and good neutral monsters won't attack unless confused. if (mons_wont_attack(attacker) && !mons_is_confused(attacker)) return (false); @@ -4986,12 +4984,9 @@ bool monster_attack(int monster_attacking, bool allow_unarmed) } // Two monsters fighting each other. -bool monsters_fight(int monster_attacking, int monster_attacked, +bool monsters_fight(monsters* attacker, monsters* defender, bool allow_unarmed) { - monsters *attacker = &menv[monster_attacking]; - monsters *defender = &menv[monster_attacked]; - melee_attack attk(attacker, defender, allow_unarmed); return attk.attack(); } diff --git a/crawl-ref/source/fight.h b/crawl-ref/source/fight.h index 731430e2f5..9786a8ba7c 100644 --- a/crawl-ref/source/fight.h +++ b/crawl-ref/source/fight.h @@ -40,46 +40,19 @@ enum unchivalric_attack_type struct mon_attack_def; -// added Sept 18, 2000 -- bwr -/* *********************************************************************** - * called from: item_use.cc - * *********************************************************************** */ int effective_stat_bonus( int wepType = -1 ); int resist_adjust_damage(actor *defender, beam_type flavour, int res, int rawdamage, bool ranged = false); -// added Sept 18, 2000 -- bwr -/* *********************************************************************** - * called from: describe.cc - * *********************************************************************** */ int weapon_str_weight( object_class_type wpn_class, int wpn_type ); - - -// last updated: 08jun2000 {dlb} -/* *********************************************************************** - * called from: acr - it_use3 - * *********************************************************************** */ bool you_attack(int monster_attacked, bool unarmed_attacks); - - -// last updated: 08jun2000 {dlb} -/* *********************************************************************** - * called from: monstuff - * *********************************************************************** */ -bool monster_attack(int monster_attacking, bool allow_unarmed = true); - - -// last updated: 08jun2000 {dlb} -/* *********************************************************************** - * called from: monstuff - * *********************************************************************** */ -bool monsters_fight(int monster_attacking, int monster_attacked, +bool monster_attack(monsters* attacker, bool allow_unarmed = true); +bool monsters_fight(monsters* attacker, monsters* attacked, bool allow_unarmed = true); -int calc_your_to_hit( bool random_factor ); - -int calc_heavy_armour_penalty( bool random_factor ); +int calc_your_to_hit(bool random_factor); +int calc_heavy_armour_penalty(bool random_factor); unchivalric_attack_type is_unchivalric_attack(const actor *attacker, const actor *defender); diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 40417e29c1..9c6e475274 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -2185,6 +2185,24 @@ bool monster_blink(monsters *monster) return (true); } +static void _set_random_target(monsters* mon) +{ + mon->target = random_in_bounds(); // If we don't find anything better + for (int tries = 0; tries < 150; ++tries) + { + coord_def delta = coord_def(random2(13), random2(13)) - coord_def(6,6); + if (delta.origin()) + continue; + + const coord_def newtarget = delta + mon->pos(); + if (!in_bounds(newtarget)) + continue; + + mon->target = newtarget; + break; + } +} + // allow_adjacent: allow target to be adjacent to origin. // restrict_LOS: restrict target to be within PLAYER line of sight. bool random_near_space(const coord_def& origin, coord_def& target, @@ -3641,7 +3659,7 @@ static void _check_wander_target(monsters *mon, bool isPacified = false, // wandering monsters at least appear to have some sort of // attention span. -- bwr if (need_target) - mon->target = random_in_bounds(); + _set_random_target(mon); } } @@ -3772,7 +3790,7 @@ static void _handle_behaviour(monsters *mon) // Check for confusion -- early out. if (mon->has_ench(ENCH_CONFUSION)) { - mon->target = random_in_bounds(); + _set_random_target(mon); return; } @@ -4069,7 +4087,7 @@ static void _handle_behaviour(monsters *mon) // Sometimes, your friends will wander a bit. if (isFriendly && one_chance_in(8)) { - mon->target = random_in_bounds(); + _set_random_target(mon); mon->foe = MHITNOT; new_beh = BEH_WANDER; } @@ -4125,7 +4143,7 @@ static void _handle_behaviour(monsters *mon) mon->travel_target = MTRAV_NONE; patrolling = false; mon->patrol_point.reset(); - mon->target = random_in_bounds(); + _set_random_target(mon); } } @@ -5832,19 +5850,20 @@ static bool _handle_reaching(monsters *monster) && grid_distance(monster->pos(), you.pos()) == 2) { ret = true; - monster_attack(monster_index(monster), false); + monster_attack(monster, false); } } else if (monster->foe != MHITNOT) { - coord_def foepos = menv[monster->foe].pos(); + monsters& mfoe = menv[monster->foe]; + coord_def foepos = mfoe.pos(); // Same comments as to invisibility as above. if (monster->target == foepos && monster->mon_see_grid(foepos, true) && grid_distance(monster->pos(), foepos) == 2) { ret = true; - monsters_fight(monster_index(monster), monster->foe, false); + monsters_fight(monster, &mfoe, false); } } } @@ -6779,11 +6798,8 @@ static void _monster_regenerate(monsters *monster) } } -static bool _swap_monsters(const int mover_idx, const int moved_idx) +static bool _swap_monsters(monsters* mover, monsters* moved) { - monsters* mover = &menv[mover_idx]; - monsters* moved = &menv[moved_idx]; - // Can't swap with a stationary monster. if (mons_is_stationary(moved)) return (false); @@ -6829,11 +6845,10 @@ static bool _swap_monsters(const int mover_idx, const int moved_idx) const coord_def moved_pos = moved->pos(); mover->pos() = moved_pos; - moved->pos() = mover_pos; - mgrd(mover->pos()) = mover_idx; - mgrd(moved->pos()) = moved_idx; + mgrd(mover->pos()) = mover->mindex(); + mgrd(moved->pos()) = moved->mindex(); if (you.can_see(mover) && you.can_see(moved)) { @@ -6864,10 +6879,9 @@ static void _swim_or_move_energy(monsters *mon) # define DEBUG_ENERGY_USE(problem) ((void) 0) #endif -static void _handle_monster_move(int i, monsters *monster) +static void _handle_monster_move(monsters *monster) { bool brkk = false; - FixedArray <unsigned int, 19, 19> show; monster->hit_points = std::min(monster->max_hit_points, monster->hit_points); @@ -7028,9 +7042,8 @@ static void _handle_monster_move(int i, monsters *monster) if (monster->type == MONS_TIAMAT && one_chance_in(3)) { - int cols[] = { RED, WHITE, DARKGREY, GREEN, MAGENTA }; - int newcol = cols[random2(sizeof(cols) / sizeof(cols[0]))]; - monster->colour = newcol; + const int cols[] = { RED, WHITE, DARKGREY, GREEN, MAGENTA }; + monster->colour = RANDOM_ELEMENT(cols); } _monster_regenerate(monster); @@ -7063,7 +7076,7 @@ static void _handle_monster_move(int i, monsters *monster) // Harpies may eat food/corpses on the ground. if (monster->type == MONS_HARPY && !mons_is_fleeing(monster) && (mons_wont_attack(monster) - || (monster->pos() - you.pos()).rdist() > 1) + || (grid_distance(monster->pos(), you.pos()) > 1)) && (mons_is_wandering(monster) && one_chance_in(3) || one_chance_in(5)) && expose_items_to_element(BEAM_STEAL_FOOD, monster->pos(), 10)) @@ -7149,39 +7162,21 @@ static void _handle_monster_move(int i, monsters *monster) { std::vector<coord_def> moves; + mmov.reset(); int pfound = 0; - for (int yi = -1; yi <= 1; ++yi) - for (int xi = -1; xi <= 1; ++xi) - { - coord_def c = monster->pos() + coord_def(xi, yi); - if (in_bounds(c) && monster->can_pass_through(c) - && one_chance_in(++pfound)) - { - mmov.x = xi; - mmov.y = yi; - } - } - - if (x_chance_in_y(2, 2 + pfound)) - mmov.reset(); - - // Bounds check: don't let confused monsters try to run - // off the grid. - const coord_def s = monster->pos() + mmov; - if (!in_bounds_x(s.x)) - mmov.x = 0; - if (!in_bounds_y(s.y)) - mmov.y = 0; - - if (!monster->can_pass_through(monster->pos() + mmov)) - mmov.reset(); - - int enemy = mgrd(monster->pos() + mmov); - if (enemy != NON_MONSTER - && !is_sanctuary(monster->pos()) - && !mmov.origin()) + for (adjacent_iterator ai(monster->pos(), false); ai; ++ai) + if (monster->can_pass_through(*ai)) + if (one_chance_in(++pfound)) + mmov = *ai - monster->pos(); + + // OK, mmov determined. + const coord_def newcell = mmov + monster->pos(); + monsters* enemy = monster_at(newcell); + if (enemy + && newcell != monster->pos() + && !is_sanctuary(monster->pos())) { - if (monsters_fight(i, enemy)) + if (monsters_fight(monster, enemy)) { brkk = true; mmov.reset(); @@ -7193,8 +7188,8 @@ static void _handle_monster_move(int i, monsters *monster) // Instead run away! if (monster->add_ench(mon_enchant(ENCH_FEAR))) { - behaviour_event(monster, ME_SCARE, MHITNOT, - monster->pos() + mmov); + behaviour_event(monster, ME_SCARE, + MHITNOT, newcell); } break; } @@ -7276,24 +7271,24 @@ static void _handle_monster_move(int i, monsters *monster) if (!mons_is_caught(monster)) { // See if we move into (and fight) an unfriendly monster. - int targmon = mgrd(monster->pos() + mmov); - if (targmon != NON_MONSTER - && targmon != i - && !mons_aligned(i, targmon)) + monsters* targ = monster_at(monster->pos() + mmov); + if (targ + && targ != monster + && !mons_aligned(monster->mindex(), targ->mindex())) { // Maybe they can swap places? - if (_swap_monsters(i, targmon)) + if (_swap_monsters(monster, targ)) { _swim_or_move_energy(monster); continue; } // Figure out if they fight. - else if (monsters_fight(i, targmon)) + else if (monsters_fight(monster, targ)) { if (mons_is_batty(monster)) { monster->behaviour = BEH_WANDER; - monster->target = random_in_bounds(); + _set_random_target(monster); // monster->speed_increment -= monster->speed; } @@ -7309,24 +7304,17 @@ static void _handle_monster_move(int i, monsters *monster) if (monster->pos() + mmov == you.pos()) { ASSERT(!crawl_state.arena); - bool isFriendly = mons_friendly(monster); - bool attacked = false; - if (!isFriendly) + if (!mons_friendly(monster)) { - monster_attack(i); - attacked = true; + monster_attack(monster); if (mons_is_batty(monster)) { monster->behaviour = BEH_WANDER; - monster->target = random_in_bounds(); + _set_random_target(monster); } DEBUG_ENERGY_USE("monster_attack()"); - } - - if (attacked) - { mmov.reset(); continue; } @@ -7381,7 +7369,7 @@ void handle_monsters() const coord_def oldpos = monster->pos(); - _handle_monster_move(i, monster); + _handle_monster_move(monster); if (!invalid_monster(monster) && monster->pos() != oldpos) immobile_monster[i] = true; @@ -7693,21 +7681,14 @@ static bool _do_move_monster(monsters *monster, const coord_def& delta) if (f == you.pos()) { - monster_attack( monster_index(monster) ); - return (true); - } - - // XXX Is this necessary? Isn't it handled by the next case? - if (f == monster->pos()) - { - const int mx = monster_index(monster); - monsters_fight( mx, mx ); + monster_attack(monster); return (true); } - if (mgrd(f) != NON_MONSTER) + // This includes the case where the monster attacks itself. + if (monsters* def = monster_at(f)) { - monsters_fight( monster_index(monster), mgrd(f) ); + monsters_fight(monster, def); return (true); } @@ -8456,7 +8437,7 @@ forget_it: // Check for attacking player. if (monster->pos() + mmov == you.pos()) { - ret = monster_attack( monster_index(monster) ); + ret = monster_attack(monster); mmov.reset(); } @@ -8490,14 +8471,13 @@ forget_it: } // Check for attacking another monster. - int targmon = mgrd(monster->pos() + mmov); - if (targmon != NON_MONSTER) + if (monsters* targ = monster_at(monster->pos() + mmov)) { - if (mons_aligned(monster_index(monster), targmon)) + if (mons_aligned(monster->mindex(), targ->mindex())) ret = _monster_swaps_places(monster, mmov); else { - monsters_fight(monster_index(monster), targmon); + monsters_fight(monster, targ); ret = true; } |