summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/monstuff.cc116
-rw-r--r--crawl-ref/source/monstuff.h2
-rw-r--r--crawl-ref/source/player.cc150
-rw-r--r--crawl-ref/source/spells1.cc6
4 files changed, 180 insertions, 94 deletions
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 885502f2c5..c4fa1b663a 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -2004,7 +2004,7 @@ bool swap_places(monsters *monster, const coord_def &loc)
// Returns true if this is a valid swap for this monster. If true, then
// the valid location is set in loc. (Otherwise loc becomes garbage.)
-bool swap_check(monsters *monster, coord_def &loc)
+bool swap_check(monsters *monster, coord_def &loc, bool quiet)
{
loc = you.pos();
@@ -2017,7 +2017,8 @@ bool swap_check(monsters *monster, coord_def &loc)
if (mons_is_caught(monster))
{
- simple_monster_message(monster, " is held in a net!");
+ if (!quiet)
+ simple_monster_message(monster, " is held in a net!");
return (false);
}
@@ -2029,16 +2030,18 @@ bool swap_check(monsters *monster, coord_def &loc)
{
int num_found = 0;
- for ( adjacent_iterator ai; ai; ++ai )
- if (mgrd(*ai) == NON_MONSTER && _habitat_okay( monster, grd(*ai)))
- if (one_chance_in(++num_found))
- loc = *ai;
+ for (adjacent_iterator ai; ai; ++ai)
+ if (mgrd(*ai) == NON_MONSTER && _habitat_okay( monster, grd(*ai))
+ && one_chance_in(++num_found))
+ {
+ loc = *ai;
+ }
if (num_found)
swap = true;
}
- if (!swap)
+ if (!swap && !quiet)
{
// Might not be ideal, but it's better than insta-killing
// the monster... maybe try for a short blink instead? -- bwr
@@ -2048,7 +2051,7 @@ bool swap_check(monsters *monster, coord_def &loc)
}
return (swap);
-} // end swap_places()
+}
void mons_get_damage_level( const monsters* monster, std::string& desc,
mon_dam_level_type& dam_level )
@@ -2868,7 +2871,7 @@ static bool _find_siren_water_target(monsters *mon)
ASSERT(mon->type == MONS_SIREN);
// Moving away could break the entrancement, so don't do this.
- if ((mon->pos() - you.pos()).rdist() > 6)
+ if ((mon->pos() - you.pos()).rdist() >= 6)
return (false);
// Already completely surrounded by deep water.
@@ -3469,13 +3472,11 @@ static void _handle_behaviour(monsters *mon)
if (mon->foe == MHITYOU)
{
// The foe is the player.
- if (mon->type == MONS_SIREN)
+ if (mon->type == MONS_SIREN
+ && player_mesmerised_by(mon)
+ && _find_siren_water_target(mon))
{
- if (player_mesmerised_by(mon)
- && _find_siren_water_target(mon))
- {
- break;
- }
+ break;
}
if (_try_pathfind(mon, can_move, trans_wall_block))
@@ -4343,7 +4344,77 @@ static void _handle_nearby_ability(monsters *monster)
default: break;
}
-} // end handle_nearby_ability()
+}
+
+static bool _siren_movement_effect(const monsters *monster)
+{
+ bool do_resist = (you.attribute[ATTR_HELD] || you_resist_magic(70));
+
+ if (!do_resist)
+ {
+ coord_def dir(coord_def(0,0));
+ if (monster->pos().x < you.pos().x)
+ dir.x = -1;
+ else if (monster->pos().x > you.pos().x)
+ dir.x = 1;
+ if (monster->pos().y < you.pos().y)
+ dir.y = -1;
+ else if (monster->pos().y > you.pos().y)
+ dir.y = 1;
+
+ const coord_def newpos = you.pos() + dir;
+
+ if (!in_bounds(newpos) || is_grid_dangerous(grd(newpos)))
+ {
+ do_resist = true;
+ }
+ else
+ {
+ bool swapping = false;
+ monsters *mon;
+ if (mgrd(newpos) != NON_MONSTER)
+ {
+ mon = &menv[mgrd(newpos)];
+ if (mons_wont_attack(mon)
+ && !mons_is_stationary(mon)
+ && !mons_cannot_act(mon)
+ && !mons_is_sleeping(mon)
+ && swap_check(mon, you.pos(), true))
+ {
+ swapping = true;
+ }
+ else if (!mons_is_submerged(mon))
+ do_resist = true;
+ }
+
+ if (!do_resist)
+ {
+ const coord_def oldpos = you.pos();
+ mprf("The pull of her song draws you forwards.");
+
+ if (swapping)
+ {
+ int swap_mon = mgrd(newpos);
+ // Pick the monster up.
+ mgrd(newpos) = NON_MONSTER;
+ mon->moveto(oldpos);
+
+ // Plunk it down.
+ mgrd(mon->pos()) = swap_mon;
+
+ mprf("You swap places with %s.",
+ mon->name(DESC_NOCAP_THE).c_str());
+ }
+ move_player_to_grid(newpos, true, true, true);
+
+ if (swapping)
+ mon->apply_location_effects(newpos);
+ }
+ }
+ }
+
+ return (do_resist);
+}
//---------------------------------------------------------------
//
@@ -4761,12 +4832,22 @@ static bool _handle_special_ability(monsters *monster, bolt & beem)
{
noisy(12, monster->pos(), NULL, true);
+ bool did_resist = false;
if (player_monster_visible(monster))
{
simple_monster_message(monster,
make_stringf(" chants %s song.",
already_mesmerised ? "her luring" : "a haunting").c_str(),
spl);
+
+ if (monster->type == MONS_SIREN)
+ {
+ if (_siren_movement_effect(monster))
+ {
+ canned_msg(MSG_YOU_RESIST); // flavour only
+ did_resist = true;
+ }
+ }
}
else
{
@@ -4794,7 +4875,8 @@ static bool _handle_special_ability(monsters *monster, bolt & beem)
if (!already_mesmerised
&& (you.species == SP_MERFOLK || you_resist_magic(100)))
{
- canned_msg(MSG_YOU_RESIST);
+ if (!did_resist)
+ canned_msg(MSG_YOU_RESIST);
break;
}
diff --git a/crawl-ref/source/monstuff.h b/crawl-ref/source/monstuff.h
index 93448c5aac..b48a11af5e 100644
--- a/crawl-ref/source/monstuff.h
+++ b/crawl-ref/source/monstuff.h
@@ -159,7 +159,7 @@ monsters *choose_random_monster_on_level(
* *********************************************************************** */
bool swap_places(monsters *monster);
bool swap_places(monsters *monster, const coord_def &loc);
-bool swap_check(monsters *monster, coord_def &loc);
+bool swap_check(monsters *monster, coord_def &loc, bool quiet = false);
/* ***********************************************************************
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index f9dac8ce42..8d5ff3a482 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -116,101 +116,105 @@ bool move_player_to_grid( const coord_def& p, bool stepped, bool allow_shift,
|| !swapping && (mgrd(p) == NON_MONSTER
|| mons_is_submerged( &menv[ mgrd(p) ])));
- const int cloud = env.cgrid(p);
- if (cloud != EMPTY_CLOUD && !you.confused())
- {
- const cloud_type ctype = env.cloud[ cloud ].type;
- // Don't prompt if already in a cloud of the same type.
- if (is_damaging_cloud(ctype, true)
- && (env.cgrid(you.pos()) == EMPTY_CLOUD
- || ctype != env.cloud[ env.cgrid(you.pos()) ].type))
+ // Don't prompt if force is true.
+ if (!force)
+ {
+ const int cloud = env.cgrid(p);
+ if (cloud != EMPTY_CLOUD && !you.confused())
{
- std::string prompt = make_stringf(
- "Really step into that cloud of %s?",
- cloud_name(ctype).c_str());
-
- if (!yesno(prompt.c_str(), false, 'n'))
+ const cloud_type ctype = env.cloud[ cloud ].type;
+ // Don't prompt if already in a cloud of the same type.
+ if (is_damaging_cloud(ctype, true)
+ && (env.cgrid(you.pos()) == EMPTY_CLOUD
+ || ctype != env.cloud[ env.cgrid(you.pos()) ].type))
{
- canned_msg(MSG_OK);
- you.turn_is_over = false;
- return (false);
+ std::string prompt = make_stringf(
+ "Really step into that cloud of %s?",
+ cloud_name(ctype).c_str());
+
+ if (!yesno(prompt.c_str(), false, 'n'))
+ {
+ canned_msg(MSG_OK);
+ you.turn_is_over = false;
+ return (false);
+ }
}
}
- }
- // If we're walking along, give a chance to avoid traps.
- if (stepped && !force && !you.confused())
- {
- if (new_grid == DNGN_UNDISCOVERED_TRAP)
+ // If we're walking along, give a chance to avoid traps.
+ if (stepped && !you.confused())
{
- const int skill = 4 + you.skills[SK_TRAPS_DOORS]
- + player_mutation_level(MUT_ACUTE_VISION)
- - 2 * player_mutation_level(MUT_BLURRY_VISION);
-
- if (random2(skill) > 6)
+ if (new_grid == DNGN_UNDISCOVERED_TRAP)
{
- if (trap_def* ptrap = find_trap(p))
- ptrap->reveal();
+ const int skill = 4 + you.skills[SK_TRAPS_DOORS]
+ + player_mutation_level(MUT_ACUTE_VISION)
+ - 2 * player_mutation_level(MUT_BLURRY_VISION);
- viewwindow(true, false);
+ if (random2(skill) > 6)
+ {
+ if (trap_def* ptrap = find_trap(p))
+ ptrap->reveal();
- mprf( MSGCH_WARN,
- "Wait a moment, %s! Do you really want to step there?",
- you.your_name );
+ viewwindow(true, false);
- if (!you.running.is_any_travel())
- more();
+ mprf( MSGCH_WARN,
+ "Wait a moment, %s! Do you really want to step there?",
+ you.your_name );
- exercise( SK_TRAPS_DOORS, 3 );
+ if (!you.running.is_any_travel())
+ more();
- you.turn_is_over = false;
+ exercise( SK_TRAPS_DOORS, 3 );
- return (false);
+ you.turn_is_over = false;
+
+ return (false);
+ }
}
- }
- else if (new_grid == DNGN_TRAP_MAGICAL
+ else if (new_grid == DNGN_TRAP_MAGICAL
#ifdef CLUA_BINDINGS
- || new_grid == DNGN_TRAP_MECHANICAL
- && Options.trap_prompt
+ || new_grid == DNGN_TRAP_MECHANICAL
+ && Options.trap_prompt
#endif
- || new_grid == DNGN_TRAP_NATURAL)
- {
- const trap_type type = get_trap_type(p);
- if (type == TRAP_ZOT)
+ || new_grid == DNGN_TRAP_NATURAL)
{
- if (!yes_or_no("Do you really want to step into the Zot trap"))
+ const trap_type type = get_trap_type(p);
+ if (type == TRAP_ZOT)
{
- canned_msg(MSG_OK);
- stop_running();
- you.turn_is_over = false;
- return (false);
+ if (!yes_or_no("Do you really want to step into the Zot trap"))
+ {
+ canned_msg(MSG_OK);
+ stop_running();
+ you.turn_is_over = false;
+ return (false);
+ }
}
- }
- else if (new_grid != DNGN_TRAP_MAGICAL && you.airborne())
- {
- // No prompt (shaft and mechanical traps ineffective, if flying)
- }
- else
+ else if (new_grid != DNGN_TRAP_MAGICAL && you.airborne())
+ {
+ // No prompt (shaft and mechanical traps ineffective, if flying)
+ }
+ else
#ifdef CLUA_BINDINGS
- // Prompt for any trap where you might not have enough hp
- // as defined in init.txt (see trapwalk.lua)
- if (new_grid != DNGN_TRAP_MECHANICAL
- || !clua.callbooleanfn(false, "ch_cross_trap",
- "s", trap_name(p.x, p.y)))
+ // Prompt for any trap where you might not have enough hp
+ // as defined in init.txt (see trapwalk.lua)
+ if (new_grid != DNGN_TRAP_MECHANICAL
+ || !clua.callbooleanfn(false, "ch_cross_trap",
+ "s", trap_name(p.x, p.y)))
#endif
- {
- std::string prompt = make_stringf(
- "Really step %s that %s?",
- (type == TRAP_ALARM) ? "onto" : "into",
- feature_description(new_grid, type,
- false, DESC_BASENAME, false).c_str());
-
- if (!yesno(prompt.c_str(), true, 'n'))
{
- canned_msg(MSG_OK);
- stop_running();
- you.turn_is_over = false;
- return (false);
+ std::string prompt = make_stringf(
+ "Really step %s that %s?",
+ (type == TRAP_ALARM) ? "onto" : "into",
+ feature_description(new_grid, type,
+ false, DESC_BASENAME, false).c_str());
+
+ if (!yesno(prompt.c_str(), true, 'n'))
+ {
+ canned_msg(MSG_OK);
+ stop_running();
+ you.turn_is_over = false;
+ return (false);
+ }
}
}
}
diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc
index 1c17ae78d8..dd1e0b7497 100644
--- a/crawl-ref/source/spells1.cc
+++ b/crawl-ref/source/spells1.cc
@@ -172,12 +172,12 @@ int blink(int pow, bool high_level_controlled_blink, bool wizard_blink)
}
else
{
- // no longer held in net
+ // No longer held in net.
clear_trapping_net();
move_player_to_grid(beam.target, false, true, true);
- // controlling teleport contaminates the player -- bwr
+ // Controlling teleport contaminates the player. -- bwr
if (!wizard_blink)
contaminate_player( 1, true );
}
@@ -190,7 +190,7 @@ int blink(int pow, bool high_level_controlled_blink, bool wizard_blink)
crawl_state.cancel_cmd_repeat();
return (1);
-} // end blink()
+}
void random_blink(bool allow_partial_control, bool override_abyss)
{