From 8d8a727b80167a76d8282614fff1610fd9625a61 Mon Sep 17 00:00:00 2001 From: Adam Borowski Date: Thu, 31 Dec 2009 14:08:54 +0100 Subject: IOOD vs shields: blocks (boo!) and reflection (yay!) --- crawl-ref/source/beam.cc | 10 ++---- crawl-ref/source/itemprop.cc | 6 ++++ crawl-ref/source/itemprop.h | 1 + crawl-ref/source/mon-project.cc | 72 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 8 deletions(-) (limited to 'crawl-ref') diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 41eddbe46b..e991e44b51 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -3720,12 +3720,6 @@ bool bolt::is_reflectable(const item_def *it) const return (it && is_shield(*it) && shield_reflects(*it)); } -static void _ident_reflector(item_def *item) -{ - if (!is_artefact(*item)) - set_ident_flags(*item, ISFLAG_KNOW_TYPE); -} - // Reflect a beam back the direction it came. This is used // by shields of reflection. void bolt::reflect() @@ -3852,7 +3846,7 @@ bool bolt::misses_player() mprf( "Your %s reflects the %s!", you.shield()->name(DESC_PLAIN).c_str(), name.c_str() ); - _ident_reflector(you.shield()); + ident_reflector(you.shield()); reflect(); } else @@ -4818,7 +4812,7 @@ bool bolt::attempt_block(monsters* mon) name.c_str(), mon->pronoun(PRONOUN_NOCAP_POSSESSIVE).c_str(), shield->name(DESC_PLAIN).c_str()); - _ident_reflector(shield); + ident_reflector(shield); } else if (you.see_cell(pos())) mprf("The %s bounces off of thin air!", name.c_str()); diff --git a/crawl-ref/source/itemprop.cc b/crawl-ref/source/itemprop.cc index bf47f3ab96..88b579114d 100644 --- a/crawl-ref/source/itemprop.cc +++ b/crawl-ref/source/itemprop.cc @@ -2462,6 +2462,12 @@ bool shield_reflects(const item_def &shield) return (get_armour_ego_type(shield) == SPARM_REFLECTION); } +void ident_reflector(item_def *item) +{ + if (!is_artefact(*item)) + set_ident_flags(*item, ISFLAG_KNOW_TYPE); +} + std::string item_base_name(const item_def &item) { switch (item.base_type) diff --git a/crawl-ref/source/itemprop.h b/crawl-ref/source/itemprop.h index 5604d352f5..d1231bc9f5 100644 --- a/crawl-ref/source/itemprop.h +++ b/crawl-ref/source/itemprop.h @@ -84,6 +84,7 @@ bool is_shield(const item_def &item); bool is_shield_incompatible(const item_def &weapon, const item_def *shield = NULL); bool shield_reflects(const item_def &shield); +void ident_reflector(item_def *item); // Only works for armour/weapons/missiles // weapon functions: diff --git a/crawl-ref/source/mon-project.cc b/crawl-ref/source/mon-project.cc index 0af08ef38d..86ebc0a983 100644 --- a/crawl-ref/source/mon-project.cc +++ b/crawl-ref/source/mon-project.cc @@ -19,6 +19,7 @@ #include "directn.h" #include "coord.h" #include "env.h" +#include "itemprop.h" #include "mgen_data.h" #include "mon-place.h" #include "mon-stuff.h" @@ -88,6 +89,19 @@ void _iood_dissipate(monsters &mon) monster_die(&mon, KILL_DISMISSED, NON_MONSTER); } +// Alas, too much differs to reuse beam shield blocks :( +bool _iood_shielded(monsters &mon, actor &victim) +{ + if (!victim.shield() || victim.incapacitated()) + return (false); + + const int to_hit = 15 + mon.props["iood_pow"].get_short()/12; + const int con_block = random2(to_hit + victim.shield_block_penalty()); + const int pro_block = victim.shield_bonus(); + dprf("iood shield: pro %d, con %d", pro_block, con_block); + return (pro_block >= con_block); +} + bool _iood_hit(monsters &mon, const coord_def &pos, bool big_boom = false) { bolt beam; @@ -193,6 +207,8 @@ bool iood_act(monsters &mon, bool no_trail) mon.props["iood_vy"] = vy; } +reflected: + x += vx; y += vy; @@ -236,6 +252,62 @@ bool iood_act(monsters &mon, bool no_trail) return (true); } + if (victim && _iood_shielded(mon, *victim)) + { + item_def *shield = victim->shield(); + if (!shield_reflects(*shield)) + { + if (victim->atype() == ACT_PLAYER) + { + mprf("You block %s.", mon.name(DESC_NOCAP_THE, true).c_str()); + } + else + { + simple_monster_message((monsters*)victim, (" blocks the " + + mon.name(DESC_NOCAP_THE, true) + ".").c_str()); + } + victim->shield_block_succeeded(&mon); + _iood_dissipate(mon); + return (true); + } + + if (victim->atype() == ACT_PLAYER) + { + mprf("Your %s reflects %s!", + shield->name(DESC_PLAIN).c_str(), + mon.name(DESC_NOCAP_THE, true).c_str()); + ident_reflector(shield); + } + else if (you.see_cell(pos)) + { + if (victim->observable()) + { + mprf("%s reflects %s with %s %s!", + victim->name(DESC_CAP_THE, true).c_str(), + mon.name(DESC_NOCAP_THE, true).c_str(), + mon.pronoun(PRONOUN_NOCAP_POSSESSIVE).c_str(), + shield->name(DESC_PLAIN).c_str()); + ident_reflector(shield); + } + else + { + mprf("%s bounces off thin air!", + mon.name(DESC_CAP_THE, true).c_str()); + } + } + victim->shield_block_succeeded(&mon); + + mon.props["iood_vx"] = vx = -vx; + mon.props["iood_vy"] = vy = -vy; + + // Need to get out of the victim's square. + + // If you're next to the caster and both of you wear shields of + // reflection, this can lead to a brief game of ping-pong, but + // rapidly increasing shield penalties will make it short. + goto reflected; + } + if (_iood_hit(mon, pos)) return (true); } -- cgit v1.2.3-54-g00ecf