summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/item_use.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/item_use.cc')
-rw-r--r--crawl-ref/source/item_use.cc454
1 files changed, 247 insertions, 207 deletions
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index 2307435db5..0e59c37712 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -45,6 +45,7 @@
#include "it_use3.h"
#include "items.h"
#include "itemname.h"
+#include "itemprop.h"
#include "misc.h"
#include "monplace.h"
#include "monstuff.h"
@@ -90,7 +91,7 @@ bool can_wield(const item_def& weapon)
return false;
if ((you.species < SP_OGRE || you.species > SP_OGRE_MAGE)
- && mass_item( weapon ) >= 500)
+ && item_mass( weapon ) >= 500)
return false;
if ((you.species == SP_HALFLING || you.species == SP_GNOME
@@ -98,7 +99,7 @@ bool can_wield(const item_def& weapon)
&& (weapon.sub_type == WPN_GREAT_SWORD
|| weapon.sub_type == WPN_TRIPLE_SWORD
|| weapon.sub_type == WPN_GREAT_MACE
- || weapon.sub_type == WPN_GREAT_FLAIL
+ || weapon.sub_type == WPN_DIRE_FLAIL
|| weapon.sub_type == WPN_BATTLEAXE
|| weapon.sub_type == WPN_EXECUTIONERS_AXE
|| weapon.sub_type == WPN_HALBERD
@@ -109,7 +110,7 @@ bool can_wield(const item_def& weapon)
return false;
if (hands_reqd_for_weapon( weapon.base_type,
- weapon.sub_type ) == HANDS_TWO_HANDED
+ weapon.sub_type ) == HANDS_TWO
&& you.equip[EQ_SHIELD] != -1)
return false;
@@ -247,7 +248,7 @@ bool wield_weapon(bool auto_wield, int slot, bool show_weff_messages)
else
{
if ((you.species < SP_OGRE || you.species > SP_OGRE_MAGE)
- && mass_item( you.inv[item_slot] ) >= 500)
+ && item_mass( you.inv[item_slot] ) >= 500)
{
mpr("That's too large and heavy for you to wield.");
return (false);
@@ -259,7 +260,7 @@ bool wield_weapon(bool auto_wield, int slot, bool show_weff_messages)
&& (you.inv[item_slot].sub_type == WPN_GREAT_SWORD
|| you.inv[item_slot].sub_type == WPN_TRIPLE_SWORD
|| you.inv[item_slot].sub_type == WPN_GREAT_MACE
- || you.inv[item_slot].sub_type == WPN_GREAT_FLAIL
+ || you.inv[item_slot].sub_type == WPN_DIRE_FLAIL
|| you.inv[item_slot].sub_type == WPN_BATTLEAXE
|| you.inv[item_slot].sub_type == WPN_EXECUTIONERS_AXE
|| you.inv[item_slot].sub_type == WPN_HALBERD
@@ -274,7 +275,7 @@ bool wield_weapon(bool auto_wield, int slot, bool show_weff_messages)
}
if (hands_reqd_for_weapon( you.inv[item_slot].base_type,
- you.inv[item_slot].sub_type ) == HANDS_TWO_HANDED
+ you.inv[item_slot].sub_type ) == HANDS_TWO
&& you.equip[EQ_SHIELD] != -1)
{
mpr("You can't wield that with a shield.");
@@ -617,37 +618,8 @@ void wear_armour(void)
do_wear_armour( armour_wear_2, false );
}
-int armour_equip_slot(const item_def &item)
-{
- int wh_equip = EQ_BODY_ARMOUR;
-
- switch (item.sub_type)
- {
- case ARM_BUCKLER:
- case ARM_LARGE_SHIELD:
- case ARM_SHIELD:
- wh_equip = EQ_SHIELD;
- break;
- case ARM_CLOAK:
- wh_equip = EQ_CLOAK;
- break;
- case ARM_HELMET:
- wh_equip = EQ_HELMET;
- break;
- case ARM_GLOVES:
- wh_equip = EQ_GLOVES;
- break;
- case ARM_BOOTS:
- wh_equip = EQ_BOOTS;
- break;
- }
- return (wh_equip);
-}
-
bool do_wear_armour( int item, bool quiet )
{
- char wh_equip = 0;
-
if (!is_valid_item( you.inv[item] ))
{
if (!quiet)
@@ -656,7 +628,8 @@ bool do_wear_armour( int item, bool quiet )
return (false);
}
- if (you.inv[item].base_type != OBJ_ARMOUR)
+ const int base_type = you.inv[item].base_type;
+ if (base_type != OBJ_ARMOUR)
{
if (!quiet)
mpr("You can't wear that.");
@@ -664,6 +637,10 @@ bool do_wear_armour( int item, bool quiet )
return (false);
}
+ const int sub_type = you.inv[item].sub_type;
+ const item_def &invitem = you.inv[item];
+ const equipment_type slot = get_armour_slot(invitem);
+
if (item == you.equip[EQ_WEAPON])
{
if (!quiet)
@@ -691,7 +668,7 @@ bool do_wear_armour( int item, bool quiet )
|| you.inv[item].sub_type == ARM_LARGE_SHIELD)
// weapon is two-handed
&& hands_reqd_for_weapon(you.inv[you.equip[EQ_WEAPON]].base_type,
- you.inv[you.equip[EQ_WEAPON]].sub_type) == HANDS_TWO_HANDED)
+ you.inv[you.equip[EQ_WEAPON]].sub_type) == HANDS_TWO)
{
if (!quiet)
mpr("You'd need three hands to do that!");
@@ -699,21 +676,26 @@ bool do_wear_armour( int item, bool quiet )
return (false);
}
- if (you.inv[item].sub_type == ARM_BOOTS)
- {
- if (you.species != SP_NAGA && you.inv[item].plus2 == TBOOT_NAGA_BARDING)
- {
- if (!quiet)
- mpr("You can't wear that!");
+ bool can_wear = true;
+ if (sub_type == ARM_NAGA_BARDING)
+ can_wear = (you.species == SP_NAGA);
- return (false);
- }
+ if (sub_type == ARM_CENTAUR_BARDING)
+ can_wear = (you.species == SP_CENTAUR);
+
+ if (!can_wear)
+ {
+ if (!quiet)
+ mpr("You can't wear that!");
+ return (false);
+ }
- if (you.species != SP_CENTAUR && you.inv[item].plus2 == TBOOT_CENTAUR_BARDING)
+ if (you.inv[item].sub_type == ARM_BOOTS)
+ {
+ if (you.species == SP_NAGA || you.species == SP_CENTAUR)
{
if (!quiet)
- mpr("You can't wear that!");
-
+ mpr("You can't wear that!");
return (false);
}
@@ -726,28 +708,24 @@ bool do_wear_armour( int item, bool quiet )
}
}
- wh_equip = armour_equip_slot(you.inv[item]);
-
- if (you.species == SP_NAGA && you.inv[item].sub_type == ARM_BOOTS
- && you.inv[item].plus2 == TBOOT_NAGA_BARDING
+ if (you.species == SP_NAGA && sub_type == ARM_NAGA_BARDING
&& !player_is_shapechanged())
{
// it fits
}
else if (you.species == SP_CENTAUR
- && you.inv[item].sub_type == ARM_BOOTS
- && you.inv[item].plus2 == TBOOT_CENTAUR_BARDING
+ && sub_type == ARM_CENTAUR_BARDING
&& !player_is_shapechanged())
{
// it fits
}
- else if (you.inv[item].sub_type == ARM_HELMET
- && (cmp_helmet_type( you.inv[item], THELM_CAP )
- || cmp_helmet_type( you.inv[item], THELM_WIZARD_HAT )))
+ else if (sub_type == ARM_HELMET
+ && (get_helmet_type(invitem) == THELM_CAP
+ || get_helmet_type(invitem) == THELM_WIZARD_HAT))
{
// caps & wiz hats always fit, unless your head's too big (ogres &c)
}
- else if (!can_equip( wh_equip ))
+ else if (!can_equip( slot ))
{
if (!quiet)
mpr("You can't wear that in your present form.");
@@ -757,8 +735,8 @@ bool do_wear_armour( int item, bool quiet )
// Cannot swim in heavy armour
if (player_is_swimming()
- && wh_equip == EQ_BODY_ARMOUR
- && !is_light_armour( you.inv[item] ))
+ && slot == EQ_BODY_ARMOUR
+ && !is_light_armour( invitem ))
{
if (!quiet)
mpr("You can't swim in that!");
@@ -770,14 +748,14 @@ bool do_wear_armour( int item, bool quiet )
if ((you.species >= SP_OGRE && you.species <= SP_OGRE_MAGE)
|| player_genus(GENPC_DRACONIAN))
{
- if ((you.inv[item].sub_type >= ARM_LEATHER_ARMOUR
- && you.inv[item].sub_type <= ARM_PLATE_MAIL)
- || (you.inv[item].sub_type >= ARM_GLOVES
- && you.inv[item].sub_type <= ARM_BUCKLER)
- || you.inv[item].sub_type == ARM_CRYSTAL_PLATE_MAIL
- || (you.inv[item].sub_type == ARM_HELMET
- && (cmp_helmet_type( you.inv[item], THELM_HELM )
- || cmp_helmet_type( you.inv[item], THELM_HELMET ))))
+ if ((sub_type >= ARM_LEATHER_ARMOUR
+ && sub_type <= ARM_PLATE_MAIL)
+ || (sub_type >= ARM_GLOVES
+ && sub_type <= ARM_BUCKLER)
+ || sub_type == ARM_CRYSTAL_PLATE_MAIL
+ || (sub_type == ARM_HELMET
+ && (get_helmet_type(invitem) == THELM_HELM
+ || get_helmet_type(invitem) == THELM_HELMET)))
{
if (!quiet)
mpr("This armour doesn't fit on your body.");
@@ -789,16 +767,16 @@ bool do_wear_armour( int item, bool quiet )
// Tiny races
if (you.species == SP_SPRIGGAN)
{
- if ((you.inv[item].sub_type >= ARM_LEATHER_ARMOUR
- && you.inv[item].sub_type <= ARM_PLATE_MAIL)
- || you.inv[item].sub_type == ARM_GLOVES
- || you.inv[item].sub_type == ARM_BOOTS
- || you.inv[item].sub_type == ARM_SHIELD
- || you.inv[item].sub_type == ARM_LARGE_SHIELD
- || you.inv[item].sub_type == ARM_CRYSTAL_PLATE_MAIL
- || (you.inv[item].sub_type == ARM_HELMET
- && (cmp_helmet_type( you.inv[item], THELM_HELM )
- || cmp_helmet_type( you.inv[item], THELM_HELMET ))))
+ if ((sub_type >= ARM_LEATHER_ARMOUR
+ && sub_type <= ARM_PLATE_MAIL)
+ || sub_type == ARM_GLOVES
+ || sub_type == ARM_BOOTS
+ || sub_type == ARM_SHIELD
+ || sub_type == ARM_LARGE_SHIELD
+ || sub_type == ARM_CRYSTAL_PLATE_MAIL
+ || (sub_type == ARM_HELMET
+ && (get_helmet_type(invitem) == THELM_HELM
+ || get_helmet_type(invitem) == THELM_HELMET)))
{
if (!quiet)
mpr("This armour doesn't fit on your body.");
@@ -810,11 +788,10 @@ bool do_wear_armour( int item, bool quiet )
bool removedCloak = false;
int cloak = -1;
- if ((you.inv[item].sub_type < ARM_SHIELD
- || you.inv[item].sub_type > ARM_LARGE_SHIELD)
- && (you.equip[EQ_CLOAK] != -1 && !cloak_is_being_removed()))
+ if (slot == EQ_BODY_ARMOUR
+ && you.equip[EQ_CLOAK] != -1 && !cloak_is_being_removed())
{
- if (item_uncursed( you.inv[you.equip[EQ_CLOAK]] ))
+ if (!item_cursed( you.inv[you.equip[EQ_CLOAK]] ))
{
cloak = you.equip[ EQ_CLOAK ];
if (!takeoff_armour(you.equip[EQ_CLOAK]))
@@ -831,42 +808,37 @@ bool do_wear_armour( int item, bool quiet )
}
}
- if (you.inv[item].sub_type == ARM_CLOAK && you.equip[EQ_CLOAK] != -1)
+ if (slot == EQ_CLOAK && you.equip[EQ_CLOAK] != -1)
{
if (!takeoff_armour(you.equip[EQ_CLOAK]))
return (false);
}
- if (you.inv[item].sub_type == ARM_HELMET && you.equip[EQ_HELMET] != -1)
+ if (slot == EQ_HELMET && you.equip[EQ_HELMET] != -1)
{
if (!takeoff_armour(you.equip[EQ_HELMET]))
return (false);
}
- if (you.inv[item].sub_type == ARM_GLOVES && you.equip[EQ_GLOVES] != -1)
+ if (slot == EQ_GLOVES && you.equip[EQ_GLOVES] != -1)
{
if (!takeoff_armour(you.equip[EQ_GLOVES]))
return (false);
}
- if (you.inv[item].sub_type == ARM_BOOTS && you.equip[EQ_BOOTS] != -1)
+ if (slot == EQ_BOOTS && you.equip[EQ_BOOTS] != -1)
{
if (!takeoff_armour(you.equip[EQ_BOOTS]))
return (false);
}
- if ((you.inv[item].sub_type == ARM_SHIELD
- || you.inv[item].sub_type == ARM_LARGE_SHIELD
- || you.inv[item].sub_type == ARM_BUCKLER)
- && you.equip[EQ_SHIELD] != -1)
+ if (slot == EQ_SHIELD && you.equip[EQ_SHIELD] != -1)
{
if (!takeoff_armour(you.equip[EQ_SHIELD]))
return (false);
}
- if ((you.inv[item].sub_type < ARM_SHIELD
- || you.inv[item].sub_type > ARM_LARGE_SHIELD)
- && you.equip[EQ_BODY_ARMOUR] != -1)
+ if (slot == EQ_BODY_ARMOUR && you.equip[EQ_BODY_ARMOUR] != -1)
{
if (!takeoff_armour(you.equip[EQ_BODY_ARMOUR]))
return (false);
@@ -912,13 +884,13 @@ bool takeoff_armour(int item)
bool removedCloak = false;
int cloak = -1;
+ const equipment_type slot = get_armour_slot(you.inv[item]);
- if (you.inv[item].sub_type < ARM_SHIELD
- || you.inv[item].sub_type > ARM_LARGE_SHIELD)
+ if (slot == EQ_BODY_ARMOUR)
{
if (you.equip[EQ_CLOAK] != -1 && !cloak_is_being_removed())
{
- if (item_uncursed( you.inv[you.equip[EQ_CLOAK]] ))
+ if (!item_cursed( you.inv[you.equip[EQ_CLOAK]] ))
{
cloak = you.equip[ EQ_CLOAK ];
if (!takeoff_armour(you.equip[EQ_CLOAK]))
@@ -943,11 +915,9 @@ bool takeoff_armour(int item)
}
else
{
- switch (you.inv[item].sub_type)
+ switch (slot)
{
- case ARM_BUCKLER:
- case ARM_LARGE_SHIELD:
- case ARM_SHIELD:
+ case EQ_SHIELD:
if (item != you.equip[EQ_SHIELD])
{
mpr("You aren't wearing that!");
@@ -955,7 +925,7 @@ bool takeoff_armour(int item)
}
break;
- case ARM_CLOAK:
+ case EQ_CLOAK:
if (item != you.equip[EQ_CLOAK])
{
mpr("You aren't wearing that!");
@@ -963,7 +933,7 @@ bool takeoff_armour(int item)
}
break;
- case ARM_HELMET:
+ case EQ_HELMET:
if (item != you.equip[EQ_HELMET])
{
mpr("You aren't wearing that!");
@@ -971,8 +941,7 @@ bool takeoff_armour(int item)
}
break;
-
- case ARM_GLOVES:
+ case EQ_GLOVES:
if (item != you.equip[EQ_GLOVES])
{
mpr("You aren't wearing that!");
@@ -980,13 +949,16 @@ bool takeoff_armour(int item)
}
break;
- case ARM_BOOTS:
+ case EQ_BOOTS:
if (item != you.equip[EQ_BOOTS])
{
mpr("You aren't wearing that!");
return false;
}
break;
+
+ default:
+ break;
}
}
@@ -1196,6 +1168,7 @@ static void throw_it(struct bolt &pbolt, int throw_2)
int lnchHitBonus = 0, lnchDamBonus = 0; // special add from launcher
int exHitBonus = 0, exDamBonus = 0; // 'extra' bonus from skill/dex/str
int effSkill = 0; // effective launcher skill
+ int damageMult = 100;
bool launched = false; // item is launched
bool thrown = false; // item is sensible thrown item
@@ -1290,11 +1263,11 @@ static void throw_it(struct bolt &pbolt, int throw_2)
}
// baseHit and damage for generic objects
- baseHit = you.strength - mass_item(item) / 10;
+ baseHit = you.strength - item_mass(item) / 10;
if (baseHit > 0)
baseHit = 0;
- baseDam = mass_item(item) / 100;
+ baseDam = item_mass(item) / 100;
// special: might be throwing generic weapon;
// use base wep. damage, w/ penalty
@@ -1322,21 +1295,47 @@ static void throw_it(struct bolt &pbolt, int throw_2)
// CALCULATIONS FOR LAUNCHED WEAPONS
if (launched)
{
- const int bow_brand = get_weapon_brand( you.inv[you.equip[EQ_WEAPON]] );
+ const item_def &launcher = you.inv[you.equip[EQ_WEAPON]];
+ const int bow_brand = get_weapon_brand( launcher );
const int ammo_brand = get_ammo_brand( item );
+ const bool two_handed = (you.equip[EQ_SHIELD] == -1);
bool poisoned = (ammo_brand == SPMSL_POISONED
|| ammo_brand == SPMSL_POISONED_II);
-
- // this is deliberately confusing: the 'hit' value for
- // ammo is the _damage_ when used with a launcher. Geez.
- baseHit = 0;
- baseDam = property( item, PWPN_HIT );
+ const int rc_skill = you.skills[SK_RANGED_COMBAT];
+
+ const int item_base_dam = property( item, PWPN_DAMAGE );
+ const int lnch_base_dam = property( launcher, PWPN_DAMAGE );
+
+ const skill_type launcher_skill = range_skill( launcher );
+ const int str_weight = weapon_str_weight( launcher );
+ const int dex_weight = 10 - str_weight;
+
+ int speed_base = 10 * property( launcher, PWPN_SPEED );
+ int speed_min = 50;
+ int speed_stat = str_weight * you.strength + dex_weight * you.dex;
+ int speed = 100;
+
+ baseHit = property( launcher, PWPN_HIT );
+ baseDam = item_base_dam + random2(1 + lnch_base_dam);
+
+ if (launcher_skill == SK_BOWS)
+ speed_min = 40;
+ else if (launcher_skill == SK_CROSSBOWS)
+ speed_min = 60;
+
+#ifdef DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS,
+ "Base hit == %d; Base damage == %d "
+ "(item %d + launcher %d)",
+ baseHit, baseDam,
+ item_base_dam, lnch_base_dam);
+#endif
// fix ammo damage bonus, since missiles only use inv_plus
ammoDamBonus = ammoHitBonus;
// check for matches; dwarven,elven,orcish
- if (!cmp_equip_race( you.inv[you.equip[EQ_WEAPON]], 0 ))
+ if (!get_equip_race(you.inv[you.equip[EQ_WEAPON]]) == 0)
{
if (get_equip_race( you.inv[you.equip[EQ_WEAPON]] )
== get_equip_race( item ))
@@ -1345,7 +1344,8 @@ static void throw_it(struct bolt &pbolt, int throw_2)
baseDam += 1;
// elves with elven bows
- if (cmp_equip_race(you.inv[you.equip[EQ_WEAPON]], ISFLAG_ELVEN)
+ if (get_equip_race(you.inv[you.equip[EQ_WEAPON]])
+ == ISFLAG_ELVEN
&& player_genus(GENPC_ELVEN))
{
baseHit += 1;
@@ -1353,69 +1353,78 @@ static void throw_it(struct bolt &pbolt, int throw_2)
}
}
- if (you.inv[you.equip[EQ_WEAPON]].sub_type == WPN_CROSSBOW)
- {
- // extra time taken, as a percentage. range from 30 -> 12
- int extraTime = 30 - ((you.skills[SK_CROSSBOWS] * 2) / 3);
-
- you.time_taken = (100 + extraTime) * you.time_taken;
- you.time_taken /= 100;
- }
-
- if (bow_brand == SPWPN_SPEED)
- {
- you.time_taken *= 5;
- you.time_taken /= 10;
- }
-
// for all launched weapons, maximum effective specific skill
// is twice throwing skill. This models the fact that no matter
// how 'good' you are with a bow, if you know nothing about
// trajectories you're going to be a damn poor bowman. Ditto
// for crossbows and slings.
- switch (lnchType)
+
+ // [dshaligram] Throwing now two parts launcher skill, one part
+ // ranged combat. Removed the old model which is... silly.
+
+ shoot_skill = you.skills[launcher_skill];
+ effSkill = (shoot_skill * 2 + skill_bump(SK_RANGED_COMBAT)) / 3;
+
+ // FIXME: Use actual body size
+ if (!two_handed && hands_reqd(launcher, SIZE_MEDIUM) == HANDS_HALF)
{
- case WPN_SLING:
- shoot_skill = you.skills[SK_SLINGS];
- break;
- case WPN_BOW:
- shoot_skill = you.skills[SK_BOWS];
- break;
- case WPN_BLOWGUN:
- shoot_skill = you.skills[SK_DARTS];
- break;
- case WPN_CROSSBOW:
- case WPN_HAND_CROSSBOW:
- shoot_skill = you.skills[SK_CROSSBOWS];
- break;
- default:
- shoot_skill = 0;
- break;
+ speed_base = (speed_base * 3 + 1) / 2;
+ speed_min = (speed_min * 3 + 1) / 2;
+ }
+
+ speed = speed_base - shoot_skill * speed_stat / 50;
+ if (speed < speed_min)
+ speed = speed_min;
+
+ if (bow_brand == SPWPN_SPEED)
+ {
+ // Speed nerf as per 4.1
+ speed = 2 * speed / 3;
}
+#ifdef DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS, "Final launcher speed: %d", speed);
+#endif
+
+ you.time_taken = speed * you.time_taken / 100;
+
+ // effSkill = you.skills[SK_RANGED_COMBAT] * 2 + 1;
+ // effSkill = (shoot_skill > effSkill) ? effSkill : shoot_skill;
- effSkill = you.skills[SK_THROWING] * 2 + 1;
- effSkill = (shoot_skill > effSkill) ? effSkill : shoot_skill;
+ // [dshaligram] Improving missile weapons:
+ // - Remove the strength/enchantment cap where you need to be strong
+ // to exploit a launcher bonus.
+ // - Add on launcher and missile pluses to extra damage.
+ // [dshaligram] This can get large...
+ exDamBonus = lnchDamBonus + ammoDamBonus;
+ exHitBonus = lnchHitBonus;
+
+ // Raw ranged combat skill also helps with damage.
+ if (lnchType != WPN_BLOWGUN)
+ exDamBonus += rc_skill / 4;
+
// removed 2 random2(2)s from each of the learning curves, but
// left slings because they're hard enough to develop without
// a good source of shot in the dungeon.
- switch (lnchType)
+ switch (launcher_skill)
+ {
+ case SK_SLINGS:
{
- case WPN_SLING:
// Slings are really easy to learn because they're not
// really all that good, and its harder to get ammo anyways.
exercise(SK_SLINGS, 1 + random2avg(3, 2));
baseHit += 0;
- exHitBonus = (effSkill * 3) / 2;
+ exHitBonus += (effSkill * 3) / 2;
// strength is good if you're using a nice sling.
- exDamBonus = (10 * (you.strength - 10)) / 9;
- exDamBonus = (exDamBonus * (2 * baseDam + ammoDamBonus)) / 20;
+ int strbonus = (10 * (you.strength - 10)) / 9;
+ strbonus = (strbonus * (2 * baseDam + ammoDamBonus)) / 20;
// cap
- if (exDamBonus > lnchDamBonus + 1)
- exDamBonus = lnchDamBonus + 1;
+ if (strbonus > lnchDamBonus + 1)
+ strbonus = lnchDamBonus + 1;
+ exDamBonus += strbonus;
// add skill for slings.. helps to find those vulnerable spots
exDamBonus += effSkill / 2;
@@ -1423,16 +1432,16 @@ static void throw_it(struct bolt &pbolt, int throw_2)
if (lnchDamBonus > 0)
lnchDamBonus = 0;
break;
-
+ }
// blowguns take a _very_ steady hand; a lot of the bonus
// comes from dexterity. (Dex bonus here as well as below)
- case WPN_BLOWGUN:
+ case SK_DARTS:
exercise(SK_DARTS, (coinflip()? 2 : 1));
baseHit -= 2;
- exHitBonus = (effSkill * 3) / 2 + you.dex / 2;
+ exHitBonus += (effSkill * 3) / 2 + you.dex / 2;
// no extra damage for blowguns
- exDamBonus = 0;
+ // exDamBonus = 0;
// now kill the launcher damage and ammo bonuses
if (lnchDamBonus > 0)
@@ -1441,52 +1450,62 @@ static void throw_it(struct bolt &pbolt, int throw_2)
ammoDamBonus = 0;
break;
-
- case WPN_BOW:
+ case SK_BOWS:
+ {
exercise(SK_BOWS, (coinflip()? 2 : 1));
baseHit -= 4;
- exHitBonus = (effSkill * 2);
+ exHitBonus += (effSkill * 2);
// strength is good if you're using a nice bow
- exDamBonus = (10 * (you.strength - 10)) / 4;
- exDamBonus = (exDamBonus * (2 * baseDam + ammoDamBonus)) / 20;
+ int strbonus = (10 * (you.strength - 10)) / 4;
+ strbonus = (strbonus * (2 * baseDam + ammoDamBonus)) / 20;
- // cap
- if (exDamBonus > (lnchDamBonus + 1) * 3)
- exDamBonus = (lnchDamBonus + 1) * 3;
+ // cap; reduced this cap, because we don't want to allow
+ // the extremely-strong to quadruple the enchantment bonus.
+ if (strbonus > lnchDamBonus + 1)
+ strbonus = lnchDamBonus + 1;
+
+ exDamBonus += strbonus;
// add in skill for bows.. help you to find those vulnerable spots.
- exDamBonus += effSkill;
+ exDamBonus += effSkill * 5 / 4;
// now kill the launcher damage bonus
if (lnchDamBonus > 0)
lnchDamBonus = 0;
break;
-
+ }
// Crossbows are easy for unskilled people.
- case WPN_CROSSBOW:
+ case SK_CROSSBOWS:
exercise(SK_CROSSBOWS, (coinflip()? 2 : 1));
- baseHit += 2;
- exHitBonus = (3 * effSkill) / 2 + 6;
- exDamBonus = effSkill / 2 + 4;
+ baseHit += lnchType == WPN_CROSSBOW? 2 : 1;
+ exHitBonus += (3 * effSkill) / 2 + 6;
+ exDamBonus += effSkill * 2 / 3 + 4;
+ if (lnchType == WPN_HAND_CROSSBOW)
+ {
+ exHitBonus -= 2;
+ exDamBonus -= 2;
+ }
break;
- case WPN_HAND_CROSSBOW:
- exercise(SK_CROSSBOWS, (coinflip()? 2 : 1));
- baseHit += 1;
- exHitBonus = (3 * effSkill) / 2 + 4;
- exDamBonus = effSkill / 2 + 2;
+ default:
break;
}
// all launched weapons have a slight chance of improving
// throwing skill
if (coinflip())
- exercise(SK_THROWING, 1);
+ exercise(SK_RANGED_COMBAT, 1);
// all launched weapons get a tohit boost from throwing skill.
- exHitBonus += (3 * you.skills[SK_THROWING]) / 4;
+ exHitBonus += (3 * you.skills[SK_RANGED_COMBAT]) / 4;
+
+ if (bow_brand == SPWPN_VORPAL)
+ {
+ // Vorpal brand adds 35% damage bonus.
+ exDamBonus = exDamBonus * 135 / 100;
+ }
// special cases for flame, frost, poison, etc.
// check for venom brand (usually only available for blowguns)
@@ -1502,7 +1521,9 @@ static void throw_it(struct bolt &pbolt, int throw_2)
if ((bow_brand == SPWPN_FLAME || ammo_brand == SPMSL_FLAME)
&& ammo_brand != SPMSL_ICE && bow_brand != SPWPN_FROST)
{
- baseDam += 1 + random2(5);
+ // [dshaligram] Branded arrows are much stronger.
+ damageMult = 150;
+
pbolt.flavour = BEAM_FIRE;
strcpy(pbolt.beam_name, "bolt of ");
@@ -1526,7 +1547,9 @@ static void throw_it(struct bolt &pbolt, int throw_2)
if ((bow_brand == SPWPN_FROST || ammo_brand == SPMSL_ICE)
&& ammo_brand != SPMSL_FLAME && bow_brand != SPWPN_FLAME)
{
- baseDam += 1 + random2(5);
+ // [dshaligram] Branded arrows are much stronger.
+ damageMult = 150;
+
pbolt.flavour = BEAM_COLD;
strcpy(pbolt.beam_name, "bolt of ");
@@ -1563,7 +1586,7 @@ static void throw_it(struct bolt &pbolt, int throw_2)
* and vice versa */
// ID check
- if (item_not_ident( you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_PLUSES )
+ if (!item_ident( you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_PLUSES )
&& random2(100) < shoot_skill)
{
set_ident_flags(you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_PLUSES);
@@ -1593,7 +1616,8 @@ static void throw_it(struct bolt &pbolt, int throw_2)
|| (wepClass == OBJ_MISSILES && wepType == MI_STONE))
{
// elves with elven weapons
- if (cmp_equip_race(item, ISFLAG_ELVEN) && player_genus(GENPC_ELVEN))
+ if (get_equip_race(item) == ISFLAG_ELVEN
+ && player_genus(GENPC_ELVEN))
baseHit += 1;
// give an appropriate 'tohit' -
@@ -1617,11 +1641,11 @@ static void throw_it(struct bolt &pbolt, int throw_2)
}
}
- exHitBonus = you.skills[SK_THROWING] * 2;
+ exHitBonus = you.skills[SK_RANGED_COMBAT] * 2;
baseDam = property( item, PWPN_DAMAGE );
exDamBonus =
- (10 * (you.skills[SK_THROWING] / 2 + you.strength - 10)) / 12;
+ (10 * (you.skills[SK_RANGED_COMBAT] / 2 + you.strength - 10)) / 12;
// now, exDamBonus is a multiplier. The full multiplier
// is applied to base damage, but only a third is applied
@@ -1636,16 +1660,30 @@ static void throw_it(struct bolt &pbolt, int throw_2)
baseDam = property( item, PWPN_DAMAGE );
exHitBonus = you.skills[SK_DARTS] * 2;
- exHitBonus += (you.skills[SK_THROWING] * 2) / 3;
- exDamBonus = you.skills[SK_DARTS] / 4;
+ exHitBonus += (you.skills[SK_RANGED_COMBAT] * 2) / 3;
+ exDamBonus = you.skills[SK_DARTS] / 3;
+ exDamBonus += you.skills[SK_RANGED_COMBAT] / 5;
// exercise skills
exercise(SK_DARTS, 1 + random2avg(3, 2));
}
+ if (wepClass == OBJ_MISSILES && wepType == MI_NEEDLE)
+ {
+ // Throwing needles is now seriously frowned upon; it's difficult
+ // to grip a fiddly little needle, and not penalising it cheapens
+ // blowguns.
+ exHitBonus -= (30 - you.skills[SK_DARTS]) / 3;
+ baseHit -= (30 - you.skills[SK_DARTS]) / 4;
+#ifdef DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS, "Needle base hit = %d, exHitBonus = %d",
+ baseHit, exHitBonus);
+#endif
+ }
+
// exercise skill
if (coinflip())
- exercise(SK_THROWING, 1);
+ exercise(SK_RANGED_COMBAT, 1);
}
// range, dexterity bonus, possible skill increase for silly throwing
@@ -1676,7 +1714,7 @@ static void throw_it(struct bolt &pbolt, int throw_2)
else
{
// range based on mass & strength, between 1 and 9
- pbolt.range = you.strength - mass_item(item) / 10 + 3;
+ pbolt.range = you.strength - item_mass(item) / 10 + 3;
if (pbolt.range < 1)
pbolt.range = 1;
@@ -1687,7 +1725,7 @@ static void throw_it(struct bolt &pbolt, int throw_2)
pbolt.rangeMax = pbolt.range;
if (one_chance_in(20))
- exercise(SK_THROWING, 1);
+ exercise(SK_RANGED_COMBAT, 1);
exHitBonus = you.dex / 4;
}
@@ -1703,6 +1741,9 @@ static void throw_it(struct bolt &pbolt, int throw_2)
else
pbolt.damage = dice_def( 1, baseDam - random2(0 - (exDamBonus - 1)) );
+ pbolt.damage.size = damageMult * pbolt.damage.size / 100;
+ scale_dice( pbolt.damage );
+
// only add bonuses if we're throwing something sensible
if (thrown || launched || wepClass == OBJ_WEAPONS)
{
@@ -1711,13 +1752,11 @@ static void throw_it(struct bolt &pbolt, int throw_2)
}
#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE,
- "H:%d+%d;a%dl%d. D:%d+%d;a%dl%d -> %d,%dd%d",
+ mprf( MSGCH_DIAGNOSTICS,
+ "H:%d+%d;a%dl%d. D:%d+%d;a%dl%d -> %d,%dd%d",
baseHit, exHitBonus, ammoHitBonus, lnchHitBonus,
baseDam, exDamBonus, ammoDamBonus, lnchDamBonus,
pbolt.hit, pbolt.damage.num, pbolt.damage.size );
-
- mpr( info, MSGCH_DIAGNOSTICS );
#endif
// create message
@@ -1733,8 +1772,8 @@ static void throw_it(struct bolt &pbolt, int throw_2)
mpr(info);
// ensure we're firing a 'missile'-type beam
- pbolt.isBeam = false;
- pbolt.isTracer = false;
+ pbolt.is_beam = false;
+ pbolt.is_tracer = false;
// mark this item as thrown if it's a missile, so that we'll pick it up
// when we walk over it.
@@ -2189,7 +2228,7 @@ void zap_wand(void)
// system will default to cycling through all monsters. -- bwr
int targ_mode = TARG_ANY;
- beam.obviousEffect = false;
+ beam.obvious_effect = false;
if (inv_count() < 1)
{
@@ -2280,7 +2319,7 @@ void zap_wand(void)
zapping( type_zapped, 30 + roll_dice(2, you.skills[SK_EVOCATIONS]), beam );
- if (beam.obviousEffect == 1 || you.inv[item_slot].sub_type == WAND_FIREBALL)
+ if (beam.obvious_effect == 1 || you.inv[item_slot].sub_type == WAND_FIREBALL)
{
if (get_ident_type( you.inv[item_slot].base_type,
you.inv[item_slot].sub_type ) != ID_KNOWN_TYPE)
@@ -2309,7 +2348,7 @@ void zap_wand(void)
&& (item_ident( you.inv[item_slot], ISFLAG_KNOW_PLUSES )
|| you.skills[SK_EVOCATIONS] > 5 + random2(15)))
{
- if (item_not_ident( you.inv[item_slot], ISFLAG_KNOW_PLUSES ))
+ if (!item_ident( you.inv[item_slot], ISFLAG_KNOW_PLUSES ))
{
mpr("Your skill with magical items lets you calculate the power of this device...");
}
@@ -2491,8 +2530,7 @@ static bool affix_weapon_enchantment( void )
switch (get_weapon_brand( you.inv[wpn] ))
{
case SPWPN_VORPAL:
- if (damage_type( you.inv[wpn].base_type,
- you.inv[wpn].sub_type ) != DVORP_CRUSHING)
+ if (get_vorpal_type( you.inv[wpn] ) != DVORP_CRUSHING)
{
strcat(info, "'s sharpness seems more permanent.");
}
@@ -2517,7 +2555,8 @@ static bool affix_weapon_enchantment( void )
beam.thrower = KILL_YOU;
beam.aux_source = "a fiery explosion";
beam.ex_size = 2;
- beam.isTracer = false;
+ beam.is_tracer = false;
+ beam.is_explosion = true;
explosion(beam);
break;
@@ -2697,7 +2736,7 @@ static bool enchant_armour( void )
you.redraw_armour_class = 1;
- hide2armour( &(you.inv[nthing].sub_type) );
+ hide2armour(you.inv[nthing]);
return (true);
}
@@ -2828,7 +2867,7 @@ void read_scroll(void)
char str_pass[ ITEMNAME_SIZE ];
// added: scroll effects are never tracers.
- beam.isTracer = false;
+ beam.is_tracer = false;
if (you.berserker)
{
@@ -3005,6 +3044,7 @@ void read_scroll(void)
beam.thrower = KILL_YOU;
beam.aux_source = "reading a scroll of immolation";
beam.ex_size = 2;
+ beam.is_explosion = true;
explosion(beam);
break;
@@ -3140,7 +3180,7 @@ void read_scroll(void)
affected = EQ_WEAPON;
for (i = EQ_CLOAK; i <= EQ_BODY_ARMOUR; i++)
{
- if (you.equip[i] != -1 && item_uncursed( you.inv[you.equip[i]] ))
+ if (you.equip[i] != -1 && !item_cursed( you.inv[you.equip[i]] ))
{
count++;
if (one_chance_in( count ))