From a69d08bdd16aefda2a5fc616d9244a1d944fd11e Mon Sep 17 00:00:00 2001
From: argonaut <none>
Date: Tue, 5 Nov 2013 21:36:00 +0000
Subject: [PATCH 1/3] Don't timeout repel/deflect missiles

Instead they'll deflect a set (random) number when cast.

This does 2 things: prevents the tedium of recasting while travelling,
and makes it more likely that you'll need to recast in combat (since
that's the only time it goes away).
---
 crawl-ref/source/beam.cc         |    1 +
 crawl-ref/source/main.cc         |   10 ---------
 crawl-ref/source/player.cc       |   43 ++++++++++++++++++++++++++++++++++++--
 crawl-ref/source/player.h        |    1 +
 crawl-ref/source/spl-selfench.cc |    4 ++--
 5 files changed, 45 insertions(+), 14 deletions(-)

diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index 2e8b312..0ad3d4f 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -3322,6 +3322,7 @@ bool bolt::misses_player()
         // active voice to imply stronger effect
         mprf(defl == 1 ? "The %s is repelled." : "You deflect the %s!",
              name.c_str());
+        you.decrement_deflection();
     }
     else if (!_test_beam_hit(real_tohit, dodge, is_beam, defl, r))
     {
diff --git a/crawl-ref/source/main.cc b/crawl-ref/source/main.cc
index 291f231..9466513 100644
--- a/crawl-ref/source/main.cc
+++ b/crawl-ref/source/main.cc
@@ -2425,16 +2425,6 @@ static void _decrement_durations()
 
     _decrement_a_duration(DUR_SILENCE, delay, "Your hearing returns.");
 
-    _decrement_a_duration(DUR_REPEL_MISSILES, delay,
-                          "You feel less protected from missiles.",
-                          coinflip(),
-                          "Your repel missiles spell is about to expire...");
-
-    _decrement_a_duration(DUR_DEFLECT_MISSILES, delay,
-                          "You feel less protected from missiles.",
-                          coinflip(),
-                          "Your deflect missiles spell is about to expire...");
-
     if (_decrement_a_duration(DUR_TROGS_HAND, delay,
                               NULL, coinflip(),
                               "You feel the effects of Trog's Hand fading."))
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index eb5a697..9722ff3 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -3972,6 +3972,10 @@ int get_expiration_threshold(duration_type dur)
     case DUR_PETRIFYING:
         return 1 * BASELINE_DELAY;
 
+    case DUR_REPEL_MISSILES:
+    case DUR_DEFLECT_MISSILES:
+        return (2 * BASELINE_DELAY);
+
     case DUR_QUAD_DAMAGE:
         return 3 * BASELINE_DELAY; // per client.qc
 
@@ -3979,8 +3983,6 @@ int get_expiration_threshold(duration_type dur)
     case DUR_SILENCE: // no message
         return 5 * BASELINE_DELAY;
 
-    case DUR_DEFLECT_MISSILES:
-    case DUR_REPEL_MISSILES:
     case DUR_REGENERATION:
     case DUR_RESISTANCE:
     case DUR_SWIFTNESS:
@@ -6289,6 +6291,43 @@ int player::missile_deflection() const
     return 0;
 }
 
+static void _decrement_a_deflection(duration_type dur,
+                              const char* endmsg = NULL,
+                              const char* expiremsg = NULL,
+                              msg_channel_type chan = MSGCH_DURATION)
+{
+    // use BASELINE_DELAY since set_duration scales it up by that.
+    you.duration[dur] -= BASELINE_DELAY;
+    if (you.duration[dur] < 0)
+        you.duration[dur] = 0;
+
+    if (you.duration[dur] == 2 * BASELINE_DELAY)
+    {
+        if (need_expiration_warning(dur))
+            mprf(MSGCH_DANGER, "Careful! %s", expiremsg);
+        else
+            mpr(expiremsg, chan);
+    }
+    else if (you.duration[dur] == 0)
+        mpr(endmsg, chan);
+}
+
+void player::decrement_deflection()
+{
+    if (duration[DUR_DEFLECT_MISSILES] > 0)
+    {
+        _decrement_a_deflection(DUR_DEFLECT_MISSILES,
+                          "You feel less protected from missiles.",
+                          "Your deflect missiles spell is about to expire...");
+    }
+    else if (duration[DUR_REPEL_MISSILES] > 0)
+    {
+        _decrement_a_deflection(DUR_REPEL_MISSILES,
+                          "You feel less protected from missiles.",
+                          "Your repel missiles spell is about to expire...");
+    }
+}
+
 int player::unadjusted_body_armour_penalty() const
 {
     const item_def *body_armour = slot_item(EQ_BODY_ARMOUR, false);
diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h
index d65df58..2b48f3e 100644
--- a/crawl-ref/source/player.h
+++ b/crawl-ref/source/player.h
@@ -696,6 +696,7 @@ public:
     int shield_bypass_ability(int tohit) const;
     void shield_block_succeeded(actor *foe);
     int missile_deflection() const;
+    void decrement_deflection();
 
     // Combat-related adjusted penalty calculation methods
     int unadjusted_body_armour_penalty() const;
diff --git a/crawl-ref/source/spl-selfench.cc b/crawl-ref/source/spl-selfench.cc
index 905f520..3b785db 100644
--- a/crawl-ref/source/spl-selfench.cc
+++ b/crawl-ref/source/spl-selfench.cc
@@ -113,7 +113,7 @@ spret_type ice_armour(int pow, bool fail)
 spret_type missile_prot(int pow, bool fail)
 {
     fail_check();
-    you.increase_duration(DUR_REPEL_MISSILES, 8 + roll_dice(2, pow), 100,
+    you.set_duration(DUR_REPEL_MISSILES, 2 + roll_dice(2, pow / 16 + 1), 100,
                           "You feel protected from missiles.");
     return SPRET_SUCCESS;
 }
@@ -121,7 +121,7 @@ spret_type missile_prot(int pow, bool fail)
 spret_type deflection(int pow, bool fail)
 {
     fail_check();
-    you.increase_duration(DUR_DEFLECT_MISSILES, 15 + random2(pow), 100,
+    you.set_duration(DUR_DEFLECT_MISSILES, 3 + roll_dice(2, pow / 8 + 1), 100,
                           "You feel very safe from missiles.");
     return SPRET_SUCCESS;
 }
-- 
1.7.10.4

