diff options
-rw-r--r-- | crawl-ref/source/acr.cc | 46 | ||||
-rw-r--r-- | crawl-ref/source/direct.cc | 3 | ||||
-rw-r--r-- | crawl-ref/source/dungeon.cc | 7 | ||||
-rw-r--r-- | crawl-ref/source/enum.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/externs.h | 4 | ||||
-rw-r--r-- | crawl-ref/source/makeitem.cc | 32 | ||||
-rw-r--r-- | crawl-ref/source/misc.cc | 7 | ||||
-rw-r--r-- | crawl-ref/source/mon-data.h | 24 | ||||
-rw-r--r-- | crawl-ref/source/mon-pick.cc | 14 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 6 | ||||
-rw-r--r-- | crawl-ref/source/monplace.cc | 6 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 107 | ||||
-rw-r--r-- | crawl-ref/source/output.cc | 6 | ||||
-rw-r--r-- | crawl-ref/source/player.cc | 68 | ||||
-rw-r--r-- | crawl-ref/source/player.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/spells4.cc | 7 | ||||
-rw-r--r-- | crawl-ref/source/tags.cc | 10 | ||||
-rw-r--r-- | crawl-ref/source/view.cc | 9 |
18 files changed, 349 insertions, 12 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index 636a86d41d..09f70c8742 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -648,6 +648,12 @@ static void handle_wizard_command( void ) case 'H': you.rotting = 0; you.duration[DUR_POISONING] = 0; + if (you.duration[DUR_BEHELD]) + { + you.duration[DUR_BEHELD] = 0; + you.beheld_by.clear(); + } + you.duration[DUR_CONF] = 0; you.disease = 0; inc_hp( 10, true ); set_hp( you.hp_max, false ); @@ -2458,6 +2464,12 @@ static void decrement_durations() decrement_a_duration( DUR_SURE_BLADE, "The bond with your blade fades away." ); + if ( decrement_a_duration( DUR_BEHELD, "You break out of your daze.", + -1, 0, NULL, MSGCH_RECOVERY )) + { + you.beheld_by.clear(); + } + dec_slow_player(); dec_haste_player(); @@ -3602,6 +3614,34 @@ static void move_player(int move_x, int move_y) } } // end of if you.duration[DUR_CONF] + const int targ_x = you.x_pos + move_x; + const int targ_y = you.y_pos + move_y; + const dungeon_feature_type targ_grid = grd[ targ_x ][ targ_y ]; + const unsigned short targ_monst = mgrd[ targ_x ][ targ_y ]; + const bool targ_solid = grid_is_solid(targ_grid); + + // cannot move away from mermaid but you CAN fight neighbouring squares + if (you.duration[DUR_BEHELD] && !you.duration[DUR_CONF] + && (targ_monst == NON_MONSTER || mons_is_submerged(&menv[targ_monst]))) + { + for (unsigned int i = 0; i < you.beheld_by.size(); i++) + { + coord_def pos = menv[you.beheld_by[i]].pos(); + int olddist = distance(you.x_pos, you.y_pos, pos.x, pos.y); + int newdist = distance(you.x_pos + move_x, you.y_pos + move_y, pos.x, pos.y); + + if (olddist < newdist) + { + mprf("You cannot move away from %s!", + (menv[you.beheld_by[i]]).name(DESC_NOCAP_THE, true).c_str()); + + move_x = 0; + move_y = 0; + return; + } + } + } // end of beholding check + if (you.running.check_stop_running()) { move_x = 0; @@ -3611,12 +3651,6 @@ static void move_player(int move_x, int move_y) return; } - const int targ_x = you.x_pos + move_x; - const int targ_y = you.y_pos + move_y; - const dungeon_feature_type targ_grid = grd[ targ_x ][ targ_y ]; - const unsigned short targ_monst = mgrd[ targ_x ][ targ_y ]; - const bool targ_solid = grid_is_solid(targ_grid); - if (targ_monst != NON_MONSTER && !mons_is_submerged(&menv[targ_monst])) { struct monsters *mon = &menv[targ_monst]; diff --git a/crawl-ref/source/direct.cc b/crawl-ref/source/direct.cc index 5c98b25623..4315930792 100644 --- a/crawl-ref/source/direct.cc +++ b/crawl-ref/source/direct.cc @@ -1844,6 +1844,9 @@ static void describe_monster(const monsters *mon) text += "."; print_formatted_paragraph(text, get_number_of_cols()); + if (player_beheld_by(mon)) + mpr("You are beheld by her song.", MSGCH_EXAMINE); + if (mon->type == MONS_HYDRA) { mprf(MSGCH_EXAMINE, "It has %d head%s.", mon->number, diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index 14233e9b1d..cc9c4f4f46 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -2546,6 +2546,13 @@ static void place_aquatic_monsters(int level_number, char level_type) swimming_things[i] = MONS_BIG_FISH + random2(4); if (player_in_branch( BRANCH_SWAMP ) && !one_chance_in(3)) swimming_things[i] = MONS_SWAMP_WORM; + else if (player_in_branch( BRANCH_SHOALS )) + { + if (one_chance_in(3)) + swimming_things[i] = MONS_MERFOLK; + else if (one_chance_in(5)) + swimming_things[i] = MONS_MERMAID; + } } if (level_number >= 25 && one_chance_in(5)) diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index 01048e2340..b2895d7eaa 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -983,6 +983,7 @@ enum duration_type DUR_CONF, DUR_PARALYSIS, DUR_SLOW, + DUR_BEHELD, DUR_HASTE, DUR_MIGHT, DUR_LEVITATION, @@ -1557,6 +1558,8 @@ enum monster_type // (int) menv[].type MONS_BLACK_BEAR, // 189 MONS_SIMULACRUM_SMALL, MONS_SIMULACRUM_LARGE, + MONS_MERFOLK, + MONS_MERMAID, // 193 //jmf: end new monsters MONS_WHITE_IMP = 220, // 220 MONS_LEMURE, diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index cd145c41be..ade001aaee 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -493,11 +493,13 @@ class player : public actor { public: bool turn_is_over; // flag signaling that player has performed a timed action - + // If true, player is headed to the Abyss. bool banished; std::string banished_by; + std::vector<int> beheld_by; // monsters beholding player + bool just_autoprayed; // autopray just kicked in unsigned char prev_targ; diff --git a/crawl-ref/source/makeitem.cc b/crawl-ref/source/makeitem.cc index d251b071e7..75e6e33508 100644 --- a/crawl-ref/source/makeitem.cc +++ b/crawl-ref/source/makeitem.cc @@ -3420,6 +3420,34 @@ static item_make_species_type give_weapon(monsters *mon, int level, } break; + case MONS_MERMAID: + if (one_chance_in(3)) + { + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_SPEAR; + } + break; + + case MONS_MERFOLK: + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + // 1/3 each for trident, spears and javelins + if (one_chance_in(3)) + item.sub_type = WPN_TRIDENT; + else if (coinflip()) + { + item.sub_type = WPN_SPEAR; + iquan = 1 + random2(3); + } + else + { + item.base_type = OBJ_MISSILES; + item.sub_type = MI_JAVELIN; + iquan = 3 + random2(6); + } + break; + case MONS_CENTAUR: case MONS_CENTAUR_WARRIOR: item_race = MAKE_ITEM_NO_RACE; @@ -3672,6 +3700,9 @@ static item_make_species_type give_weapon(monsters *mon, int level, return (item_race); } + if (iquan > 1 && !force_item) + mitm[thing_created].quantity = iquan; + give_monster_item(mon, thing_created, force_item); if (give_aux_melee && (i.base_type != OBJ_WEAPONS || is_range_weapon(i))) @@ -3751,6 +3782,7 @@ static void give_ammo(monsters *mon, int level, case MONS_DRACONIAN_KNIGHT: case MONS_GNOLL: case MONS_HILL_GIANT: + case MONS_MERFOLK: if (!one_chance_in(20)) break; // fall through diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index 8fa092b0a0..8351616c1c 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -1243,6 +1243,13 @@ void down_stairs( int old_level, dungeon_feature_type force_stair, new_level(); + // clear list of beholding monsters + if (you.duration[DUR_BEHELD]) + { + you.beheld_by.clear(); + you.duration[DUR_BEHELD] = 0; + } + viewwindow(1, true); if (you.skills[SK_TRANSLOCATIONS] > 0 && !allow_control_teleport( true )) diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h index cd585b36b9..b021392e7d 100644 --- a/crawl-ref/source/mon-data.h +++ b/crawl-ref/source/mon-data.h @@ -3985,6 +3985,30 @@ }, { + MONS_MERFOLK, 'm', LIGHTBLUE, "merfolk fighter", + M_HUMANOID | M_WARM_BLOOD | M_AMPHIBIOUS, + MR_RES_POISON | MR_RES_COLD, + 500, 10, MONS_MERFOLK, MONS_MERFOLK, MH_NATURAL, -3, + { {AT_HIT, AF_PLAIN, 14}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, + { 8, 2, 4, 0 }, + 4, 12, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM +} +, + +{ + MONS_MERMAID, 'm', LIGHTCYAN, "mermaid", + M_SPELLCASTER | M_HUMANOID | M_WARM_BLOOD | M_AMPHIBIOUS, + MR_RES_POISON | MR_RES_COLD, + 500, 10, MONS_MERMAID, MONS_MERMAID, MH_NATURAL, -5, + { {AT_HIT, AF_PLAIN, 10}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, + { 8, 2, 4, 0 }, + 4, 12, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM +} +, + +{ MONS_GIANT_NEWT, 'l', LIGHTGREEN, "giant newt", M_COLD_BLOOD | M_AMPHIBIOUS, MR_NO_FLAGS, diff --git a/crawl-ref/source/mon-pick.cc b/crawl-ref/source/mon-pick.cc index cf4f03fcd4..d7989c10c2 100644 --- a/crawl-ref/source/mon-pick.cc +++ b/crawl-ref/source/mon-pick.cc @@ -2029,6 +2029,8 @@ int mons_shoals_level(int mcls) case MONS_GIANT_BAT: break; + case MONS_MERFOLK: + case MONS_MERMAID: case MONS_CENTAUR: case MONS_ETTIN: case MONS_SHEEP: @@ -2069,8 +2071,12 @@ int mons_shoals_rare(int mcls) case MONS_ETTIN: case MONS_SHEEP: + case MONS_MERFOLK: return 50; + case MONS_MERMAID: + return 40; + case MONS_HIPPOGRIFF: case MONS_GIANT_BAT: case MONS_BUTTERFLY: @@ -2112,6 +2118,8 @@ int mons_swamp_level(int mcls) case MONS_SWAMP_DRAKE: case MONS_WORM: case MONS_SWAMP_WORM: + case MONS_MERFOLK: + case MONS_MERMAID: mlev++; break; @@ -2189,6 +2197,7 @@ int mons_swamp_rare(int mcls) return 61; case MONS_SLIME_CREATURE: + case MONS_MERFOLK: return 54; case MONS_SNAKE: @@ -2216,6 +2225,7 @@ int mons_swamp_rare(int mcls) case MONS_KOMODO_DRAGON: case MONS_VERY_UGLY_THING: case MONS_VAPOUR: + case MONS_MERMAID: return 15; case MONS_PHANTOM: @@ -2669,6 +2679,8 @@ int mons_standard_level(int mcls) case MONS_DEEP_ELF_MASTER_ARCHER: return 33; + case MONS_MERFOLK: + case MONS_MERMAID: case MONS_BIG_FISH: case MONS_ELECTRICAL_EEL: case MONS_GIANT_GOLDFISH: @@ -2691,6 +2703,8 @@ int mons_standard_rare(int mcls) { // "another lava thing" has no stats! (GDL) // case MONS_ANOTHER_LAVA_THING: + case MONS_MERFOLK: + case MONS_MERMAID: case MONS_BIG_FISH: case MONS_ELECTRICAL_EEL: case MONS_GIANT_GOLDFISH: diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 764de91b12..8428a4f0a7 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -488,6 +488,11 @@ bool mons_is_humanoid( int mc ) case 'T': // trolls return (true); + case 'm': // merfolk + if (mc == MONS_MERFOLK || mc == MONS_MERMAID) + return (true); + return (false); + case 'g': // goblines, hobgoblins, gnolls, boggarts -- but not gargoyles if (mc != MONS_GARGOYLE && mc != MONS_METAL_GARGOYLE @@ -2169,6 +2174,7 @@ const char *mons_pronoun(monster_type mon_type, pronoun_type variant) case MONS_EROLCHA: case MONS_ERICA: case MONS_TIAMAT: + case MONS_MERMAID: gender = GENDER_FEMALE; break; default: diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc index 3327b51253..067b825e38 100644 --- a/crawl-ref/source/monplace.cc +++ b/crawl-ref/source/monplace.cc @@ -104,7 +104,9 @@ bool monster_habitable_grid(int monster_class, int actual_grid, int flies, // And water elementals are native to the water but happy on land // as well. - || (monster_class == MONS_WATER_ELEMENTAL + || ((monster_class == MONS_WATER_ELEMENTAL + || monster_class == MONS_MERFOLK + || monster_class == MONS_MERMAID) && grid_compatible(DNGN_FLOOR, actual_grid))); } @@ -113,6 +115,8 @@ bool monster_can_submerge(int monster_class, int grid) { switch (monster_class) { + case MONS_MERFOLK: + case MONS_MERMAID: case MONS_BIG_FISH: case MONS_GIANT_GOLDFISH: case MONS_ELECTRICAL_EEL: diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 322cc9163c..b3a2eb4995 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -422,6 +422,8 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent) if (net != NON_ITEM) remove_item_stationary(mitm[net]); } + // update list of monsters beholding player + update_beholders(monster, true); const int monster_killed = monster_index(monster); const bool death_message = @@ -2321,6 +2323,8 @@ static void handle_nearby_ability(monsters *monster) case MONS_LAVA_FISH: case MONS_LAVA_SNAKE: case MONS_SALAMANDER: + case MONS_MERFOLK: + case MONS_MERMAID: case MONS_BIG_FISH: case MONS_GIANT_GOLDFISH: case MONS_ELECTRICAL_EEL: @@ -2328,18 +2332,22 @@ static void handle_nearby_ability(monsters *monster) case MONS_WATER_ELEMENTAL: case MONS_SWAMP_WORM: if (monster_can_submerge(monster->type, grd[monster->x][monster->y]) - && (one_chance_in(5) || (grid_distance( monster->x, monster->y, - you.x_pos, you.y_pos ) > 1 + && ( !player_beheld_by(monster) // no submerging if player entranced + && (one_chance_in(5) || (grid_distance( monster->x, monster->y, + you.x_pos, you.y_pos ) > 1 // FIXME This is better expressed as a // function such as // monster_has_ranged_attack: && monster->type != MONS_ELECTRICAL_EEL && monster->type != MONS_LAVA_SNAKE - && !one_chance_in(20)) + && (monster->type != MONS_MERMAID + || you.species == SP_MERFOLK) + && !one_chance_in(20)) ) || monster->hit_points <= monster->max_hit_points / 2) || env.cgrid[monster->x][monster->y] != EMPTY_CLOUD) { monster->add_ench(ENCH_SUBMERGED); + update_beholders(monster); } break; @@ -2668,6 +2676,87 @@ static bool handle_special_ability(monsters *monster, bolt & beem) } break; + case MONS_MERMAID: + { + // won't sing if either of you silenced, or it's friendly or confused + if (monster->has_ench(ENCH_CONFUSION) || mons_friendly(monster) + || silenced(monster->x, monster->y) || silenced(you.x_pos, you.y_pos)) + { + break; + } + + // reduce probability because of spamminess + if (you.species == SP_MERFOLK && !one_chance_in(4)) + break; + + // a wounded invisible mermaid is less likely to give away her position + if (monster->invisible() + && monster->hit_points <= monster->max_hit_points / 2 + && !one_chance_in(3)) + { + break; + } + + bool already_beheld = player_beheld_by(monster); + + if (one_chance_in(5) + || monster->foe == MHITYOU && !already_beheld && coinflip()) + { + if (player_monster_visible(monster)) + { + simple_monster_message(monster, + make_stringf(" chants %s song.", + already_beheld? "her luring" : "a haunting").c_str(), + MSGCH_MONSTER_SPELL); + } + else + { + // if you're already beheld by an invisible mermaid she can + // still prolong the enchantment; otherwise you "resist" + if (already_beheld) + mpr("You hear a luring song.", MSGCH_SOUND); + else + { + if (one_chance_in(4)) // reduce spamminess + { + if (coinflip()) + mpr("You hear a haunting song.", MSGCH_SOUND); + else + mpr("You hear an eerie melody.", MSGCH_SOUND); + + canned_msg(MSG_YOU_RESIST); // flavour only + } + break; + } + } + + // once beheld by a particular monster, cannot resist anymore + if (!already_beheld + && (you.species == SP_MERFOLK || you_resist_magic(100))) + { + canned_msg(MSG_YOU_RESIST); + break; + } + + if (!you.duration[DUR_BEHELD]) + { + you.duration[DUR_BEHELD] = 7; + you.beheld_by.push_back(monster_index(monster)); + mpr("You are beheld!", MSGCH_WARN); + } + else + { + you.duration[DUR_BEHELD] += 5; + if (!already_beheld) + you.beheld_by.push_back(monster_index(monster)); + } + used = true; + + if (you.duration[DUR_BEHELD] > 12) + you.duration[DUR_BEHELD] = 12; + } + break; + } default: break; } @@ -4241,6 +4330,8 @@ static void handle_monster_move(int i, monsters *monster) if (!monster_move(monster)) monster->speed_increment -= non_move_energy; } + update_beholders(monster); + // reevaluate behaviour, since the monster's // surroundings have changed (it may have moved, // or died for that matter. Don't bother for @@ -4306,7 +4397,15 @@ void handle_monsters(void) // If the player got banished, discard pending monster actions. if (you.banished) + { + // clear list of beholding monsters + if (you.duration[DUR_BEHELD]) + { + you.beheld_by.clear(); + you.duration[DUR_BEHELD] = 0; + } break; + } } // end of for loop // Clear any summoning flags so that lower indiced @@ -5493,6 +5592,8 @@ dungeon_feature_type monster_habitat(int which_class) { switch (which_class) { + case MONS_MERFOLK: + case MONS_MERMAID: case MONS_BIG_FISH: case MONS_GIANT_GOLDFISH: case MONS_ELECTRICAL_EEL: diff --git a/crawl-ref/source/output.cc b/crawl-ref/source/output.cc index a6aac29f88..27b9a16a17 100644 --- a/crawl-ref/source/output.cc +++ b/crawl-ref/source/output.cc @@ -541,6 +541,12 @@ void print_stats(void) textcolor( RED ); // no different levels cprintf( "Conf " ); } + + if (you.duration[DUR_BEHELD]) + { + textcolor( RED ); // no different levels + cprintf( "Bhld " ); + } if (you.duration[DUR_LIQUID_FLAMES]) { diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index 674e2df54c..02266afb2a 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -2324,7 +2324,7 @@ int player_see_invis(bool calc_unid) // This does NOT do line of sight! It checks the monster's visibility // with repect to the players perception, but doesn't do walls or range... -// to find if the square the monster is in is visible see mons_near(). +// to find if the square the monster is in los see mons_near(). bool player_monster_visible( const monsters *mon ) { if (mon->has_ench(ENCH_SUBMERGED) @@ -2336,6 +2336,69 @@ bool player_monster_visible( const monsters *mon ) return (true); } +// returns true if player is beheld by a given monster +bool player_beheld_by( const monsters *mon ) +{ + if (!you.duration[DUR_BEHELD]) + return false; + + // can this monster even behold you? + if (mon->type != MONS_MERMAID) + return false; + +#ifdef DEBUG_DIAGNOSTICS + mprf(MSGCH_DIAGNOSTICS, "beheld_by.size: %d, DUR_BEHELD: %d, current mon: %d", + you.beheld_by.size(), you.duration[DUR_BEHELD], + monster_index(mon)); +#endif + + if (you.beheld_by.empty()) // shouldn't happen + { + you.duration[DUR_BEHELD] = 0; + return false; + } + + for (unsigned int i = 0; i < you.beheld_by.size(); i++) + { + unsigned int which_mon = you.beheld_by[i]; + if (monster_index(mon) == which_mon) + return true; + } + + return false; +} + +// removes a monster from the list of beholders +// if force == true (e.g. monster dead) or one of +// several cases is met +void update_beholders(const monsters *mon, bool force) +{ + if (!player_beheld_by(mon)) // not in list? + return; + + // is an update even necessary? + if (force || !mons_near(mon) || mons_friendly(mon) || mon->submerged() + || mon->has_ench(ENCH_CONFUSION) || mons_is_paralysed(mon) || mon->asleep() + || silenced(you.x_pos, you.y_pos) || silenced(mon->x, mon->y)) + { + const std::vector<int> help = you.beheld_by; + you.beheld_by.clear(); + + for (unsigned int i = 0; i < help.size(); i++) + { + unsigned int which_mon = help[i]; + if (monster_index(mon) != which_mon) + you.beheld_by.push_back(i); + } + + if (you.beheld_by.empty()) + { + mpr("You are no longer entranced.", MSGCH_RECOVERY); + you.duration[DUR_BEHELD] = 0; + } + } +} + int player_sust_abil(bool calc_unid) { int sa = 0; @@ -3362,6 +3425,9 @@ void display_char_status() if (you.duration[DUR_CONF]) mpr( "You are confused." ); + if (you.duration[DUR_BEHELD]) + mpr( "You are beheld." ); + if (you.duration[DUR_PARALYSIS]) mpr( "You are paralysed." ); diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h index 390ce4e505..95e35193f9 100644 --- a/crawl-ref/source/player.h +++ b/crawl-ref/source/player.h @@ -263,6 +263,8 @@ int slaying_bonus(char which_affected); int player_see_invis(bool calc_unid = true); bool player_monster_visible( const monsters *mon ); +bool player_beheld_by( const monsters *mon ); +void update_beholders( const monsters *mon, bool force = false); /* *********************************************************************** * called from: acr - decks - it_use2 - ouch diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc index f7dde163dc..2358498568 100644 --- a/crawl-ref/source/spells4.cc +++ b/crawl-ref/source/spells4.cc @@ -1232,6 +1232,13 @@ void cast_silence(int pow) if (you.duration[DUR_SILENCE] > 100) you.duration[DUR_SILENCE] = 100; + + if (you.duration[DUR_BEHELD]) + { + mpr("You break out of your daze!", MSGCH_RECOVERY); + you.duration[DUR_BEHELD] = 0; + you.beheld_by.clear(); + } } // end cast_silence() diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc index e4631d3f6d..818da4051c 100644 --- a/crawl-ref/source/tags.cc +++ b/crawl-ref/source/tags.cc @@ -928,6 +928,11 @@ static void tag_construct_you(struct tagHeader &th) marshallShort(th, you.transit_stair); marshallByte(th, you.entering_level); + + // list of currently beholding monsters (usually empty) + marshallByte(th, you.beheld_by.size()); + for (unsigned int k = 0; k < you.beheld_by.size(); k++) + marshallByte(th, you.beheld_by[k]); } static void tag_construct_you_items(struct tagHeader &th) @@ -1263,6 +1268,11 @@ static void tag_read_you(struct tagHeader &th, char minorVersion) you.transit_stair = static_cast<dungeon_feature_type>(unmarshallShort(th)); you.entering_level = unmarshallByte(th); + + // list of currently beholding monsters (usually empty) + count_c = unmarshallByte(th); + for (i = 0; i < count_c; i++) + you.beheld_by.push_back(unmarshallByte(th)); } static void tag_read_you_items(struct tagHeader &th, char minorVersion) diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index 80612fda71..c7018aa032 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -1359,6 +1359,15 @@ bool noisy( int loudness, int nois_x, int nois_y, const char *msg ) you.check_awaken(dist - player_distance); + if (loudness >= 20 && you.duration[DUR_BEHELD]) + { + mprf("For a moment, you cannot hear the mermaid%s!", + you.beheld_by.size() == 1? "" : "s"); + mpr("You break out of your daze!", MSGCH_DURATION); + you.duration[DUR_BEHELD] = 0; + you.beheld_by.clear(); + } + ret = true; } |