Attached Files |
newskald_spectralweapon_reset_and_more.patch [^] (12,165 bytes) 2013-06-26 13:01 [Show Content] [Hide Content]From 10e05a742f65e8cdc632ae6a41ffe855d3a22730 Mon Sep 17 00:00:00 2001
From: Ed Gonzalez <ed.gonzalez3@gmail.com>
Date: Wed, 26 Jun 2013 02:00:49 -0700
Subject: [PATCH 1/4] Make Spectral Weapon reset on player's next turn for
real this time.
If the Spectral Weapon hasn't attacked by the player's next turn, it
gets reset. This occurs either right before the next order is given to
the weapon, or (if the player did something else) after the player's
turn.
Unlike 04540f5, this reset mechanism doesn't prevent the spectral weapon
from ever attacking.
---
crawl-ref/source/mon-act.cc | 1 +
crawl-ref/source/spl-summoning.cc | 34 +++++++++++++++++++++++++++++++---
crawl-ref/source/spl-summoning.h | 1 +
3 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/crawl-ref/source/mon-act.cc b/crawl-ref/source/mon-act.cc
index 8e11232..95eb962 100644
--- a/crawl-ref/source/mon-act.cc
+++ b/crawl-ref/source/mon-act.cc
@@ -1799,6 +1799,7 @@ static void _pre_monster_move(monster* mons)
}
reset_battlesphere(mons);
+ reset_spectral_weapon(mons);
// This seems to need to go here to actually get monsters to slow down.
// XXX: Replace with a new ENCH_LIQUEFIED_GROUND or something.
diff --git a/crawl-ref/source/spl-summoning.cc b/crawl-ref/source/spl-summoning.cc
index c0b8d68..034ea5f 100644
--- a/crawl-ref/source/spl-summoning.cc
+++ b/crawl-ref/source/spl-summoning.cc
@@ -3052,12 +3052,37 @@ bool trigger_spectral_weapon(actor* agent, const actor* target)
if (target->as_monster() == spectral_weapon)
return false;
+ // Clear out any old orders.
+ reset_spectral_weapon(spectral_weapon);
+
spectral_weapon->props["target_mid"].get_int() = target->mid;
- spectral_weapon->props["ready"] = true;
+ spectral_weapon->props["readied"] = true;
return true;
}
+// Called at the start of each round. Cancels attack order given in the
+// previous round, if the weapon was not able to execute them fully
+// before the next player action
+void reset_spectral_weapon(monster* mons)
+{
+ if (!mons || mons->type != MONS_SPECTRAL_WEAPON)
+ return;
+
+ if (mons->props.exists("tracking"))
+ {
+ mons->props.erase("tracking");
+ mons->props.erase("readied");
+ mons->props.erase("target_mid");
+
+ return;
+ }
+
+ // If an attack has been readied, begin tracking.
+ if (mons->props.exists("readied"))
+ mons->props["tracking"] = true;
+}
+
/* Checks if the spectral weapon is targetting the given position.
*
* Checks that the defender is our actual target.
@@ -3079,11 +3104,14 @@ bool check_target_spectral_weapon(const actor* mons, const actor *defender)
*/
bool confirm_attack_spectral_weapon(monster* mons, const actor *defender)
{
+ // No longer tracking towards the target.
+ mons->props.erase("tracking");
+
if (check_target_spectral_weapon(mons, defender)
- && mons->props.exists("ready"))
+ && mons->props.exists("readied"))
{
// Consume our ready state and attack
- mons->props.erase("ready");
+ mons->props.erase("readied");
return true;
}
diff --git a/crawl-ref/source/spl-summoning.h b/crawl-ref/source/spl-summoning.h
index 138741b..c5fde0b 100644
--- a/crawl-ref/source/spl-summoning.h
+++ b/crawl-ref/source/spl-summoning.h
@@ -98,6 +98,7 @@ void end_spectral_weapon(monster* mons, bool killed, bool quiet = false);
bool trigger_spectral_weapon(actor* agent, const actor* target);
bool check_target_spectral_weapon(const actor* mons, const actor *defender);
bool confirm_attack_spectral_weapon(monster* mons, const actor *defender);
+void reset_spectral_weapon(monster* mons);
bool summoned_monster(monster* mons, actor* caster, spell_type spell);
bool summons_are_capped(spell_type spell);
--
1.7.10.4
From 3161427aaee289ea7bc2d90f7e14b2bfa058c3a9 Mon Sep 17 00:00:00 2001
From: Ed Gonzalez <ed.gonzalez3@gmail.com>
Date: Wed, 26 Jun 2013 02:35:06 -0700
Subject: [PATCH 2/4] Prefix spectral weapon properties with "sw_" and use
#define for them.
This allows easier understanding of what code uses the properties,
reduces chances of conflicts, and helps catch mispellings.
---
crawl-ref/source/mon-behv.cc | 4 ++--
crawl-ref/source/mon-stuff.cc | 4 ++--
crawl-ref/source/spl-summoning.cc | 26 +++++++++++++-------------
crawl-ref/source/spl-summoning.h | 7 +++++++
4 files changed, 24 insertions(+), 17 deletions(-)
diff --git a/crawl-ref/source/mon-behv.cc b/crawl-ref/source/mon-behv.cc
index 4980c78..4ced6ad 100644
--- a/crawl-ref/source/mon-behv.cc
+++ b/crawl-ref/source/mon-behv.cc
@@ -387,9 +387,9 @@ void handle_behaviour(monster* mon)
mon->target = owner->pos();
mon->foe = MHITNOT;
// Try to move towards any monsters the owner is attacking
- if (mon->props.exists("target_mid"))
+ if (mon->props.exists(SW_TARGET_MID))
{
- actor *atarget = actor_by_mid(mon->props["target_mid"].get_int());
+ actor *atarget = actor_by_mid(mon->props[SW_TARGET_MID].get_int());
// Only go after the target if the owner can still reach
// FIXME: intervening features are currently ignored
diff --git a/crawl-ref/source/mon-stuff.cc b/crawl-ref/source/mon-stuff.cc
index 0466d46..32db8a5 100644
--- a/crawl-ref/source/mon-stuff.cc
+++ b/crawl-ref/source/mon-stuff.cc
@@ -3571,9 +3571,9 @@ bool summon_can_attack(const monster* mons, const coord_def &p)
{
// FIXME: find a way to use check_target_spectral_weapon
// without potential info leaks about visibility.
- if (mons->props.exists("target_mid"))
+ if (mons->props.exists(SW_TARGET_MID))
{
- actor *target = actor_by_mid(mons->props["target_mid"].get_int());
+ actor *target = actor_by_mid(mons->props[SW_TARGET_MID].get_int());
return (target && target->pos() == p);
}
return false;
diff --git a/crawl-ref/source/spl-summoning.cc b/crawl-ref/source/spl-summoning.cc
index 034ea5f..8c5f0ba 100644
--- a/crawl-ref/source/spl-summoning.cc
+++ b/crawl-ref/source/spl-summoning.cc
@@ -3055,8 +3055,8 @@ bool trigger_spectral_weapon(actor* agent, const actor* target)
// Clear out any old orders.
reset_spectral_weapon(spectral_weapon);
- spectral_weapon->props["target_mid"].get_int() = target->mid;
- spectral_weapon->props["readied"] = true;
+ spectral_weapon->props[SW_TARGET_MID].get_int() = target->mid;
+ spectral_weapon->props[SW_READIED] = true;
return true;
}
@@ -3069,18 +3069,18 @@ void reset_spectral_weapon(monster* mons)
if (!mons || mons->type != MONS_SPECTRAL_WEAPON)
return;
- if (mons->props.exists("tracking"))
+ if (mons->props.exists(SW_TRACKING))
{
- mons->props.erase("tracking");
- mons->props.erase("readied");
- mons->props.erase("target_mid");
+ mons->props.erase(SW_TRACKING);
+ mons->props.erase(SW_READIED);
+ mons->props.erase(SW_TARGET_MID);
return;
}
// If an attack has been readied, begin tracking.
- if (mons->props.exists("readied"))
- mons->props["tracking"] = true;
+ if (mons->props.exists(SW_READIED))
+ mons->props[SW_TRACKING] = true;
}
/* Checks if the spectral weapon is targetting the given position.
@@ -3089,9 +3089,9 @@ void reset_spectral_weapon(monster* mons)
*/
bool check_target_spectral_weapon(const actor* mons, const actor *defender)
{
- if (mons->props.exists("target_mid"))
+ if (mons->props.exists(SW_TARGET_MID))
{
- mid_t target_mid = mons->props["target_mid"].get_int();
+ mid_t target_mid = mons->props[SW_TARGET_MID].get_int();
return (target_mid == defender->mid);
}
return false;
@@ -3105,13 +3105,13 @@ bool check_target_spectral_weapon(const actor* mons, const actor *defender)
bool confirm_attack_spectral_weapon(monster* mons, const actor *defender)
{
// No longer tracking towards the target.
- mons->props.erase("tracking");
+ mons->props.erase(SW_TRACKING);
if (check_target_spectral_weapon(mons, defender)
- && mons->props.exists("readied"))
+ && mons->props.exists(SW_READIED))
{
// Consume our ready state and attack
- mons->props.erase("readied");
+ mons->props.erase(SW_READIED);
return true;
}
diff --git a/crawl-ref/source/spl-summoning.h b/crawl-ref/source/spl-summoning.h
index c5fde0b..e1a47b7 100644
--- a/crawl-ref/source/spl-summoning.h
+++ b/crawl-ref/source/spl-summoning.h
@@ -14,6 +14,13 @@
#define DEAD_ARE_SLITHERING 8
#define DEAD_ARE_HOPPING 16
+
+// Properties set for active summons
+#define SW_TARGET_MID "sw_target_mid"
+#define SW_READIED "sw_readied"
+#define SW_TRACKING "sw_tracking"
+
+
spret_type cast_summon_butterflies(int pow, god_type god = GOD_NO_GOD,
bool fail = false);
spret_type cast_summon_small_mammal(int pow, god_type god, bool fail);
--
1.7.10.4
From c3c9d49e7333c0babb632d91c47d62b759fee213 Mon Sep 17 00:00:00 2001
From: Ed Gonzalez <ed.gonzalez3@gmail.com>
Date: Wed, 26 Jun 2013 02:42:44 -0700
Subject: [PATCH 3/4] On reset of a Spectral Weapon, remove the target if
we're not tracking.
---
crawl-ref/source/spl-summoning.cc | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/crawl-ref/source/spl-summoning.cc b/crawl-ref/source/spl-summoning.cc
index 8c5f0ba..985041f 100644
--- a/crawl-ref/source/spl-summoning.cc
+++ b/crawl-ref/source/spl-summoning.cc
@@ -3080,7 +3080,13 @@ void reset_spectral_weapon(monster* mons)
// If an attack has been readied, begin tracking.
if (mons->props.exists(SW_READIED))
+ {
mons->props[SW_TRACKING] = true;
+ }
+ else
+ {
+ mons->props.erase(SW_TARGET_MID);
+ }
}
/* Checks if the spectral weapon is targetting the given position.
--
1.7.10.4
From aab507fb3e26dfc33d0c55619f7090793dc1b086 Mon Sep 17 00:00:00 2001
From: Ed Gonzalez <ed.gonzalez3@gmail.com>
Date: Wed, 26 Jun 2013 03:49:21 -0700
Subject: [PATCH 4/4] Leash Spectral Weapon to a range of 2, let it attack
retreating targets.
Instead of only going after targets that could still be attacked by the
owner, it now chases after retreating/batty targets as long as it can
reach them while staying within 2 squares of its owner.
This makes it more likely to attack such targets, but also runs the risk
of putting itself (and thus the owner) at more risk.
---
crawl-ref/source/mon-behv.cc | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/crawl-ref/source/mon-behv.cc b/crawl-ref/source/mon-behv.cc
index 4ced6ad..8f1ac99 100644
--- a/crawl-ref/source/mon-behv.cc
+++ b/crawl-ref/source/mon-behv.cc
@@ -391,17 +391,23 @@ void handle_behaviour(monster* mon)
{
actor *atarget = actor_by_mid(mon->props[SW_TARGET_MID].get_int());
- // Only go after the target if the owner can still reach
- // FIXME: intervening features are currently ignored
- // because there's no good way to check if an actor
- // can make a reaching attack without actually doing so.
+ // Only go after the target if it's still near the owner,
+ // and so are we.
+ // The weapon is restricted to a leash range of 2,
+ // and things reachable within that leash range [qoala]
+ const int leash = 2;
if (atarget && atarget->alive()
&& (grid_distance(owner->pos(), atarget->pos())
- <= ((owner->reach_range() == REACH_TWO) ? 2 : 1)))
+ <= ((mon->reach_range() == REACH_TWO) ? leash + 2 : leash + 1))
+ && (grid_distance(owner->pos(), mon->pos()) <= leash))
{
mon->target = atarget->pos();
mon->foe = atarget->mindex();
}
+ else
+ {
+ reset_spectral_weapon(mon);
+ }
}
}
--
1.7.10.4
|