diff options
author | zelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573> | 2008-12-01 04:00:00 +0000 |
---|---|---|
committer | zelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573> | 2008-12-01 04:00:00 +0000 |
commit | 04f5058cac8e12d3b85834bda4589239932f371a (patch) | |
tree | 20863dfb1b0a87c9643f0ca98ce2cb43cf195416 /crawl-ref/source/item_use.cc | |
parent | 6e3985b473d0b26c028820b3d0a3808d3f3dd7ee (diff) | |
download | crawl-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.cc | 182 |
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. |