From b4459c80d7fcbed7fd611312c0ccfb40e2728728 Mon Sep 17 00:00:00 2001 From: dshaligram Date: Sun, 2 Dec 2007 12:54:25 +0000 Subject: Trunk->0.3 merge (2916-2917): Fixed monsters getting past plants on level load, warn of quarterstaff borkage by shield. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/branches/stone_soup-0.3@2971 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/externs.h | 14 +++ crawl-ref/source/item_use.cc | 8 +- crawl-ref/source/items.cc | 289 +++++++++++++++++++++---------------------- crawl-ref/source/mon-util.cc | 9 +- crawl-ref/source/monplace.cc | 20 +-- crawl-ref/source/monplace.h | 13 +- crawl-ref/source/monstuff.cc | 11 +- 7 files changed, 195 insertions(+), 169 deletions(-) diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index 72db529680..d815a2f1e6 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -256,6 +256,13 @@ struct coord_def y /= div; return (*this); } + + const coord_def &operator *= (int mul) + { + x *= mul; + y *= mul; + return (*this); + } coord_def operator + (const coord_def &other) const { @@ -287,6 +294,12 @@ struct coord_def return (copy /= div); } + coord_def operator * (int mul) const + { + coord_def copy = *this; + return (copy *= mul); + } + int abs() const { return (x * x + y * y); @@ -980,6 +993,7 @@ public: god_type deity() const; bool alive() const; coord_def pos() const; + coord_def target_pos() const; bool swimming() const; bool submerged() const; bool can_drown() const; diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index c6e724b10a..cca40c5785 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -333,7 +333,7 @@ void warn_shield_penalties() if (!player_shield()) return; - // Warnings are limited to rods and bows at the moment. + // Warnings are limited to rods, bows, and quarterstaves at the moment. const item_def *weapon = player_weapon(); if (!weapon) return; @@ -342,6 +342,12 @@ void warn_shield_penalties() warn_rod_shield_interference(*weapon); else if (is_range_weapon(*weapon)) warn_launcher_shield_slowdown(*weapon); + else if (weapon->base_type == OBJ_WEAPONS + && weapon->sub_type == WPN_QUARTERSTAFF) + { + mprf(MSGCH_WARN, "Your %s severely limits your weapon's effectiveness.", + shield_base_name(player_shield())); + } } int item_special_wield_effect(const item_def &item) diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc index 2067fde798..449dd2d7a8 100644 --- a/crawl-ref/source/items.cc +++ b/crawl-ref/source/items.cc @@ -2130,42 +2130,36 @@ void update_level( double elapsedTime ) } } - int pos_x = mon->x, pos_y = mon->y; - + coord_def pos(mon->pos()); // dirt simple movement: for (i = 0; i < moves; i++) { - int mx = (pos_x > mon->target_x) ? -1 : - (pos_x < mon->target_x) ? 1 - : 0; - - int my = (pos_y > mon->target_y) ? -1 : - (pos_y < mon->target_y) ? 1 - : 0; + coord_def inc(mon->target_pos() - pos); + inc = coord_def(sgn(inc.x), sgn(inc.y)); if (mon->behaviour == BEH_FLEE) - { - mx *= -1; - my *= -1; - } + inc *= -1; - if (pos_x + mx < 0 || pos_x + mx >= GXM) - mx = 0; + if (pos.x + inc.x < 0 || pos.x + inc.x >= GXM) + inc.x = 0; - if (pos_y + my < 0 || pos_y + my >= GXM) - my = 0; + if (pos.y + inc.y < 0 || pos.y + inc.y >= GYM) + inc.y = 0; - if (mx == 0 && my == 0) + if (inc.origin()) break; - if (grd[pos_x + mx][pos_y + my] < DNGN_FLOOR) + const coord_def next(pos + inc); + const dungeon_feature_type feat = grd(next); + if (grid_is_solid(feat) + || mgrd(next) != NON_MONSTER + || !monster_habitable_grid(mon, feat)) break; - pos_x += mx; - pos_y += my; + pos = next; } - if (!shift_monster( mon, pos_x, pos_y )) + if (!shift_monster( mon, pos.x, pos.y )) shift_monster( mon, mon->x, mon->y ); #if DEBUG_DIAGNOSTICS @@ -2181,6 +2175,130 @@ void update_level( double elapsedTime ) delete_cloud( i ); } +static void hell_effects() +{ + int temp_rand = random2(17); + spschool_flag_type which_miscast = SPTYP_RANDOM; + bool summon_instead = false; + monster_type which_beastie = MONS_PROGRAM_BUG; + + mpr((temp_rand == 0) ? "\"You will not leave this place.\"" : + (temp_rand == 1) ? "\"Die, mortal!\"" : + (temp_rand == 2) ? "\"We do not forgive those who trespass against us!\"" : + (temp_rand == 3) ? "\"Trespassers are not welcome here!\"" : + (temp_rand == 4) ? "\"You do not belong in this place!\"" : + (temp_rand == 5) ? "\"Leave now, before it is too late!\"" : + (temp_rand == 6) ? "\"We have you now!\"" : + // plain messages + (temp_rand == 7) ? (player_can_smell()) ? "You smell brimstone." : + "Brimstone rains from above." : + (temp_rand == 8) ? "You feel lost and a long, long way from home..." : + (temp_rand == 9) ? "You shiver with fear." : + // warning + (temp_rand == 10) ? "You feel a terrible foreboding..." : + (temp_rand == 11) ? "Something frightening happens." : + (temp_rand == 12) ? "You sense an ancient evil watching you..." : + (temp_rand == 13) ? "You suddenly feel all small and vulnerable." : + (temp_rand == 14) ? "You sense a hostile presence." : + // sounds + (temp_rand == 15) ? "A gut-wrenching scream fills the air!" : + (temp_rand == 16) ? "You hear words spoken in a strange and terrible language..." + : "You hear diabolical laughter!", + (temp_rand < 7 ? MSGCH_TALK : + temp_rand < 10 ? MSGCH_PLAIN : + temp_rand < 15 ? MSGCH_WARN + : MSGCH_SOUND) ); + + temp_rand = random2(27); + + if (temp_rand > 17) // 9 in 27 odds {dlb} + { + temp_rand = random2(8); + + if (temp_rand > 3) // 4 in 8 odds {dlb} + which_miscast = SPTYP_NECROMANCY; + else if (temp_rand > 1) // 2 in 8 odds {dlb} + which_miscast = SPTYP_SUMMONING; + else if (temp_rand > 0) // 1 in 8 odds {dlb} + which_miscast = SPTYP_CONJURATION; + else // 1 in 8 odds {dlb} + which_miscast = SPTYP_ENCHANTMENT; + + miscast_effect( which_miscast, 4 + random2(6), random2avg(97, 3), + 100, "the effects of Hell" ); + } + else if (temp_rand > 7) // 10 in 27 odds {dlb} + { + // 60:40 miscast:summon split {dlb} + summon_instead = (random2(5) > 2); + + switch (you.where_are_you) + { + case BRANCH_DIS: + if (summon_instead) + which_beastie = summon_any_demon(DEMON_GREATER); + else + which_miscast = SPTYP_EARTH; + break; + case BRANCH_GEHENNA: + if (summon_instead) + which_beastie = MONS_FIEND; + else + which_miscast = SPTYP_FIRE; + break; + case BRANCH_COCYTUS: + if (summon_instead) + which_beastie = MONS_ICE_FIEND; + else + which_miscast = SPTYP_ICE; + break; + case BRANCH_TARTARUS: + if (summon_instead) + which_beastie = MONS_SHADOW_FIEND; + else + which_miscast = SPTYP_NECROMANCY; + break; + default: // this is to silence gcc compiler warnings {dlb} + if (summon_instead) + which_beastie = MONS_FIEND; + else + which_miscast = SPTYP_NECROMANCY; + break; + } + + if (summon_instead) + { + create_monster( which_beastie, 0, BEH_HOSTILE, you.x_pos, + you.y_pos, MHITYOU, 250 ); + } + else + { + miscast_effect( which_miscast, 4 + random2(6), + random2avg(97, 3), 100, "the effects of Hell" ); + } + } + + // NB: no "else" - 8 in 27 odds that nothing happens through + // first chain {dlb} + // also note that the following is distinct from and in + // addition to the above chain: + + // try to summon at least one and up to five random monsters {dlb} + if (one_chance_in(3)) + { + create_monster( RANDOM_MONSTER, 0, BEH_HOSTILE, + you.x_pos, you.y_pos, MHITYOU, 250 ); + + for (int i = 0; i < 4; i++) + { + if (one_chance_in(3)) + { + create_monster( RANDOM_MONSTER, 0, BEH_HOSTILE, + you.x_pos, you.y_pos, MHITYOU, 250 ); + } + } + } +} //--------------------------------------------------------------- // @@ -2194,137 +2312,12 @@ void handle_time( long time_delta ) { int temp_rand; // probability determination {dlb} - // so as not to reduplicate f(x) calls {dlb} - unsigned int which_miscast = SPTYP_RANDOM; - - bool summon_instead; // for branching within a single switch {dlb} - int which_beastie = MONS_PROGRAM_BUG; // error trapping {dlb} unsigned char i; // loop variable {dlb} bool new_rotting_item = false; //mv: becomes true when some new item becomes rotting // BEGIN - Nasty things happen to people who spend too long in Hell: if (player_in_hell() && coinflip()) - { - temp_rand = random2(17); - - mpr((temp_rand == 0) ? "\"You will not leave this place.\"" : - (temp_rand == 1) ? "\"Die, mortal!\"" : - (temp_rand == 2) ? "\"We do not forgive those who trespass against us!\"" : - (temp_rand == 3) ? "\"Trespassers are not welcome here!\"" : - (temp_rand == 4) ? "\"You do not belong in this place!\"" : - (temp_rand == 5) ? "\"Leave now, before it is too late!\"" : - (temp_rand == 6) ? "\"We have you now!\"" : - // plain messages - (temp_rand == 7) ? (player_can_smell()) ? "You smell brimstone." : - "Brimstone rains from above." : - (temp_rand == 8) ? "You feel lost and a long, long way from home..." : - (temp_rand == 9) ? "You shiver with fear." : - // warning - (temp_rand == 10) ? "You feel a terrible foreboding..." : - (temp_rand == 11) ? "Something frightening happens." : - (temp_rand == 12) ? "You sense an ancient evil watching you..." : - (temp_rand == 13) ? "You suddenly feel all small and vulnerable." : - (temp_rand == 14) ? "You sense a hostile presence." : - // sounds - (temp_rand == 15) ? "A gut-wrenching scream fills the air!" : - (temp_rand == 16) ? "You hear words spoken in a strange and terrible language..." - : "You hear diabolical laughter!", - (temp_rand < 7 ? MSGCH_TALK : - temp_rand < 10 ? MSGCH_PLAIN : - temp_rand < 15 ? MSGCH_WARN - : MSGCH_SOUND) ); - - temp_rand = random2(27); - - if (temp_rand > 17) // 9 in 27 odds {dlb} - { - temp_rand = random2(8); - - if (temp_rand > 3) // 4 in 8 odds {dlb} - which_miscast = SPTYP_NECROMANCY; - else if (temp_rand > 1) // 2 in 8 odds {dlb} - which_miscast = SPTYP_SUMMONING; - else if (temp_rand > 0) // 1 in 8 odds {dlb} - which_miscast = SPTYP_CONJURATION; - else // 1 in 8 odds {dlb} - which_miscast = SPTYP_ENCHANTMENT; - - miscast_effect( which_miscast, 4 + random2(6), random2avg(97, 3), - 100, "the effects of Hell" ); - } - else if (temp_rand > 7) // 10 in 27 odds {dlb} - { - // 60:40 miscast:summon split {dlb} - summon_instead = (random2(5) > 2); - - switch (you.where_are_you) - { - case BRANCH_DIS: - if (summon_instead) - which_beastie = summon_any_demon(DEMON_GREATER); - else - which_miscast = SPTYP_EARTH; - break; - case BRANCH_GEHENNA: - if (summon_instead) - which_beastie = MONS_FIEND; - else - which_miscast = SPTYP_FIRE; - break; - case BRANCH_COCYTUS: - if (summon_instead) - which_beastie = MONS_ICE_FIEND; - else - which_miscast = SPTYP_ICE; - break; - case BRANCH_TARTARUS: - if (summon_instead) - which_beastie = MONS_SHADOW_FIEND; - else - which_miscast = SPTYP_NECROMANCY; - break; - default: // this is to silence gcc compiler warnings {dlb} - if (summon_instead) - which_beastie = MONS_FIEND; - else - which_miscast = SPTYP_NECROMANCY; - break; - } - - if (summon_instead) - { - create_monster( which_beastie, 0, BEH_HOSTILE, you.x_pos, - you.y_pos, MHITYOU, 250 ); - } - else - { - miscast_effect( which_miscast, 4 + random2(6), - random2avg(97, 3), 100, "the effects of Hell" ); - } - } - - // NB: no "else" - 8 in 27 odds that nothing happens through - // first chain {dlb} - // also note that the following is distinct from and in - // addition to the above chain: - - // try to summon at least one and up to five random monsters {dlb} - if (one_chance_in(3)) - { - create_monster( RANDOM_MONSTER, 0, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250 ); - - for (i = 0; i < 4; i++) - { - if (one_chance_in(3)) - { - create_monster( RANDOM_MONSTER, 0, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250 ); - } - } - } - } - // END - special Hellish things... + hell_effects(); // Adjust the player's stats if s/he's diseased (or recovering). if (!you.disease) diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index fc30799dc5..6aaf8b6286 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -112,7 +112,7 @@ habitat_type grid2habitat(int grid) } } -int habitat2grid(habitat_type ht) +dungeon_feature_type habitat2grid(habitat_type ht) { switch (ht) { @@ -132,7 +132,7 @@ static void initialize_randmons() { for (int i = 0; i < NUM_HABITATS; ++i) { - int grid = habitat2grid( habitat_type(i) ); + const dungeon_feature_type grid = habitat2grid( habitat_type(i) ); for (int m = 0; m < NUM_MONSTERS; ++m) { @@ -2361,6 +2361,11 @@ coord_def monsters::pos() const return coord_def(x, y); } +coord_def monsters::target_pos() const +{ + return coord_def(target_x, target_y); +} + bool monsters::swimming() const { const dungeon_feature_type grid = grd[x][y]; diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc index f28088591a..b51559c82c 100644 --- a/crawl-ref/source/monplace.cc +++ b/crawl-ref/source/monplace.cc @@ -47,7 +47,8 @@ static int place_monster_aux(int mon_type, beh_type behaviour, int target, // Returns whether actual_grid is compatible with grid_wanted for monster // movement (or for monster generation, if generation is true). -bool grid_compatible(int grid_wanted, int actual_grid, bool generation) +bool grid_compatible(dungeon_feature_type grid_wanted, + dungeon_feature_type actual_grid, bool generation) { // XXX What in Xom's name is DNGN_WATER_STUCK? It looks like an artificial // device to slow down fiery monsters flying over water. @@ -66,7 +67,7 @@ bool grid_compatible(int grid_wanted, int actual_grid, bool generation) // // If you have an actual monster, use this instead of the overloaded function // that uses only the monster class to make decisions. -bool monster_habitable_grid(const monsters *m, int actual_grid) +bool monster_habitable_grid(const monsters *m, dungeon_feature_type actual_grid) { return (monster_habitable_grid(m->type, actual_grid, mons_flies(m), m->paralysed())); @@ -86,10 +87,13 @@ inline static bool mons_airborne(int mcls, int flies, bool paralysed) // one check, so we no longer care if a water elemental springs into existence // on dry land, because they're supposed to be able to move onto dry land // anyway. -bool monster_habitable_grid(int monster_class, int actual_grid, int flies, +bool monster_habitable_grid(int monster_class, + dungeon_feature_type actual_grid, + int flies, bool paralysed) { - const int preferred_habitat = monster_habitat(monster_class); + const dungeon_feature_type preferred_habitat = + monster_habitat(monster_class); return (grid_compatible(preferred_habitat, actual_grid) // [dshaligram] Flying creatures are all DNGN_FLOOR, so we // only have to check for the additional valid grids of deep @@ -457,7 +461,7 @@ bool place_monster(int &id, int mon_type, int power, beh_type behaviour, // a) not occupied // b) compatible // c) in the 'correct' proximity to the player - unsigned char grid_wanted = monster_habitat(mon_type); + dungeon_feature_type grid_wanted = monster_habitat(mon_type); while(true) { // handled above, won't change anymore @@ -635,7 +639,7 @@ static int place_monster_aux( int mon_type, beh_type behaviour, int target, bool first_band_member, int dur ) { int id, i; - unsigned char grid_wanted; + dungeon_feature_type grid_wanted = DNGN_UNSEEN; int fx=0, fy=0; // final x,y // gotta be able to pick an ID @@ -1542,7 +1546,7 @@ coord_def find_newmons_square(int mons_class, int x, int y) if (mons_class == WANDERING_MONSTER) mons_class = RANDOM_MONSTER; - int spcw = ((mons_class == RANDOM_MONSTER)? DNGN_FLOOR + dungeon_feature_type spcw = ((mons_class == RANDOM_MONSTER)? DNGN_FLOOR : monster_habitat( mons_class )); // Might be better if we chose a space and tried to match the monster @@ -1649,7 +1653,7 @@ int create_monster( int cls, int dur, beh_type beha, int cr_x, int cr_y, } // end create_monster() -bool empty_surrounds(int emx, int emy, unsigned char spc_wanted, +bool empty_surrounds(int emx, int emy, dungeon_feature_type spc_wanted, int radius, bool allow_centre, FixedVector < char, 2 > &empty) { diff --git a/crawl-ref/source/monplace.h b/crawl-ref/source/monplace.h index 3e91d49568..20cbba83e4 100644 --- a/crawl-ref/source/monplace.h +++ b/crawl-ref/source/monplace.h @@ -136,7 +136,8 @@ bool player_angers_monster(monsters *mon); /* *********************************************************************** * called from: misc - monplace - spells3 * *********************************************************************** */ -bool empty_surrounds( int emx, int emy, unsigned char spc_wanted, int radius, +bool empty_surrounds( int emx, int emy, dungeon_feature_type spc_wanted, + int radius, bool allow_centre, FixedVector& empty ); @@ -169,10 +170,14 @@ monster_type rand_dragon( dragon_class_type type ); void mark_interesting_monst(struct monsters* monster, beh_type behaviour = BEH_SLEEP); -bool grid_compatible(int grid_wanted, int actual_grid, bool generation = false); -bool monster_habitable_grid(int monster_class, int actual_grid, +bool grid_compatible(dungeon_feature_type grid_wanted, + dungeon_feature_type actual_grid, + bool generation = false); +bool monster_habitable_grid(int monster_class, + dungeon_feature_type actual_grid, int flies = -1, bool paralysed = false); -bool monster_habitable_grid(const monsters *m, int actual_grid); +bool monster_habitable_grid(const monsters *m, + dungeon_feature_type actual_grid); bool monster_can_submerge(int monster_class, int grid); coord_def find_newmons_square(int mons_class, int x, int y); diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index adf19e2e98..2ed1f64598 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -1044,7 +1044,7 @@ void alert_nearby_monsters(void) static bool valid_morph( monsters *monster, int new_mclass ) { - unsigned char current_tile = grd[monster->x][monster->y]; + const dungeon_feature_type current_tile = grd[monster->x][monster->y]; // morph targets are _always_ "base" classes, not derived ones. new_mclass = mons_species(new_mclass); @@ -1349,7 +1349,7 @@ bool random_near_space(int ox, int oy, int &tx, int &ty, bool allow_adjacent, return (tries < 150); } // end random_near_space() -static bool habitat_okay( const monsters *monster, int targ ) +static bool habitat_okay( const monsters *monster, dungeon_feature_type targ ) { return (monster_habitable_grid(monster, targ)); } @@ -4526,7 +4526,7 @@ void mons_check_pool(monsters *mons, killer_type killer, int killnum) if (mons->airborne()) return; - int grid = grd(mons->pos()); + dungeon_feature_type grid = grd(mons->pos()); if ((grid == DNGN_LAVA || grid == DNGN_DEEP_WATER) && !monster_habitable_grid(mons, grid)) { @@ -5704,7 +5704,7 @@ bool shift_monster( monsters *mon, int x, int y ) tx = x + i; ty = y + j; - if (tx < 5 || tx > GXM - 5 || ty < 5 || ty > GXM - 5) + if (!in_bounds(tx, ty)) continue; // won't drop on anything but vanilla floor right now @@ -5717,8 +5717,7 @@ bool shift_monster( monsters *mon, int x, int y ) if (tx == you.x_pos && ty == you.y_pos) continue; - count++; - if (one_chance_in(count)) + if (one_chance_in(++count)) { nx = tx; ny = ty; -- cgit v1.2.3-54-g00ecf