summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/beam.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/beam.cc')
-rw-r--r--crawl-ref/source/beam.cc118
1 files changed, 118 insertions, 0 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index d78fa1cdc4..c4443068ff 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -60,6 +60,7 @@
#include "terrain.h"
#include "traps.h"
#include "view.h"
+#include "xom.h"
#define BEAM_STOP 1000 // all beams stopped by subtracting this
// from remaining range
@@ -1507,6 +1508,14 @@ void fire_beam( bolt &pbolt, item_def *item )
canned_msg(MSG_NOTHING_HAPPENS);
}
+ if (!pbolt.is_tracer && pbolt.beam_source != NON_MONSTER)
+ {
+ if (pbolt.foe_hurt == 0 && pbolt.fr_hurt > 0)
+ xom_is_stimulated(128);
+ else if (pbolt.foe_helped > 0 && pbolt.fr_helped == 0)
+ xom_is_stimulated(128);
+ }
+
// that's it!
#ifdef WIN32CONSOLE
if (!pbolt.is_tracer)
@@ -3146,6 +3155,8 @@ static int affect_player( bolt &beam )
}
else
{
+ bool nasty = true, nice = false;
+
// BEGIN enchantment beam
if (beam.flavour != BEAM_HASTE
&& beam.flavour != BEAM_INVISIBILITY
@@ -3156,6 +3167,12 @@ static int affect_player( bolt &beam )
&& you_resist_magic( beam.ench_power ))
{
canned_msg(MSG_YOU_RESIST);
+
+ // You *could* have gotten a free teleportation in the Abyss,
+ // but no, you resisted.
+ if (beam.flavour != BEAM_TELEPORT && you.level_type == LEVEL_ABYSS)
+ xom_is_stimulated(255);
+
return (range_used_on_hit(beam));
}
@@ -3213,11 +3230,15 @@ static int affect_player( bolt &beam )
potion_effect( POT_SPEED, beam.ench_power );
contaminate_player( 1 );
beam.obvious_effect = true;
+ nasty = false;
+ nice = true;
break; // haste
case BEAM_HEALING:
potion_effect( POT_HEAL_WOUNDS, beam.ench_power );
beam.obvious_effect = true;
+ nasty = false;
+ nice = true;
break; // heal (heal wounds potion eff)
case BEAM_PARALYSIS:
@@ -3234,12 +3255,20 @@ static int affect_player( bolt &beam )
potion_effect( POT_INVISIBILITY, beam.ench_power );
contaminate_player( 1 + random2(2) );
beam.obvious_effect = true;
+ nasty = false;
+ nice = true;
break; // invisibility
// 6 is used by digging
case BEAM_TELEPORT:
you_teleport();
+
+ // An enemy helping you escape while in the Abyss, or an
+ // enemy stabalizing a teleport that was about to happen.
+ if (beam.attitude == ATT_HOSTILE && you.level_type == LEVEL_ABYSS)
+ xom_is_stimulated(255);
+
beam.obvious_effect = true;
break;
@@ -3312,6 +3341,28 @@ static int affect_player( bolt &beam )
break;
} // end of switch (beam.colour)
+ if (nasty)
+ {
+ if (beam.attitude != ATT_HOSTILE)
+ {
+ beam.fr_hurt++;
+ xom_is_stimulated(128);
+ }
+ else
+ beam.foe_hurt++;
+ }
+
+ if (nice)
+ {
+ if (beam.attitude != ATT_HOSTILE)
+ beam.fr_helped++;
+ else
+ {
+ beam.foe_helped++;
+ xom_is_stimulated(128);
+ }
+ }
+
// regardless of affect, we need to know if this is a stopper
// or not - it seems all of the above are.
return (range_used_on_hit(beam));
@@ -3359,6 +3410,9 @@ static int affect_player( bolt &beam )
}
}
+ bool was_affected = false;
+ int old_hp = you.hp;
+
if (hurted < 0)
hurted = 0;
@@ -3367,10 +3421,16 @@ static int affect_player( bolt &beam )
if (beam.flavour == BEAM_MIASMA && hurted > 0)
{
if (player_res_poison() <= 0)
+ {
poison_player(1);
+ was_affected = true;
+ }
if (one_chance_in( 3 + 2 * player_prot_life() ))
+ {
potion_effect( POT_SLOWING, 5 );
+ was_affected = true;
+ }
}
// poisoning
@@ -3383,17 +3443,22 @@ static int affect_player( bolt &beam )
&& random2(100) < 90 - (3 * player_AC())))
{
poison_player( 1 + random2(3) );
+ was_affected = true;
}
}
if (beam.name.find("throwing net") != std::string::npos)
+ {
player_caught_in_net();
+ was_affected = true;
+ }
if (beam.name.find("curare") != std::string::npos)
{
if (random2(100) < 90 - (3 * player_AC()))
{
curare_hits_player( beam_ouch_agent(beam), 1 + random2(3) );
+ was_affected = true;
}
}
@@ -3403,7 +3468,10 @@ static int affect_player( bolt &beam )
|| you.experience_level < 6))
{
if (!player_equip( EQ_BODY_ARMOUR, ARM_MOTTLED_DRAGON_ARMOUR ))
+ {
you.duration[DUR_LIQUID_FLAMES] += random2avg(7, 3) + 1;
+ was_affected = true;
+ }
}
// simple cases for scroll burns
@@ -3429,6 +3497,21 @@ static int affect_player( bolt &beam )
mprf(MSGCH_DIAGNOSTICS, "Damage: %d", hurted );
#endif
+ if (hurted > 0 || old_hp < you.hp || was_affected)
+ {
+ if (beam.attitude != ATT_HOSTILE)
+ {
+ beam.fr_hurt++;
+
+ // Xom's ammusement at the player being damaged is handled
+ // elsewhere.
+ if (was_affected)
+ xom_is_stimulated(128);
+ }
+ else
+ beam.foe_hurt++;
+ }
+
beam_ouch( hurted, beam );
return (range_used_on_hit( beam ));
@@ -3462,6 +3545,24 @@ static int name_to_skill_level(const std::string& name)
return (2 * you.skills[type]);
}
+static void update_hurt_or_helped(bolt &beam, monsters *mon)
+{
+ if (beam.attitude != mons_attitude(mon))
+ {
+ if (nasty_beam(mon, beam))
+ beam.foe_hurt++;
+ else if (nice_beam(mon, beam))
+ beam.foe_helped++;
+ }
+ else
+ {
+ if (nasty_beam(mon, beam))
+ beam.fr_hurt++;
+ else if (nice_beam(mon, beam))
+ beam.fr_helped++;
+ }
+}
+
// return amount of range used up by affectation of this monster
static int affect_monster(bolt &beam, monsters *mon)
{
@@ -3513,6 +3614,7 @@ static int affect_monster(bolt &beam, monsters *mon)
"crumbles away!");
}
beam.obvious_effect = true;
+ update_hurt_or_helped(beam, mon);
mon->hit_points = 0;
monster_die(mon, beam);
return (BEAM_STOP);
@@ -3585,6 +3687,7 @@ static int affect_monster(bolt &beam, monsters *mon)
beam.msg_generated = true;
break;
default:
+ update_hurt_or_helped(beam, mon);
break;
}
return (rangeUsed);
@@ -3725,6 +3828,8 @@ static int affect_monster(bolt &beam, monsters *mon)
return (0);
}
+ update_hurt_or_helped(beam, mon);
+
// the beam hit.
if (mons_near(mon))
{
@@ -4606,6 +4711,18 @@ bool nasty_beam(monsters *mon, bolt &beam)
return (true);
}
+bool nice_beam( struct monsters *mon, struct bolt &beam )
+{
+ // haste
+ if (beam.flavour == BEAM_HASTE || beam.flavour == BEAM_HEALING
+ || beam.flavour == BEAM_INVISIBILITY)
+ {
+ return (true);
+ }
+
+ return (false);
+}
+
////////////////////////////////////////////////////////////////////////////
// bolt
@@ -4624,6 +4741,7 @@ bolt::bolt() : range(0), rangeMax(0), type(SYM_ZAP), colour(BLACK),
is_thrown(false), target_first(false), aimed_at_spot(false),
aux_source(), obvious_effect(false), effect_known(true),
fr_count(0), foe_count(0), fr_power(0), foe_power(0),
+ fr_hurt(0), foe_hurt(0), fr_helped(0), foe_helped(0),
is_tracer(false), aimed_at_feet(false), msg_generated(false),
in_explosion_phase(false), smart_monster(false),
can_see_invis(false), attitude(ATT_HOSTILE), foe_ratio(0),