Attached Files |
0001-Add-the-Hellbinder-s-staff.patch [^] (19,578 bytes) 2014-05-03 19:49 [Show Content] [Hide Content]From 20ae4981658118882a43ecd12944102eb0aa444e Mon Sep 17 00:00:00 2001
From: Nicholas Feinberg <pleasingfung@gmail.com>
Date: Fri, 11 Apr 2014 08:29:44 -0700
Subject: [PATCH] Add the Hellbinder's staff
Adds the quarterstaff of the Hellbinder, a powerful
spell-enhancing unrand that costs hp with every spell cast.
---
crawl-ref/source/art-data.txt | 10 ++
crawl-ref/source/art-func.h | 17 +++
crawl-ref/source/dat/descript/unrand.txt | 8 ++
crawl-ref/source/hiscores.cc | 20 ++++
crawl-ref/source/ouch.h | 1 +
crawl-ref/source/player.cc | 29 +++++
crawl-ref/source/player.h | 3 +
crawl-ref/source/rltiles/dc-player.txt | 1 +
.../item/weapon/artefact/spwpn_hellbinder.png | Bin 0 -> 1549 bytes
.../rltiles/player/hand1/artefact/hellbinder.png | Bin 0 -> 1344 bytes
crawl-ref/source/spl-cast.cc | 123 +++++++++++++++++++--
crawl-ref/source/spl-util.cc | 15 ++-
12 files changed, 212 insertions(+), 15 deletions(-)
create mode 100644 crawl-ref/source/rltiles/item/weapon/artefact/spwpn_hellbinder.png
create mode 100644 crawl-ref/source/rltiles/player/hand1/artefact/hellbinder.png
diff --git a/crawl-ref/source/art-data.txt b/crawl-ref/source/art-data.txt
index 4162a70..719751e 100644
--- a/crawl-ref/source/art-data.txt
+++ b/crawl-ref/source/art-data.txt
@@ -1150,6 +1150,16 @@ PLUS: +7/+7
BRAND: SPWPN_FLAMING
FIRE: 2
+NAME: quarterstaff of the Hellbinder
+OBJ: OBJ_WEAPONS/WPN_QUARTERSTAFF
+PLUS: +6/+6
+COLOUR: ETC_UNHOLY
+TILE: spwpn_hellbinder
+TILE_EQ: hellbinder
+MP: 6
+INT: 6
+BRAND: SPWPN_VAMPIRICISM
+
# This is the first of two amulets used to test suppression aura.
# Together, they confer every randart effect except for a few that are
# determined explicitly by checking whether a certain amulet is worn
diff --git a/crawl-ref/source/art-func.h b/crawl-ref/source/art-func.h
index b5f0153..e68065e 100644
--- a/crawl-ref/source/art-func.h
+++ b/crawl-ref/source/art-func.h
@@ -1084,3 +1084,20 @@ static void _FIRESTARTER_melee_effects(item_def* weapon, actor* attacker,
}
}
}
+
+///////////////////////////////////////////////////
+
+static void _HELLBINDER_equip(item_def *item, bool *show_msgs, bool unmeld)
+{
+ if (you.max_magic_points)
+ _equip_mpr(show_msgs, "You feel a darkness envelop your magic.");
+}
+
+static void _HELLBINDER_unequip(item_def *item, bool *show_msgs)
+{
+ if (you.max_magic_points)
+ {
+ _equip_mpr(show_msgs,
+ "The darkness slowly releases its grasp on your magic.");
+ }
+}
diff --git a/crawl-ref/source/dat/descript/unrand.txt b/crawl-ref/source/dat/descript/unrand.txt
index bf56388..63e4070 100644
--- a/crawl-ref/source/dat/descript/unrand.txt
+++ b/crawl-ref/source/dat/descript/unrand.txt
@@ -563,6 +563,14 @@ great mace "Firestarter"
Alongside its obvious effects, this weapon protects its owner's inventory from
fire, and fills monsters that it hits with an inner flame.
%%%%
+quarterstaff of the Hellbinder
+
+The Hellbinder's staff is actually a mighty demon, tricked and trapped in this
+form long ago. To survive, she now offers tremendous arcane power at a small
+price: a small portion of the caster’s life essence, taken alongside the magic
+used every time its wielder casts a spell. Of course - the demon is more than
+happy to suck the life from others, as well.
+%%%%
milk chocolate
This item is a debugging aid, granting a vast array of mostly beneficial
diff --git a/crawl-ref/source/hiscores.cc b/crawl-ref/source/hiscores.cc
index 05d77a6..5d7c83b 100644
--- a/crawl-ref/source/hiscores.cc
+++ b/crawl-ref/source/hiscores.cc
@@ -622,6 +622,7 @@ static const char *kill_method_names[] =
"beogh_smiting", "divine_wrath", "bounce", "reflect", "self_aimed",
"falling_through_gate", "disintegration", "headbutt", "rolling",
"mirror_damage", "spines", "frailty", "barbs", "being_thrown",
+ "corrupted_magic",
};
static const char *_kill_method_name(kill_method_type kmt)
@@ -1978,6 +1979,12 @@ static bool _species_is_undead(int sp)
return sp == SP_MUMMY || sp == SP_GHOUL || sp == SP_VAMPIRE;
}
+/**
+ * Describes the cause of the player's death.
+ *
+ * @param verbosity The verbosity of the description.
+ * @return A description of the cause of death.
+ */
string scorefile_entry::death_description(death_desc_verbosity verbosity) const
{
bool needs_beam_cause_line = false;
@@ -2506,6 +2513,19 @@ string scorefile_entry::death_description(death_desc_verbosity verbosity) const
needs_damage = true;
break;
+ case KILLED_BY_CORRUPTED_MAGIC:
+ if (terse)
+ desc += "corrupted magic";
+ else
+ {
+ desc += "Soul eaten by corrupted magic";
+ if (!auxkilldata.empty())
+ desc += " (" + auxkilldata + ")";
+ }
+ needs_damage = true;
+ break;
+
+
default:
desc += terse? "program bug" : "Nibbled to death by software bugs";
break;
diff --git a/crawl-ref/source/ouch.h b/crawl-ref/source/ouch.h
index 8aeb494..9423b50 100644
--- a/crawl-ref/source/ouch.h
+++ b/crawl-ref/source/ouch.h
@@ -65,6 +65,7 @@ enum kill_method_type
KILLED_BY_FRAILTY,
KILLED_BY_BARBS,
KILLED_BY_BEING_THROWN,
+ KILLED_BY_CORRUPTED_MAGIC,
NUM_KILLBY
};
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index e19c638..811f2af 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -7189,6 +7189,35 @@ bool player::tengu_flight() const
return species == SP_TENGU && flight_mode();
}
+/**
+ * Returns the HP cost (per MP) of casting a spell.
+ *
+ * Checks to see if the player is wielding the quarterstaff of the Hellbinder.
+ *
+ * @return The HP cost (per MP) of casting a spell.
+ **/
+int player::spell_hp_cost() const
+{
+ int cost = 0;
+
+ if (player_equip_unrand(UNRAND_HELLBINDER))
+ cost += 1;
+
+ return cost;
+}
+
+/**
+ * Returns true if player spellcasting is considered unholy.
+ *
+ * Checks to see if the player is wielding the quarterstaff of the Hellbinder.
+ *
+ * @return Whether player spellcasting is an unholy act.
+ */
+bool player::spellcasting_unholy() const
+{
+ return player_equip_unrand(UNRAND_HELLBINDER);
+}
+
bool player::nightvision() const
{
return is_undead
diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h
index 9c68717..b98e349 100644
--- a/crawl-ref/source/player.h
+++ b/crawl-ref/source/player.h
@@ -444,6 +444,9 @@ public:
bool tengu_flight() const;
+ int spell_hp_cost() const;
+ bool spellcasting_unholy() const;
+
// Dealing with beholders. Implemented in behold.cc.
void add_beholder(const monster* mon, bool axe = false);
bool beheld() const;
diff --git a/crawl-ref/source/rltiles/dc-player.txt b/crawl-ref/source/rltiles/dc-player.txt
index 78b90ca..ac689b6 100644
--- a/crawl-ref/source/rltiles/dc-player.txt
+++ b/crawl-ref/source/rltiles/dc-player.txt
@@ -508,6 +508,7 @@ shillelagh SHILLELAGH
dark_maul DARK_MAUL
spellbinder SPELLBINDER
firestarter FIRESTARTER
+hellbinder HELLBINDER
## polearms
trident_octopus_king TRIDENT_OCTOPUS_KING
glaive_of_prune GLAIVE_OF_PRUNE
diff --git a/crawl-ref/source/rltiles/item/weapon/artefact/spwpn_hellbinder.png b/crawl-ref/source/rltiles/item/weapon/artefact/spwpn_hellbinder.png
new file mode 100644
index 0000000000000000000000000000000000000000..fe5af2d4736f5580456881f3f26871e998b2fe9b
GIT binary patch
literal 1549
zcmV+o2J-odP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F8000CeX+uL$Nkc;*
zP;zf(X>4Tx05}naRo`#hR1`jmZ&IWdKOk5~hl<6oRa0BJ8yc;~21%2p?MfD<>DVeH
z<T^KrsT&8|>9(p*dx19w`~g7O0}n_%Aq@s%d)fBDv`JHkDym6Hd+5XuAtvnwRpGmK
zVkc9?T=n|PIo~<wJLg{8L_J?=wVD}Kh?c9aozEndlcyGxo=u9<v(!ri)T`-EEs@L3
z5-!0N_s;9#9f}Cc?UC;OPWB_edW+oAi6T$HZWSGU8TbrQ%+zbPOBBBc`}k?M2Hf);
z@Y6N~0;>X-eVh__(Z?q}P9Z-Dj?gOW6|D%o20XmjW-qs4UjrD(li^iv8@eK9k+ZFm
zVRFymFOPAzG5-%Pn|1W;U4vNroTa&AxDScmEA~{ri9gr1^c?U@uwSpaNnw8l_>cP1
zd;)kMQS_;jeRSUEM_*s96y65j1$)tOrwdK{YIQMt92l|D^(E_=$Rjw{b!QT@q!)ni
zR`|5oW9X5n$Wv+HVc@|^eX5yXnsHX<gx$-tTA9oOBadXir_JPm2Y^4ct-PoO&C)tI
zGolvqOIK@duBk!Vu9{g<3;i;gJ6?~-DQ&xz!jvD&4!U-s8Os(*#?k2}f30SEXA#=i
z1-qUX+K`{!((H5w7<t$~ygD!D1{~X6)KX%$qrgY#L_{M_7A<1csY*MfP@XcB#Jxr~
zJS8&7goVS)VKE|4(h_Xlc{z{c$ApZs7riZ_QKdV_uW-M~u~<J-*#Z0?VzcZp8)p-w
zus7J7><CN2I>8PF3UX~a6)MwxDE0HaPjyrlI!;jX{6Kvuh*8ej?;85ekN$?5uuCiS
zBTvvVG+XTxAO{m@bvM#Jr)z6J><&E22D|vq?Y?Vkbo_DijopiF$2PET#<s%v*srlI
z{B2SKJ79W>mZ8e<cESmGBON_l0n;T7>u=y$(ArYkv7@Ex`GL?QCc!_*KFrd&;n1r7
zqW-CFs9&fT)ZaU5gc&=gBz-D<EBz>aCw(vdOp0__x+47~U6sC(E(JNe@4cTT*n6*E
zVH4eoU1-&7pEV~_PRe`a7v+@vy!^5}8?Y3)UmlaE<h}6h3HHql{T;m+bPBU-O|^S1
z@dOw&4<!bj2G_<^#e}PL7FpY$lcrKO$i~?8Bd2y;oaL5^csibnCrF9!i%-PI;xhub
zp1k;8_$IKX1NHus6EHeD;B72SCCD@4ojP$=Mf3`Eo6yZ&eg@wTqDiZE);7u&SJ|(s
zuPF(9%D6IJ)klXF%`_Fy<tR3HxV^%Qqa?nAB97=m-uu2qcHInZ?ps8M|H3=#R%lzO
z6MgLv^}ib0hVV{&<};#;2lcwW;^(7C<OY#bI<VjS9qCKr-E_Cnc!2j+&nHAXA2%BR
zt~VMxUn2h&(Pi^LSpac(Y#S>R0004`Nkl<ZSP8wA%}N9@4990gP+9MuJP1C97x5i@
zNZ&!c_!tYa>{V|rdQfT;C*i--k7>%Zg`t_W%`ZtanQ`bp93aOLUV4b`e)FiDm&23F
zJp_WgpQ|%>y?NlrL)}RaGBR#H?}oR_S5@`80#5yQ_)zfv@Jw>^8sLJXdnfq&?{4_|
z-ii|(e9H`I!Oh?;nG)Q<1xLl^HCk}G+E@tS7w5O^NQ}F7I)Y+@dylfB%9y7GIy0PX
zuH`@#oE&J<h?de$U>R#<K%*xxjp<u2vR$-Eyp7C9@OhJo><?764x~Dq*`E1;4}qhm
zP%1kdJ3pmjJe`EnNmDKdEcfltAe>EDz5<0$e=`2Lh$9PgvJ)<x(`ABdPp2NAYp;6h
zKVpH;XV{h(*MtY8;u@f|`^fR1o+{wro;@|SH*jdK;OM=QQ(lnv>NL;6^nL`V_vxWE
z9HPe=*Q?|hJZ1=?BFFZbbR}?s;cSAWHZQ>uh;quFNuPrw3}q7_w>bqz7|J<Y<~8kb
z@R=b@WV2z*0c@=Tl-Xj(ycatZ0cD_GbWP?z4i_25Xe2$w00000NkvXXu0mjf{YmZj
literal 0
HcmV?d00001
diff --git a/crawl-ref/source/rltiles/player/hand1/artefact/hellbinder.png b/crawl-ref/source/rltiles/player/hand1/artefact/hellbinder.png
new file mode 100644
index 0000000000000000000000000000000000000000..d64b7ca602f5b85a754727e817003f3a05cc2c54
GIT binary patch
literal 1344
zcmV-G1;6@<P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F8000CeX+uL$Nkc;*
zP;zf(X>4Tx05}naRo`#hR1`jmZ&IWdKOk5~hl<6oRa0BJ8yc;~21%2p?MfD<>DVeH
z<T^KrsT&8|>9(p*dx19w`~g7O0}n_%Aq@s%d)fBDv`JHkDym6Hd+5XuAtvnwRpGmK
zVkc9?T=n|PIo~<wJLg{8L_J?=wVD}Kh?c9aozEndlcyGxo=u9<v(!ri)T`-EEs@L3
z5-!0N_s;9#9f}Cc?UC;OPWB_edW+oAi6T$HZWSGU8TbrQ%+zbPOBBBc`}k?M2Hf);
z@Y6N~0;>X-eVh__(Z?q}P9Z-Dj?gOW6|D%o20XmjW-qs4UjrD(li^iv8@eK9k+ZFm
zVRFymFOPAzG5-%Pn|1W;U4vNroTa&AxDScmEA~{ri9gr1^c?U@uwSpaNnw8l_>cP1
zd;)kMQS_;jeRSUEM_*s96y65j1$)tOrwdK{YIQMt92l|D^(E_=$Rjw{b!QT@q!)ni
zR`|5oW9X5n$Wv+HVc@|^eX5yXnsHX<gx$-tTA9oOBadXir_JPm2Y^4ct-PoO&C)tI
zGolvqOIK@duBk!Vu9{g<3;i;gJ6?~-DQ&xz!jvD&4!U-s8Os(*#?k2}f30SEXA#=i
z1-qUX+K`{!((H5w7<t$~ygD!D1{~X6)KX%$qrgY#L_{M_7A<1csY*MfP@XcB#Jxr~
zJS8&7goVS)VKE|4(h_Xlc{z{c$ApZs7riZ_QKdV_uW-M~u~<J-*#Z0?VzcZp8)p-w
zus7J7><CN2I>8PF3UX~a6)MwxDE0HaPjyrlI!;jX{6Kvuh*8ej?;85ekN$?5uuCiS
zBTvvVG+XTxAO{m@bvM#Jr)z6J><&E22D|vq?Y?Vkbo_DijopiF$2PET#<s%v*srlI
z{B2SKJ79W>mZ8e<cESmGBON_l0n;T7>u=y$(ArYkv7@Ex`GL?QCc!_*KFrd&;n1r7
zqW-CFs9&fT)ZaU5gc&=gBz-D<EBz>aCw(vdOp0__x+47~U6sC(E(JNe@4cTT*n6*E
zVH4eoU1-&7pEV~_PRe`a7v+@vy!^5}8?Y3)UmlaE<h}6h3HHql{T;m+bPBU-O|^S1
z@dOw&4<!bj2G_<^#e}PL7FpY$lcrKO$i~?8Bd2y;oaL5^csibnCrF9!i%-PI;xhub
zp1k;8_$IKX1NHus6EHeD;B72SCCD@4ojP$=Mf3`Eo6yZ&eg@wTqDiZE);7u&SJ|(s
zuPF(9%D6IJ)klXF%`_Fy<tR3HxV^%Qqa?nAB97=m-uu2qcHInZ?ps8M|H3=#R%lzO
z6MgLv^}ib0hVV{&<};#;2lcwW;^(7C<OY#bI<VjS9qCKr-E_Cnc!2j+&nHAXA2%BR
zt~VMxUn2h&(Pi^LSpac(Y#S>R0002jNkl<ZSP5fb7zKkh1YBKR|I@>5OxP>|S$^Z#
zKL&a^0>ce|#M%GLay$PA(HN3c7Qh+;o_cm*YhW~$?L;vSs{>F}(3peO0ssI157w|^
zVgS)Jwx0p3188k2viVpYz{tqB7L*G>G_qn^u(3LT78c<$bJPJiLjaTu=mD_W0?U3d
znjQ`rwPV0SfEk<3E-o%X%F4>ul$4Y%-@AA3IyN=b62qDZsbx4Z<_t~;!0G@PO^i>-
zRf97GK$Q_a08R(c!*Y-vqYfAifzc4ancL{qEdv0Y&MpzbAMu?40000<MNUMnLSTZF
Cd3+QA
literal 0
HcmV?d00001
diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc
index d09647e..39ff108b 100644
--- a/crawl-ref/source/spl-cast.cc
+++ b/crawl-ref/source/spl-cast.cc
@@ -521,6 +521,7 @@ static int _spell_enhancement(unsigned int typeflags)
enhanced -= 2;
enhanced += you.archmagi();
+ enhanced += player_equip_unrand(UNRAND_HELLBINDER);
if (you.species == SP_LAVA_ORC && temperature_effect(LORC_LAVA_BOOST)
&& (typeflags & SPTYP_FIRE) && (typeflags & SPTYP_EARTH))
@@ -611,7 +612,62 @@ void do_cast_spell_cmd(bool force)
flush_input_buffer(FLUSH_ON_FAILURE);
}
-// Returns false if spell failed, and true otherwise.
+/**
+ * Check if it's safe to cast this spell (for hp reasons).
+ *
+ * Only comes up if the player has a corrupted magic effect; currently only
+ * from the quarterstaff of the Hellbinder.
+ *
+ * @param spell The type of spell being cast.
+ * @return Whether the player is OK to cast the spell for HP reasons.
+ */
+bool _enough_hp_for_spell(spell_type spell)
+{
+ int hp_cost = you.spell_hp_cost() * spell_mana(spell);
+ if (!hp_cost)
+ return true;
+
+ if (spell == SPELL_PAIN && you.species != SP_DEEP_DWARF)
+ hp_cost += 1;
+
+ if (enough_hp(hp_cost, true) || you.duration[DUR_DEATHS_DOOR])
+ return true;
+
+ int miscast_chance = spell_fail(spell);
+
+ if (!miscast_chance && (spell == SPELL_DEATHS_DOOR
+ || spell == SPELL_BORGNJORS_REVIVIFICATION))
+ return true;
+
+ if (you.species == SP_DEEP_DWARF)
+ {
+ if (hp_cost == 1)
+ return true;
+
+ return yesno("Casting that spell could kill you! Are you sure?",
+ false, 'n');
+ }
+
+ if (miscast_chance != 100 && (spell == SPELL_DEATHS_DOOR
+ || spell == SPELL_BORGNJORS_REVIVIFICATION
+ || spell == SPELL_VAMPIRIC_DRAINING))
+ return yesno("Casting that spell could kill you! Are you sure?",
+ false, 'n');
+
+ mpr("Casting that spell would kill you!");
+ return false;
+}
+
+
+/**
+ * Cast a spell.
+ *
+ * Handles general preconditions & costs.
+ *
+ * @param check_range If true, abort if no targets are in range. (z vs Z)
+ * @param spell The type of spell to be cast.
+ * @return Whether the spell was successfully cast.
+ **/
bool cast_a_spell(bool check_range, spell_type spell)
{
if (!_can_cast())
@@ -720,13 +776,20 @@ bool cast_a_spell(bool check_range, spell_type spell)
return false;
}
- if (!enough_mp(spell_mana(spell), true))
+ const int cost = spell_mana(spell);
+ if (!enough_mp(cost, true))
{
mpr("You don't have enough magic to cast that spell.");
crawl_state.zero_turns_taken();
return false;
}
+ if (!_enough_hp_for_spell(spell))
+ {
+ crawl_state.zero_turns_taken();
+ return false;
+ }
+
if (check_range && spell_no_hostile_in_range(spell))
{
// Abort if there are no hostiles within range, but flash the range
@@ -778,8 +841,8 @@ bool cast_a_spell(bool check_range, spell_type spell)
const bool staff_energy = player_energy();
you.last_cast_spell = spell;
// Silently take MP before the spell.
- const int cost = spell_mana(spell);
dec_mp(cost, true);
+
const spret_type cast_result = your_spells(spell, 0, true, check_range);
if (cast_result == SPRET_ABORT)
{
@@ -1161,12 +1224,37 @@ static targetter* _spell_targetter(spell_type spell, int pow, int range)
}
}
-// Returns SPRET_SUCCESS if spell is successfully cast for purposes of
-// exercising, SPRET_FAIL otherwise, or SPRET_ABORT if the player cancelled
-// the casting.
-// Not all of these are actually real spells; invocations, decks, rods or misc.
-// effects might also land us here.
-// Others are currently unused or unimplemented.
+/**
+ * Handles damage from corrupted magic effects.
+ *
+ * Currently only from the quarterstaff of the Hellbinder.
+ *
+ * @param spell The type of spell that was just cast.
+ **/
+static void _spellcasting_corruption(spell_type spell)
+{
+ int hp_cost = you.spell_hp_cost() * spell_mana(spell);
+ const char * source = NULL;
+ if (player_equip_unrand(UNRAND_HELLBINDER))
+ source = "the quarterstaff of the Hellbinder";
+ ouch(hp_cost, NON_MONSTER, KILLED_BY_CORRUPTED_MAGIC, source);
+}
+
+/**
+ * Targets and fires player-cast spells & spell-like effects.
+ *
+ * Not all of these are actually real spells; invocations, decks, rods or misc.
+ * effects might also land us here.
+ * Others are currently unused or unimplemented.
+ *
+ * @param spell The type of spell being cast.
+ * @param powc Spellpower.
+ * @param allow_fail Whether spell-fail chance applies.
+ * @param check_range ...I'm not sure this actually does anything
+ * @return SPRET_SUCCESS if spell is successfully cast for purposes of
+ * exercising, SPRET_FAIL otherwise, or SPRET_ABORT if the player cancelled
+ * the casting.
+ **/
spret_type your_spells(spell_type spell, int powc,
bool allow_fail, bool check_range)
{
@@ -1343,8 +1431,14 @@ spret_type your_spells(spell_type spell, int powc,
aim_battlesphere(&you, spell, powc, beam);
const bool old_target = actor_at(beam.target);
+
+ spret_type cast_result = _do_cast(spell, powc, spd, beam, god,
+ potion, check_range, fail);
- switch (_do_cast(spell, powc, spd, beam, god, potion, check_range, fail))
+ if (cast_result != SPRET_ABORT && you.spell_hp_cost() && allow_fail)
+ _spellcasting_corruption(spell);
+
+ switch (cast_result)
{
case SPRET_SUCCESS:
{
@@ -1427,7 +1521,14 @@ spret_type your_spells(spell_type spell, int powc,
return SPRET_SUCCESS;
}
-// Special-cased after-effects.
+/**
+ * Handles special-cased aftereffects of spellcasting.
+ *
+ * Currently handles damage from casting Pain, since that occurs before the
+ * spellcast, whether or not it's successful, as long as it's not aborted.
+ *
+ * @param spell The type of spell that was just cast.
+ **/
static void _spell_zap_effect(spell_type spell)
{
// Casting pain costs 1 hp.
diff --git a/crawl-ref/source/spl-util.cc b/crawl-ref/source/spl-util.cc
index 7ae20a3..16dd024 100644
--- a/crawl-ref/source/spl-util.cc
+++ b/crawl-ref/source/spl-util.cc
@@ -1189,15 +1189,22 @@ bool spell_is_useless(spell_type spell, bool transient)
return false;
}
-// This function takes a spell, and determines what color it should be
-// highlighted with. You shouldn't have to touch this unless you want
-// to add new highlighting options.
+/**
+ * Determines what color a spell should be highlighted with.
+ *
+ * @param spell The type of spell to be colored.
+ * @param default_color Color to be used if the spell is unremarkable.
+ * @param transient If true, check if spell is temporarily useless.
+ * @param rod_spell If the spell being evoked from a rod.
+ * @return The color to highlight the spell.
+ */
int spell_highlight_by_utility(spell_type spell, int default_color,
bool transient, bool rod_spell)
{
// If your god hates the spell, that
// overrides all other concerns
- if (god_hates_spell(spell, you.religion, rod_spell))
+ if (god_hates_spell(spell, you.religion, rod_spell)
+ || is_good_god(you.religion) && you.spellcasting_unholy())
return COL_FORBIDDEN;
if (_spell_is_empowered(spell) && !rod_spell)
--
1.8.5.2 (Apple Git-48)
0001-Add-the-Hellbinder-s-Quarterstaff.patch [^] (19,909 bytes) 2014-05-06 05:08 [Show Content] [Hide Content]From 7cfcc7825b963f6f15f5ec22719c603791966679 Mon Sep 17 00:00:00 2001
From: Nicholas Feinberg <pleasingfung@gmail.com>
Date: Fri, 11 Apr 2014 08:29:44 -0700
Subject: [PATCH] Add the Hellbinder's Quarterstaff
Adds the quarterstaff of the Hellbinder, a powerful
spell-enhancing unrand that costs hp with every spell cast.
---
crawl-ref/source/art-data.txt | 10 ++
crawl-ref/source/art-func.h | 17 +++
crawl-ref/source/dat/descript/unrand.txt | 8 ++
crawl-ref/source/hiscores.cc | 20 ++++
crawl-ref/source/ouch.h | 1 +
crawl-ref/source/player.cc | 29 +++++
crawl-ref/source/player.h | 3 +
crawl-ref/source/rltiles/dc-player.txt | 1 +
.../item/weapon/artefact/spwpn_hellbinder.png | Bin 0 -> 1549 bytes
.../rltiles/player/hand1/artefact/hellbinder.png | Bin 0 -> 1344 bytes
crawl-ref/source/spl-cast.cc | 125 +++++++++++++++++++--
crawl-ref/source/spl-util.cc | 15 ++-
12 files changed, 213 insertions(+), 16 deletions(-)
create mode 100644 crawl-ref/source/rltiles/item/weapon/artefact/spwpn_hellbinder.png
create mode 100644 crawl-ref/source/rltiles/player/hand1/artefact/hellbinder.png
diff --git a/crawl-ref/source/art-data.txt b/crawl-ref/source/art-data.txt
index b63831a..ce210f4 100644
--- a/crawl-ref/source/art-data.txt
+++ b/crawl-ref/source/art-data.txt
@@ -1149,6 +1149,16 @@ PLUS: +7/+7
BRAND: SPWPN_FLAMING
FIRE: 2
+NAME: quarterstaff of the Hellbinder
+OBJ: OBJ_WEAPONS/WPN_QUARTERSTAFF
+PLUS: +6/+6
+COLOUR: ETC_UNHOLY
+TILE: spwpn_hellbinder
+TILE_EQ: hellbinder
+MP: 6
+INT: 6
+BRAND: SPWPN_VAMPIRICISM
+
# This is the first of two amulets used to test suppression aura.
# Together, they confer every randart effect except for a few that are
# determined explicitly by checking whether a certain amulet is worn
diff --git a/crawl-ref/source/art-func.h b/crawl-ref/source/art-func.h
index a636f31..e34ddb1 100644
--- a/crawl-ref/source/art-func.h
+++ b/crawl-ref/source/art-func.h
@@ -1085,3 +1085,20 @@ static void _FIRESTARTER_melee_effects(item_def* weapon, actor* attacker,
}
}
}
+
+///////////////////////////////////////////////////
+
+static void _HELLBINDER_equip(item_def *item, bool *show_msgs, bool unmeld)
+{
+ if (you.max_magic_points)
+ _equip_mpr(show_msgs, "You feel a darkness envelop your magic.");
+}
+
+static void _HELLBINDER_unequip(item_def *item, bool *show_msgs)
+{
+ if (you.max_magic_points)
+ {
+ _equip_mpr(show_msgs,
+ "The darkness slowly releases its grasp on your magic.");
+ }
+}
diff --git a/crawl-ref/source/dat/descript/unrand.txt b/crawl-ref/source/dat/descript/unrand.txt
index a909b28..f812c9a 100644
--- a/crawl-ref/source/dat/descript/unrand.txt
+++ b/crawl-ref/source/dat/descript/unrand.txt
@@ -567,6 +567,14 @@ great mace "Firestarter"
Alongside its obvious effects, this weapon protects its owner's inventory from
fire, and fills monsters that it hits with an inner flame.
%%%%
+quarterstaff of the Hellbinder
+
+The Hellbinder's staff is actually a mighty demon, tricked and trapped in this
+form long ago. To survive, she now offers tremendous arcane power at a small
+price: a small portion of the caster’s life essence, taken alongside the magic
+used every time its wielder casts a spell. Of course - the demon is more than
+happy to suck the life from others, as well.
+%%%%
milk chocolate
This item is a debugging aid, granting a vast array of mostly beneficial
diff --git a/crawl-ref/source/hiscores.cc b/crawl-ref/source/hiscores.cc
index 9422041..a5b4ea1 100644
--- a/crawl-ref/source/hiscores.cc
+++ b/crawl-ref/source/hiscores.cc
@@ -622,6 +622,7 @@ static const char *kill_method_names[] =
"beogh_smiting", "divine_wrath", "bounce", "reflect", "self_aimed",
"falling_through_gate", "disintegration", "headbutt", "rolling",
"mirror_damage", "spines", "frailty", "barbs", "being_thrown",
+ "corrupted_magic",
};
static const char *_kill_method_name(kill_method_type kmt)
@@ -1981,6 +1982,12 @@ static bool _species_is_undead(int sp)
return sp == SP_MUMMY || sp == SP_GHOUL || sp == SP_VAMPIRE;
}
+/**
+ * Describes the cause of the player's death.
+ *
+ * @param verbosity The verbosity of the description.
+ * @return A description of the cause of death.
+ */
string scorefile_entry::death_description(death_desc_verbosity verbosity) const
{
bool needs_beam_cause_line = false;
@@ -2509,6 +2516,19 @@ string scorefile_entry::death_description(death_desc_verbosity verbosity) const
needs_damage = true;
break;
+ case KILLED_BY_CORRUPTED_MAGIC:
+ if (terse)
+ desc += "corrupted magic";
+ else
+ {
+ desc += "Soul eaten by corrupted magic";
+ if (!auxkilldata.empty())
+ desc += " (" + auxkilldata + ")";
+ }
+ needs_damage = true;
+ break;
+
+
default:
desc += terse? "program bug" : "Nibbled to death by software bugs";
break;
diff --git a/crawl-ref/source/ouch.h b/crawl-ref/source/ouch.h
index 8aeb494..9423b50 100644
--- a/crawl-ref/source/ouch.h
+++ b/crawl-ref/source/ouch.h
@@ -65,6 +65,7 @@ enum kill_method_type
KILLED_BY_FRAILTY,
KILLED_BY_BARBS,
KILLED_BY_BEING_THROWN,
+ KILLED_BY_CORRUPTED_MAGIC,
NUM_KILLBY
};
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index a214d7f..123358b 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -7191,6 +7191,35 @@ bool player::tengu_flight() const
return species == SP_TENGU && flight_mode();
}
+/**
+ * Returns the HP cost (per MP) of casting a spell.
+ *
+ * Checks to see if the player is wielding the quarterstaff of the Hellbinder.
+ *
+ * @return The HP cost (per MP) of casting a spell.
+ **/
+int player::spell_hp_cost() const
+{
+ int cost = 0;
+
+ if (player_equip_unrand(UNRAND_HELLBINDER))
+ cost += 1;
+
+ return cost;
+}
+
+/**
+ * Returns true if player spellcasting is considered unholy.
+ *
+ * Checks to see if the player is wielding the quarterstaff of the Hellbinder.
+ *
+ * @return Whether player spellcasting is an unholy act.
+ */
+bool player::spellcasting_unholy() const
+{
+ return player_equip_unrand(UNRAND_HELLBINDER);
+}
+
bool player::nightvision() const
{
return is_undead
diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h
index 301a7ec..d5aaac0 100644
--- a/crawl-ref/source/player.h
+++ b/crawl-ref/source/player.h
@@ -444,6 +444,9 @@ public:
bool tengu_flight() const;
+ int spell_hp_cost() const;
+ bool spellcasting_unholy() const;
+
// Dealing with beholders. Implemented in behold.cc.
void add_beholder(const monster* mon, bool axe = false);
bool beheld() const;
diff --git a/crawl-ref/source/rltiles/dc-player.txt b/crawl-ref/source/rltiles/dc-player.txt
index 9f319e5..def9d7c 100644
--- a/crawl-ref/source/rltiles/dc-player.txt
+++ b/crawl-ref/source/rltiles/dc-player.txt
@@ -508,6 +508,7 @@ shillelagh SHILLELAGH
dark_maul DARK_MAUL
spellbinder SPELLBINDER
firestarter FIRESTARTER
+hellbinder HELLBINDER
## polearms
trident_octopus_king TRIDENT_OCTOPUS_KING
glaive_of_prune GLAIVE_OF_PRUNE
diff --git a/crawl-ref/source/rltiles/item/weapon/artefact/spwpn_hellbinder.png b/crawl-ref/source/rltiles/item/weapon/artefact/spwpn_hellbinder.png
new file mode 100644
index 0000000000000000000000000000000000000000..fe5af2d4736f5580456881f3f26871e998b2fe9b
GIT binary patch
literal 1549
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
literal 0
HcmV?d00001
diff --git a/crawl-ref/source/rltiles/player/hand1/artefact/hellbinder.png b/crawl-ref/source/rltiles/player/hand1/artefact/hellbinder.png
new file mode 100644
index 0000000000000000000000000000000000000000..d64b7ca602f5b85a754727e817003f3a05cc2c54
GIT binary patch
literal 1344
zcmV-G1;6@<P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F8000CeX+uL$Nkc;*
zP;zf(X>4Tx05}naRo`#hR1`jmZ&IWdKOk5~hl<6oRa0BJ8yc;~21%2p?MfD<>DVeH
z<T^KrsT&8|>9(p*dx19w`~g7O0}n_%Aq@s%d)fBDv`JHkDym6Hd+5XuAtvnwRpGmK
zVkc9?T=n|PIo~<wJLg{8L_J?=wVD}Kh?c9aozEndlcyGxo=u9<v(!ri)T`-EEs@L3
z5-!0N_s;9#9f}Cc?UC;OPWB_edW+oAi6T$HZWSGU8TbrQ%+zbPOBBBc`}k?M2Hf);
z@Y6N~0;>X-eVh__(Z?q}P9Z-Dj?gOW6|D%o20XmjW-qs4UjrD(li^iv8@eK9k+ZFm
zVRFymFOPAzG5-%Pn|1W;U4vNroTa&AxDScmEA~{ri9gr1^c?U@uwSpaNnw8l_>cP1
zd;)kMQS_;jeRSUEM_*s96y65j1$)tOrwdK{YIQMt92l|D^(E_=$Rjw{b!QT@q!)ni
zR`|5oW9X5n$Wv+HVc@|^eX5yXnsHX<gx$-tTA9oOBadXir_JPm2Y^4ct-PoO&C)tI
zGolvqOIK@duBk!Vu9{g<3;i;gJ6?~-DQ&xz!jvD&4!U-s8Os(*#?k2}f30SEXA#=i
z1-qUX+K`{!((H5w7<t$~ygD!D1{~X6)KX%$qrgY#L_{M_7A<1csY*MfP@XcB#Jxr~
zJS8&7goVS)VKE|4(h_Xlc{z{c$ApZs7riZ_QKdV_uW-M~u~<J-*#Z0?VzcZp8)p-w
zus7J7><CN2I>8PF3UX~a6)MwxDE0HaPjyrlI!;jX{6Kvuh*8ej?;85ekN$?5uuCiS
zBTvvVG+XTxAO{m@bvM#Jr)z6J><&E22D|vq?Y?Vkbo_DijopiF$2PET#<s%v*srlI
z{B2SKJ79W>mZ8e<cESmGBON_l0n;T7>u=y$(ArYkv7@Ex`GL?QCc!_*KFrd&;n1r7
zqW-CFs9&fT)ZaU5gc&=gBz-D<EBz>aCw(vdOp0__x+47~U6sC(E(JNe@4cTT*n6*E
zVH4eoU1-&7pEV~_PRe`a7v+@vy!^5}8?Y3)UmlaE<h}6h3HHql{T;m+bPBU-O|^S1
z@dOw&4<!bj2G_<^#e}PL7FpY$lcrKO$i~?8Bd2y;oaL5^csibnCrF9!i%-PI;xhub
zp1k;8_$IKX1NHus6EHeD;B72SCCD@4ojP$=Mf3`Eo6yZ&eg@wTqDiZE);7u&SJ|(s
zuPF(9%D6IJ)klXF%`_Fy<tR3HxV^%Qqa?nAB97=m-uu2qcHInZ?ps8M|H3=#R%lzO
z6MgLv^}ib0hVV{&<};#;2lcwW;^(7C<OY#bI<VjS9qCKr-E_Cnc!2j+&nHAXA2%BR
zt~VMxUn2h&(Pi^LSpac(Y#S>R0002jNkl<ZSP5fb7zKkh1YBKR|I@>5OxP>|S$^Z#
zKL&a^0>ce|#M%GLay$PA(HN3c7Qh+;o_cm*YhW~$?L;vSs{>F}(3peO0ssI157w|^
zVgS)Jwx0p3188k2viVpYz{tqB7L*G>G_qn^u(3LT78c<$bJPJiLjaTu=mD_W0?U3d
znjQ`rwPV0SfEk<3E-o%X%F4>ul$4Y%-@AA3IyN=b62qDZsbx4Z<_t~;!0G@PO^i>-
zRf97GK$Q_a08R(c!*Y-vqYfAifzc4ancL{qEdv0Y&MpzbAMu?40000<MNUMnLSTZF
Cd3+QA
literal 0
HcmV?d00001
diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc
index 03812b0..620e059 100644
--- a/crawl-ref/source/spl-cast.cc
+++ b/crawl-ref/source/spl-cast.cc
@@ -521,6 +521,7 @@ static int _spell_enhancement(unsigned int typeflags)
enhanced -= 2;
enhanced += you.archmagi();
+ enhanced += player_equip_unrand(UNRAND_HELLBINDER);
if (you.species == SP_LAVA_ORC && temperature_effect(LORC_LAVA_BOOST)
&& (typeflags & SPTYP_FIRE) && (typeflags & SPTYP_EARTH))
@@ -611,7 +612,62 @@ void do_cast_spell_cmd(bool force)
flush_input_buffer(FLUSH_ON_FAILURE);
}
-// Returns false if spell failed, and true otherwise.
+/**
+ * Check if it's safe to cast this spell (for hp reasons).
+ *
+ * Only comes up if the player has a corrupted magic effect; currently only
+ * from the quarterstaff of the Hellbinder.
+ *
+ * @param spell The type of spell being cast.
+ * @return Whether the player is OK to cast the spell for HP reasons.
+ */
+bool _enough_hp_for_spell(spell_type spell)
+{
+ int hp_cost = you.spell_hp_cost() * spell_mana(spell);
+ if (!hp_cost)
+ return true;
+
+ if (spell == SPELL_PAIN && you.species != SP_DEEP_DWARF)
+ hp_cost += 1;
+
+ if (enough_hp(hp_cost, true) || you.duration[DUR_DEATHS_DOOR])
+ return true;
+
+ int miscast_chance = spell_fail(spell);
+
+ if (!miscast_chance && (spell == SPELL_DEATHS_DOOR
+ || spell == SPELL_BORGNJORS_REVIVIFICATION))
+ return true;
+
+ if (you.species == SP_DEEP_DWARF)
+ {
+ if (hp_cost == 1)
+ return true;
+
+ return yesno("Casting that spell could kill you! Are you sure?",
+ false, 'n');
+ }
+
+ if (miscast_chance != 100 && (spell == SPELL_DEATHS_DOOR
+ || spell == SPELL_BORGNJORS_REVIVIFICATION
+ || spell == SPELL_VAMPIRIC_DRAINING))
+ return yesno("Casting that spell could kill you! Are you sure?",
+ false, 'n');
+
+ mpr("Casting that spell would kill you!");
+ return false;
+}
+
+
+/**
+ * Cast a spell.
+ *
+ * Handles general preconditions & costs.
+ *
+ * @param check_range If true, abort if no targets are in range. (z vs Z)
+ * @param spell The type of spell to be cast.
+ * @return Whether the spell was successfully cast.
+ **/
bool cast_a_spell(bool check_range, spell_type spell)
{
if (!_can_cast())
@@ -720,13 +776,20 @@ bool cast_a_spell(bool check_range, spell_type spell)
return false;
}
- if (!enough_mp(spell_mana(spell), true))
+ const int cost = spell_mana(spell);
+ if (!enough_mp(cost, true))
{
mpr("You don't have enough magic to cast that spell.");
crawl_state.zero_turns_taken();
return false;
}
+ if (!_enough_hp_for_spell(spell))
+ {
+ crawl_state.zero_turns_taken();
+ return false;
+ }
+
if (check_range && spell_no_hostile_in_range(spell))
{
// Abort if there are no hostiles within range, but flash the range
@@ -778,8 +841,8 @@ bool cast_a_spell(bool check_range, spell_type spell)
const bool staff_energy = player_energy();
you.last_cast_spell = spell;
// Silently take MP before the spell.
- const int cost = spell_mana(spell);
dec_mp(cost, true);
+
const spret_type cast_result = your_spells(spell, 0, true, check_range);
if (cast_result == SPRET_ABORT)
{
@@ -844,7 +907,7 @@ static void _spellcasting_god_conduct(spell_type spell)
const int conduct_level = 10 + spell_difficulty(spell);
- if (is_unholy_spell(spell))
+ if (is_unholy_spell(spell) || you.spellcasting_unholy())
did_god_conduct(DID_UNHOLY, conduct_level);
if (is_unclean_spell(spell))
@@ -1182,12 +1245,37 @@ static targetter* _spell_targetter(spell_type spell, int pow, int range)
}
}
-// Returns SPRET_SUCCESS if spell is successfully cast for purposes of
-// exercising, SPRET_FAIL otherwise, or SPRET_ABORT if the player cancelled
-// the casting.
-// Not all of these are actually real spells; invocations, decks, rods or misc.
-// effects might also land us here.
-// Others are currently unused or unimplemented.
+/**
+ * Handles damage from corrupted magic effects.
+ *
+ * Currently only from the quarterstaff of the Hellbinder.
+ *
+ * @param spell The type of spell that was just cast.
+ **/
+static void _spellcasting_corruption(spell_type spell)
+{
+ int hp_cost = you.spell_hp_cost() * spell_mana(spell);
+ const char * source = NULL;
+ if (player_equip_unrand(UNRAND_HELLBINDER))
+ source = "the quarterstaff of the Hellbinder";
+ ouch(hp_cost, NON_MONSTER, KILLED_BY_CORRUPTED_MAGIC, source);
+}
+
+/**
+ * Targets and fires player-cast spells & spell-like effects.
+ *
+ * Not all of these are actually real spells; invocations, decks, rods or misc.
+ * effects might also land us here.
+ * Others are currently unused or unimplemented.
+ *
+ * @param spell The type of spell being cast.
+ * @param powc Spellpower.
+ * @param allow_fail Whether spell-fail chance applies.
+ * @param check_range ...I'm not sure this actually does anything
+ * @return SPRET_SUCCESS if spell is successfully cast for purposes of
+ * exercising, SPRET_FAIL otherwise, or SPRET_ABORT if the player cancelled
+ * the casting.
+ **/
spret_type your_spells(spell_type spell, int powc,
bool allow_fail, bool check_range)
{
@@ -1364,8 +1452,14 @@ spret_type your_spells(spell_type spell, int powc,
aim_battlesphere(&you, spell, powc, beam);
const bool old_target = actor_at(beam.target);
+
+ spret_type cast_result = _do_cast(spell, powc, spd, beam, god,
+ potion, check_range, fail);
- switch (_do_cast(spell, powc, spd, beam, god, potion, check_range, fail))
+ if (cast_result != SPRET_ABORT && you.spell_hp_cost() && allow_fail)
+ _spellcasting_corruption(spell);
+
+ switch (cast_result)
{
case SPRET_SUCCESS:
{
@@ -1448,7 +1542,14 @@ spret_type your_spells(spell_type spell, int powc,
return SPRET_SUCCESS;
}
-// Special-cased after-effects.
+/**
+ * Handles special-cased aftereffects of spellcasting.
+ *
+ * Currently handles damage from casting Pain, since that occurs before the
+ * spellcast, whether or not it's successful, as long as it's not aborted.
+ *
+ * @param spell The type of spell that was just cast.
+ **/
static void _spell_zap_effect(spell_type spell)
{
// Casting pain costs 1 hp.
diff --git a/crawl-ref/source/spl-util.cc b/crawl-ref/source/spl-util.cc
index 7ae20a3..16dd024 100644
--- a/crawl-ref/source/spl-util.cc
+++ b/crawl-ref/source/spl-util.cc
@@ -1189,15 +1189,22 @@ bool spell_is_useless(spell_type spell, bool transient)
return false;
}
-// This function takes a spell, and determines what color it should be
-// highlighted with. You shouldn't have to touch this unless you want
-// to add new highlighting options.
+/**
+ * Determines what color a spell should be highlighted with.
+ *
+ * @param spell The type of spell to be colored.
+ * @param default_color Color to be used if the spell is unremarkable.
+ * @param transient If true, check if spell is temporarily useless.
+ * @param rod_spell If the spell being evoked from a rod.
+ * @return The color to highlight the spell.
+ */
int spell_highlight_by_utility(spell_type spell, int default_color,
bool transient, bool rod_spell)
{
// If your god hates the spell, that
// overrides all other concerns
- if (god_hates_spell(spell, you.religion, rod_spell))
+ if (god_hates_spell(spell, you.religion, rod_spell)
+ || is_good_god(you.religion) && you.spellcasting_unholy())
return COL_FORBIDDEN;
if (_spell_is_empowered(spell) && !rod_spell)
--
1.8.5.2 (Apple Git-48)
|