summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/item_use.cc
diff options
context:
space:
mode:
authorzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2008-12-01 04:00:00 +0000
committerzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2008-12-01 04:00:00 +0000
commit04f5058cac8e12d3b85834bda4589239932f371a (patch)
tree20863dfb1b0a87c9643f0ca98ce2cb43cf195416 /crawl-ref/source/item_use.cc
parent6e3985b473d0b26c028820b3d0a3808d3f3dd7ee (diff)
downloadcrawl-ref-04f5058cac8e12d3b85834bda4589239932f371a.tar.gz
crawl-ref-04f5058cac8e12d3b85834bda4589239932f371a.zip
Add some chaos attacks/weapons. Missiles and launchers of chaos fire a bolt of
a random type (including enchantments, which isn't so good since they don't have a visible beam). Might want to add BEAM_CHAOS and make it a beam of that. Weapons of chaos either does a random brand effect (fire, poison, etc) or a random chaos effect (which includes cloning the attack victim). The AF_CHAOS monster attack flavour either does a random monster flavour or chaos effect (same chaos effects as for weapons). The relative frequency of all the different effects/brands/flavours no doubt needs adjustment. All of this is currently only available via Xom. 10% of all common-type demons sent in by Xom will be chaos spawn (the only kind that use AF_CHAOS, and never randomly generated otherwise). All item gifts from Xom which are generated with a brand will have their brand switched to chaos (this should probably be made to happen less than 100% of the time). And finally one of Xom's bad acts is to upgrade a non-branded weapon of a nearby hostile monster to a chaos brand (this might need to be made less (or more) common). Oh, and if a randart has a brand which would be identified if it were merely an ego weapon, it now identifies the RAP_BRAND property of the randart. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7704 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/item_use.cc')
-rw-r--r--crawl-ref/source/item_use.cc182
1 files changed, 173 insertions, 9 deletions
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index 198fd61ad0..6f300fffd2 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -140,9 +140,8 @@ bool can_wield(item_def *weapon, bool say_reason,
return (false);
}
- int weap_brand = get_weapon_brand(*weapon);
if ((you.is_undead || you.species == SP_DEMONSPAWN)
- && (weap_brand == SPWPN_HOLY_WRATH || is_blessed_blade(*weapon)))
+ && is_holy_item(*weapon))
{
if (say_reason)
{
@@ -634,6 +633,11 @@ void wield_effects(int item_wield_2, bool showMsgs)
mpr("A searing pain shoots up your arm!");
break;
+ case SPWPN_CHAOS:
+ mpr("It is briefly surrounded by a scintillating arua "
+ "of random colours.");
+ break;
+
case SPWPN_SINGING_SWORD:
if (!was_known)
{
@@ -1649,12 +1653,15 @@ int launcher_final_speed(const item_def &launcher, const item_def *shield)
// positive: frost, negative: flame, zero: neither
bool elemental_missile_beam(int launcher_brand, int ammo_brand)
{
+ if (launcher_brand == SPWPN_CHAOS || ammo_brand == SPMSL_CHAOS)
+ return (true);
+
int element = (launcher_brand == SPWPN_FROST
+ ammo_brand == SPMSL_ICE
- launcher_brand == SPWPN_FLAME
- ammo_brand == SPMSL_FLAME);
- return (element);
+ return (element != 0);
}
// XXX This is a bit too generous, as it lets the player determine
@@ -1668,6 +1675,8 @@ static bool determines_ammo_brand(int bow_brand, int ammo_brand)
return (false);
if (bow_brand == SPWPN_VENOM && ammo_brand == SPMSL_POISONED)
return (false);
+ if (bow_brand == SPWPN_CHAOS && ammo_brand == SPMSL_CHAOS)
+ return (false);
return (true);
}
@@ -1739,6 +1748,140 @@ void _merge_ammo_in_inventory(int slot)
}
}
+std::string setup_chaos_ammo(bolt &pbolt, item_def ammo)
+{
+ ASSERT(!is_artefact(ammo));
+
+ const bool poisoned = (get_ammo_brand(ammo) == SPMSL_POISONED);
+
+ // Don't choose BEAM_POISON or BEAM_HEALING if we have poisoned ammo.
+ const int pois_weight = poisoned ? 0 : 10;
+ const int heal_weight = poisoned ? 0 : 10;
+
+ const beam_type flavour = static_cast<beam_type>(
+ random_choose_weighted( pois_weight, BEAM_POISON,
+ heal_weight, BEAM_HEALING,
+
+ 10, BEAM_FIRE,
+ 10, BEAM_COLD,
+ 10, BEAM_ELECTRICITY,
+ 10, BEAM_NEG,
+ 10, BEAM_ACID,
+ 10, BEAM_HELLFIRE,
+ 10, BEAM_NAPALM,
+ 10, BEAM_HELLFROST,
+ 10, BEAM_SLOW,
+ 10, BEAM_HASTE,
+ 10, BEAM_PARALYSIS,
+ 10, BEAM_CONFUSION,
+ 10, BEAM_INVISIBILITY,
+ 10, BEAM_POLYMORPH,
+ 10, BEAM_BANISH,
+ 10, BEAM_DISINTEGRATION,
+ 0 ));
+
+ std::string name;
+ int colour;
+
+ if (poisoned)
+ name = "poison ";
+
+ switch(flavour)
+ {
+ case BEAM_POISON:
+ name += "poison";
+ colour = EC_POISON;
+ break;
+ case BEAM_HEALING:
+ name += "healing";
+ colour = EC_HEAL;
+ break;
+ case BEAM_FIRE:
+ name += "flame";
+ colour = EC_FIRE;
+ break;
+ case BEAM_COLD:
+ name += "frost";
+ colour = EC_ICE;
+ break;
+ case BEAM_ELECTRICITY:
+ name += "lightning";
+ colour = EC_ELECTRICITY;
+ break;
+ case BEAM_NEG:
+ name += "negative energy";
+ colour = EC_NECRO;
+ break;
+ case BEAM_ACID:
+ name += "acid";
+ colour = YELLOW;
+ break;
+ case BEAM_HELLFIRE:
+ name += "hellfire";
+ colour = EC_FIRE;
+ break;
+ case BEAM_NAPALM:
+ name += "sticky fire";
+ colour = EC_FIRE;
+ break;
+ case BEAM_HELLFROST:
+ name += "hellfrost";
+ colour = EC_ICE;
+ break;
+ case BEAM_SLOW:
+ name += "slowing";
+ colour = EC_ENCHANT;
+ break;
+ case BEAM_HASTE:
+ name += "hasting";
+ colour = EC_ENCHANT;
+ break;
+ case BEAM_PARALYSIS:
+ name += "paralysis";
+ colour = EC_ENCHANT;
+ break;
+ case BEAM_CONFUSION:
+ name += "confusion";
+ colour = EC_ENCHANT;
+ break;
+ case BEAM_INVISIBILITY:
+ name += "invisibility";
+ colour = EC_ENCHANT;
+ break;
+ case BEAM_POLYMORPH:
+ name += "polymorphing";
+ colour = EC_MUTAGENIC;
+ break;
+ case BEAM_BANISH:
+ name += "banishment";
+ colour = EC_WARP;
+ break;
+ case BEAM_DISINTEGRATION:
+ name += "disintegration";
+ colour = EC_DEATH;
+ break;
+ default:
+ ASSERT(!"Invalid chaos ammo flavour.");
+ break;
+ }
+
+ pbolt.name = "bolt of ";
+ pbolt.name += name;
+
+ pbolt.flavour = flavour;
+ pbolt.colour = colour;
+ pbolt.type = dchar_glyph(DCHAR_FIRED_BOLT);
+
+ // Get name for a plain arrow/bolt/dart/needle.
+ ammo.special = 0;
+
+ std::string ammo_name = ammo.name(DESC_NOCAP_A);
+ ammo_name += " of ";
+ ammo_name += name;
+
+ return ammo_name;
+}
+
// throw_it - currently handles player throwing only. Monster
// throwing is handled in mstuff2:mons_throw()
// Note: If teleport is true, assume that pbolt is already set up,
@@ -1785,6 +1928,9 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus,
item_def& thrown = you.inv[throw_2];
+ // Did we know the ammo's brand before throwing it?
+ const bool ammon_brand_known = item_type_known(thrown);
+
// Get the ammo/weapon type. Convenience.
const object_class_type wepClass = thrown.base_type;
const int wepType = thrown.sub_type;
@@ -1888,6 +2034,7 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus,
// Now start real firing!
origin_set_unknown(item);
+ std::string ammo_name;
if (is_blood_potion(item) && thrown.quantity > 1)
{
@@ -2389,8 +2536,19 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus,
// and vice versa.
// Note that bow_brand is known since the bow is equipped.
- if ((bow_brand == SPWPN_FLAME || ammo_brand == SPMSL_FLAME)
- && ammo_brand != SPMSL_ICE && bow_brand != SPWPN_FROST)
+
+ // Chaos overides flame and frost/ice.
+ if (bow_brand == SPWPN_CHAOS || ammo_brand == SPMSL_CHAOS)
+ {
+ ammo_name = setup_chaos_ammo(pbolt, item);
+
+ // [dshaligram] Branded arrows are much stronger.
+ dice_mult = (dice_mult * 150) / 100;
+
+ pbolt.effect_known = false;
+ }
+ else if ((bow_brand == SPWPN_FLAME || ammo_brand == SPMSL_FLAME)
+ && ammo_brand != SPMSL_ICE && bow_brand != SPWPN_FROST)
{
// [dshaligram] Branded arrows are much stronger.
dice_mult = (dice_mult * 150) / 100;
@@ -2407,9 +2565,8 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus,
pbolt.thrower = KILL_YOU_MISSILE;
pbolt.aux_source.clear();
}
-
- if ((bow_brand == SPWPN_FROST || ammo_brand == SPMSL_ICE)
- && ammo_brand != SPMSL_FLAME && bow_brand != SPWPN_FLAME)
+ else if ((bow_brand == SPWPN_FROST || ammo_brand == SPMSL_ICE)
+ && ammo_brand != SPMSL_FLAME && bow_brand != SPWPN_FLAME)
{
// [dshaligram] Branded arrows are much stronger.
dice_mult = (dice_mult * 150) / 100;
@@ -2522,12 +2679,15 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus,
}
}
+ if (ammo_name.empty())
+ ammo_name = ammo.name(DESC_NOCAP_A);
+
// Create message.
mprf( "%s %s%s %s.",
teleport ? "Magically, you" : "You",
projected ? "" : "awkwardly ",
projected == LRET_LAUNCHED ? "shoot" : "throw",
- ammo.name(DESC_NOCAP_A).c_str() );
+ ammo_name.c_str() );
// Ensure we're firing a 'missile'-type beam.
pbolt.is_beam = false;
@@ -2559,6 +2719,10 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus,
did_return = false;
}
+ if (bow_brand == SPWPN_CHAOS || ammo_brand == SPMSL_CHAOS)
+ did_god_conduct(DID_CHAOS, 2 + random2(3),
+ bow_brand == SPWPN_CHAOS || ammon_brand_known);
+
if (did_return)
{
// Fire beam in reverse.