summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/spells2.cc
diff options
context:
space:
mode:
authorJude Brown <bookofjude@users.sourceforge.net>2010-01-01 21:46:44 +1000
committerJude Brown <bookofjude@users.sourceforge.net>2010-01-01 22:21:27 +1000
commit7e0fff01081a22364aab5a44a9b3a5040018e17a (patch)
tree62ad943e0e31c9d9c758e235b0b63e2bcda599e3 /crawl-ref/source/spells2.cc
parenta60ff1ae3bac49a203f2825ae3e00effc31796ad (diff)
downloadcrawl-ref-7e0fff01081a22364aab5a44a9b3a5040018e17a.tar.gz
crawl-ref-7e0fff01081a22364aab5a44a9b3a5040018e17a.zip
Continuation of the range combat overhaul: branding spells.
As outlined in dpeg's ranged combat overhaul, branding spells should no longer be permanant, nor apply directly to the ammunition. This commit removes all previous "<X> Ammunition" spells, including the original "Poison Ammunition" spell. Instead, branding ammunition is now done via the launcher and the currently existent weapon branding spells. Currently, those that can be applied to a launcher are: Fire Brand, Freezing Aura and Poison Weapon. There is the capacity of Excruciating Wounds to also be applied, but this would require the addition of the Pain ego for missiles, of which the mechanics would need to be decided upon first. Like temporary brands on weapons currently, these brands on launchers are permanantly affixable by using a scroll of vorpalise weapon. This commit also overhauls the Arcane Marksman class. It began by removing the non-existent ammunition spells; this left Devastating Missiles with two spells: haste and deflect missiles. On reflection, I decided to delete the book instead. The Book of Elemental Missiles was easily adjusted by replacing the three branding spells by the existent (and aforementioned) branding spells. As there are no (according to the 0.6 ranged combat overhaul spec) spells intended for use with translocation effects on missiles, this left The Book of Warped Missiles rather empty. Attempts were made (with discussion with Eronarn on IRC) to work out something else to fill up the Book of Warped Missiles with, but I made the decision to get rid it instead, as the only good suggestions basically made it the Book of Spatial Translocations, and in that case, the player may as well select the warper class. We also discussed whether or not to remove Poison Weapon from the Elemental starting book; I decided it was best to leave it now, but increase its level from 2 to 3, to give the book more of a range of levels (starting a Spriggan Arcane Marksman had all the spells listed as "excellent" or "very good"; more on this shortly). I also decided that Repel Missiles is over-used in this context, and upon Eronarn's suggestion and sorear's agreement, have replaced it with Cause Fear. I think this will provide for interesting game play, and that the level of the spell is suitably high enough for it to not be abused. I also made the executive decision that "Elemental Missiles" was no longer an appropriate title, as it didn't contain any ammunition-specific spells any longer, and have renamed the book to the "Book of Brands". It is now: Book of Brands Level 1, Corona Level 2, Swiftness Level 2, Fire Brand Level 2, Freezing Aura Level 3, Poison Weapon Level 5, Cause Fear As the Arcane Marksmen class is now launcher-specific, rather than ammunition-specific, I have adjusted it to no longer give Hill Orcs, Sludge Elves and Merfolk javelins and throwing nets (they get bows like everyone else), and made the decision to ban Trolls and Ogres from the class altogether. The reasoning here is that they have bad launcher aptitudes, and as they are described as "marksmen", it makes no sense to give them a book full of launcher-specific spells and some large rocks and throwing nets. This change could, of course, be reverted, and they could simply be given bows, crossbows or slings as relevant, in line with all other races being given launchers and ammunition. I have adjusted the starting skill levels for enchantments, spell- casting and dodging to that of Crusaders. I have also removed Poison Ammunition from the Book of Envenomations, and replaced it with Poison Weapon instead. Finally, I have increased TAG_MAJOR_VERSION to 14.
Diffstat (limited to 'crawl-ref/source/spells2.cc')
-rw-r--r--crawl-ref/source/spells2.cc215
1 files changed, 84 insertions, 131 deletions
diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc
index d765d4db5f..c83b90db83 100644
--- a/crawl-ref/source/spells2.cc
+++ b/crawl-ref/source/spells2.cc
@@ -33,6 +33,7 @@
#include "itemname.h"
#include "items.h"
#include "it_use2.h"
+#include "makeitem.h"
#include "message.h"
#include "misc.h"
#include "mon-behv.h"
@@ -234,6 +235,54 @@ void corpse_rot()
// Should make zombies decay into skeletons?
}
+// We need to know what brands equate with what missile brands to know if
+// we should disallow temporary branding or not.
+special_missile_type _convert_to_missile(brand_type which_brand)
+{
+ switch (which_brand)
+ {
+ case SPWPN_NORMAL: return SPMSL_NORMAL;
+ case SPWPN_FLAME: // deliberate fall through
+ case SPWPN_FLAMING: return SPMSL_FLAME;
+ case SPWPN_FROST: // deliberate fall through
+ case SPWPN_FREEZING: return SPMSL_FROST;
+ case SPWPN_VENOM: return SPMSL_POISONED;
+ case SPWPN_CHAOS: return SPMSL_CHAOS;
+ case SPWPN_RETURNING: return SPMSL_RETURNING;
+ default: return SPMSL_NORMAL; // there are no equivalents for the rest
+ // of the ammo brands.
+ }
+}
+
+// Some launchers need to convert different brands.
+brand_type _convert_to_launcher(brand_type which_brand)
+{
+ switch (which_brand)
+ {
+ case SPWPN_FREEZING: return SPWPN_FROST; case SPWPN_FLAMING: return SPWPN_FLAME;
+ default: return (which_brand);
+ }
+}
+
+bool _ok_for_launchers(brand_type which_brand)
+{
+ switch (which_brand)
+ {
+ case SPWPN_NORMAL:
+ case SPWPN_FREEZING:
+ case SPWPN_FROST:
+ case SPWPN_FLAMING:
+ case SPWPN_FLAME:
+ case SPWPN_VENOM:
+ //case SPWPN_PAIN: -- no pain missile type yat
+ case SPWPN_RETURNING:
+ case SPWPN_CHAOS:
+ return (true);
+ default:
+ return (false);
+ }
+}
+
bool brand_weapon(brand_type which_brand, int power)
{
if (!you.weapon())
@@ -242,8 +291,12 @@ bool brand_weapon(brand_type which_brand, int power)
const bool temp_brand = you.duration[DUR_WEAPON_BRAND];
item_def& weapon = *you.weapon();
- // Can't brand non-weapons.
- if (weapon.base_type != OBJ_WEAPONS || is_range_weapon(weapon))
+ // Can't brand non-weapons, but can brand some launchers (see later).
+ if (weapon.base_type != OBJ_WEAPONS)
+ return (false);
+
+ // But not blowguns.
+ if (weapon.sub_type == WPN_BLOWGUN)
return (false);
// Can't brand artefacts.
@@ -258,6 +311,29 @@ bool brand_weapon(brand_type which_brand, int power)
if (temp_brand && (get_weapon_brand(weapon) != which_brand))
return (false);
+ // Can only brand launchers with sensical brands
+ if (is_range_weapon(weapon))
+ {
+ // If the new missile type wouldn't match the launcher, say no
+ missile_type missile = fires_ammo_type(weapon);
+
+ // XXX: To deal with the fact that is_missile_brand_ok will be unhappy
+ // if we attempt to brand stones, tell it we're using sling bullets instead.
+ if (weapon.sub_type == WPN_SLING)
+ missile = MI_SLING_BULLET;
+
+ if (!is_missile_brand_ok(missile, _convert_to_missile(which_brand)))
+ return (false);
+
+ // If the brand isn't appropriate for that launcher, also say no.
+ if (!_ok_for_launchers(which_brand))
+ return (false);
+
+ // Otherwise, convert to the correct brand type, most specifically (but
+ // not necessarily only) flaming -> flame, freezing -> frost.
+ which_brand = _convert_to_launcher(which_brand);
+ }
+
std::string msg = weapon.name(DESC_CAP_YOUR);
const int wpn_type = get_vorpal_type(weapon);
@@ -265,11 +341,17 @@ bool brand_weapon(brand_type which_brand, int power)
int duration_affected = 0;
switch (which_brand)
{
+ case SPWPN_FLAME:
case SPWPN_FLAMING:
msg += " bursts into flame!";
duration_affected = 7;
break;
+ case SPWPN_FROST:
+ msg += " frosts over!";
+ duration_affected = 7;
+ break;
+
case SPWPN_FREEZING:
msg += " glows blue.";
duration_affected = 7;
@@ -360,135 +442,6 @@ bool brand_weapon(brand_type which_brand, int power)
return (true);
}
-bool brand_ammo(special_missile_type which_type)
-{
- const int ammo = you.equip[EQ_WEAPON];
-
- if (ammo == -1
- || you.inv[ammo].base_type != OBJ_MISSILES
- || get_ammo_brand(you.inv[ammo]) != SPMSL_NORMAL
- || you.inv[ammo].sub_type == MI_THROWING_NET)
- {
- return (false);
- }
-
- bool retval = false;
- preserve_quiver_slots q;
- const char *old_desc = you.inv[ammo].name(DESC_CAP_YOUR).c_str();
-
- switch (which_type)
- {
- case SPMSL_POISONED:
- if (set_item_ego_type(you.inv[ammo], OBJ_MISSILES, SPMSL_POISONED))
- {
- mprf("%s %s covered in a thin film of poison.", old_desc,
- (you.inv[ammo].quantity == 1) ? "is" : "are");
-
- if (ammo == you.equip[EQ_WEAPON])
- you.wield_change = true;
-
- retval = true;
- }
- break;
-
- case SPMSL_FLAME:
- if (set_item_ego_type(you.inv[ammo], OBJ_MISSILES, SPMSL_FLAME))
- {
- mprf("%s %s warm to the touch.", old_desc,
- (you.inv[ammo].quantity == 1) ? "feels" : "feel");
-
- if (ammo == you.equip[EQ_WEAPON])
- you.wield_change = true;
-
- retval = true;
- }
- break;
-
- case SPMSL_FROST:
- if (set_item_ego_type(you.inv[ammo], OBJ_MISSILES, SPMSL_FROST))
- {
- mprf("%s %s cool to the touch.", old_desc,
- (you.inv[ammo].quantity == 1) ? "feels" : "feel");
-
- if (ammo == you.equip[EQ_WEAPON])
- you.wield_change = true;
-
- retval = true;
- }
- break;
-
- case SPMSL_DISPERSAL:
- if (set_item_ego_type(you.inv[ammo], OBJ_MISSILES, SPMSL_DISPERSAL))
- {
- mprf("%s %s rather jumpy.", old_desc,
- (you.inv[ammo].quantity == 1) ? "seems" : "seem");
-
- if (ammo == you.equip[EQ_WEAPON])
- you.wield_change = true;
-
- retval = true;
- }
- break;
-
- case SPMSL_ELECTRIC:
- if (set_item_ego_type(you.inv[ammo], OBJ_MISSILES, SPMSL_ELECTRIC))
- {
- mprf("%s %s you!", old_desc,
- (you.inv[ammo].quantity == 1) ? "shocks" : "shock");
-
- if (ammo == you.equip[EQ_WEAPON])
- you.wield_change = true;
-
- retval = true;
- }
- break;
-
- case SPMSL_EXPLODING:
- if (set_item_ego_type(you.inv[ammo], OBJ_MISSILES, SPMSL_EXPLODING))
- {
- mprf("%s %s unstable!", old_desc,
- (you.inv[ammo].quantity == 1) ? "seems" : "seem");
-
- if (ammo == you.equip[EQ_WEAPON])
- you.wield_change = true;
-
- retval = true;
- }
- break;
-
- case SPMSL_REAPING:
- if (set_item_ego_type(you.inv[ammo], OBJ_MISSILES, SPMSL_REAPING))
- {
- mprf("%s %s briefly obscured by shadows.", old_desc,
- (you.inv[ammo].quantity == 1) ? "is" : "are");
-
- if (ammo == you.equip[EQ_WEAPON])
- you.wield_change = true;
-
- retval = true;
- }
- break;
-
- case SPMSL_RETURNING:
- if (set_item_ego_type(you.inv[ammo], OBJ_MISSILES, SPMSL_RETURNING))
- {
- mprf("%s %s in your hand.", old_desc,
- (you.inv[ammo].quantity == 1) ? "wiggles" : "wiggle");
-
- if (ammo == you.equip[EQ_WEAPON])
- you.wield_change = true;
-
- retval = true;
- }
- break;
-
- default:
- break;
- }
-
- return (retval);
-}
-
// Restore the stat in which_stat by the amount in stat_gain, displaying
// a message if suppress_msg is false, and doing so in the recovery
// channel if recovery is true. If stat_gain is 0, restore the stat