summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/item_use.cc
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-07-03 17:59:49 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-07-03 17:59:49 +0000
commit718202ee6b6445890db808f4420073e2cce506c2 (patch)
tree2640787ddfef39aca363946a32a05df0ae62c62e /crawl-ref/source/item_use.cc
parent589e206de3965240ac0475dcc98b339914ace70b (diff)
downloadcrawl-ref-718202ee6b6445890db808f4420073e2cce506c2.tar.gz
crawl-ref-718202ee6b6445890db808f4420073e2cce506c2.zip
Manual update (David).
Added javelins and sling bullets. Only Urug gets javelins at the moment. No monster gets sling bullets, but they can be randomly generated. Added deep elf blademasters and master archers to provide Silence-users some entertainment on Elf:7. I've adjusted the non-rogue-layout Elf:7s to use blademasters. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1732 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/item_use.cc')
-rw-r--r--crawl-ref/source/item_use.cc134
1 files changed, 98 insertions, 36 deletions
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index 2504377b1a..b2877bda6c 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -1134,7 +1134,7 @@ static int try_finding_throwing_weapon( int sub_type )
}
// Return index of first missile of sub_type or ENDOFPACK
-static int try_finding_missile( int sub_type )
+static int try_finding_missile( int sub_type, const item_def *launcher = NULL )
{
int i;
@@ -1144,15 +1144,20 @@ static int try_finding_missile( int sub_type )
if (!is_valid_item( you.inv[i] ))
continue;
+ const item_def &item = you.inv[i];
// In theory, we should do two passes, first trying
// to find a non-warning-inscribed item, then looping
// through the warning-inscribed ones. Seems unlikely
// to matter much.
+ if (launcher && item.launched_by(*launcher))
+ break;
+
// consider melee weapons that can also be thrown
- if (you.inv[i].base_type == OBJ_MISSILES &&
- you.inv[i].sub_type == sub_type &&
- check_warning_inscriptions(you.inv[i], OPER_FIRE))
+ if (item.base_type == OBJ_MISSILES
+ && (item.sub_type == sub_type
+ || (sub_type == MI_STONE && item.sub_type == MI_SLING_BULLET))
+ && check_warning_inscriptions(you.inv[i], OPER_FIRE))
{
break;
}
@@ -1180,8 +1185,7 @@ int get_fire_item_index( void )
&& you.inv[ weapon ].base_type == OBJ_WEAPONS
&& is_range_weapon( you.inv[ weapon ] ))
{
- int type_wanted = fires_ammo_type( you.inv[ weapon ] );
- item = try_finding_missile( type_wanted );
+ item = try_finding_missile( MI_NONE, &you.inv[weapon] );
}
break;
@@ -1193,6 +1197,10 @@ int get_fire_item_index( void )
item = try_finding_missile( MI_STONE );
break;
+ case FIRE_JAVELIN:
+ item = try_finding_missile( MI_JAVELIN );
+ break;
+
case FIRE_DAGGER:
item = try_finding_throwing_weapon( WPN_DAGGER );
break;
@@ -1352,6 +1360,33 @@ static bool determines_ammo_brand(int bow_brand, int ammo_brand)
return true;
}
+static int stat_adjust(int value, int stat, int statbase,
+ const int maxmult = 160, const int minmult = 40)
+{
+ int multiplier = (statbase + (stat - statbase) / 2) * 100 / statbase;
+ if (multiplier > maxmult)
+ multiplier = maxmult;
+ else if (multiplier < minmult)
+ multiplier = minmult;
+
+ if (multiplier > 100)
+ value = value * (100 + random2avg(multiplier - 100, 2)) / 100;
+ else if (multiplier < 100)
+ value = value * (100 - random2avg(100 - multiplier, 2)) / 100;
+
+ return (value);
+}
+
+static int str_adjust_thrown_damage(int dam)
+{
+ return stat_adjust(dam, you.strength, 15, 160, 90);
+}
+
+static int dex_adjust_thrown_tohit(int hit)
+{
+ return stat_adjust(hit, you.dex, 13, 160, 90);
+}
+
// 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,
@@ -1372,8 +1407,6 @@ bool throw_it(struct bolt &pbolt, int throw_2, bool teleport, int acc_bonus)
int exHitBonus = 0, exDamBonus = 0; // 'extra' bonus from skill/dex/str
int effSkill = 0; // effective launcher skill
int dice_mult = 100;
- bool launched = false; // item is launched
- bool thrown = false; // item is sensible thrown item
bool returning = false; // item will return to pack
int slayDam = 0;
@@ -1436,7 +1469,7 @@ bool throw_it(struct bolt &pbolt, int throw_2, bool teleport, int acc_bonus)
case OBJ_BOOKS: pbolt.type = SYM_OBJECT; break;
// this does not seem right, but value was 11 {dlb}
// notice how the .type does not match the class -- hmmm... {dlb}
- case OBJ_STAVES: pbolt.type = SYM_CHUNK; break;
+ case OBJ_STAVES: pbolt.type = SYM_STICK; break;
default: break;
}
@@ -1484,10 +1517,10 @@ bool throw_it(struct bolt &pbolt, int throw_2, bool teleport, int acc_bonus)
}
// figure out if we're thrown or launched
- throw_type(lnchClass, lnchType, wepClass, wepType, launched, thrown);
-
+ const launch_retval projected = is_launched(&you, you.weapon(), item);
+
// extract launcher bonuses due to magic
- if (launched)
+ if (projected == LRET_LAUNCHED)
{
lnchHitBonus = you.inv[you.equip[EQ_WEAPON]].plus;
lnchDamBonus = you.inv[you.equip[EQ_WEAPON]].plus2;
@@ -1498,7 +1531,7 @@ bool throw_it(struct bolt &pbolt, int throw_2, bool teleport, int acc_bonus)
ammoDamBonus = item.plus2;
// CALCULATIONS FOR LAUNCHED WEAPONS
- if (launched)
+ if (projected == LRET_LAUNCHED)
{
const item_def &launcher = you.inv[you.equip[EQ_WEAPON]];
const int bow_brand = get_weapon_brand( launcher );
@@ -1612,7 +1645,11 @@ bool throw_it(struct bolt &pbolt, int throw_2, bool teleport, int acc_bonus)
// 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;
+
+ // Sling bullets are designed for slinging and easier to aim.
+ if (wepType == MI_SLING_BULLET)
+ baseHit += 4;
+
exHitBonus += (effSkill * 3) / 2;
// strength is good if you're using a nice sling.
@@ -1792,14 +1829,13 @@ bool throw_it(struct bolt &pbolt, int throw_2, bool teleport, int acc_bonus)
more();
you.wield_change = true;
}
-
}
// CALCULATIONS FOR THROWN WEAPONS
- if (thrown)
+ if (projected == LRET_THROWN)
{
returning = (get_weapon_brand(item) == SPWPN_RETURNING &&
- !one_chance_in(you.skills[SK_RANGED_COMBAT]+1));
+ !one_chance_in(1 + skill_bump(SK_RANGED_COMBAT)));
baseHit = 0;
// since darts/rocks are missiles, they only use inv_plus
@@ -1808,7 +1844,8 @@ bool throw_it(struct bolt &pbolt, int throw_2, bool teleport, int acc_bonus)
// all weapons that use 'throwing' go here..
if (wepClass == OBJ_WEAPONS
- || (wepClass == OBJ_MISSILES && wepType == MI_STONE))
+ || (wepClass == OBJ_MISSILES
+ && (wepType == MI_STONE || wepType == MI_SLING_BULLET)))
{
// elves with elven weapons
if (get_equip_race(item) == ISFLAG_ELVEN
@@ -1848,26 +1885,51 @@ bool throw_it(struct bolt &pbolt, int throw_2, bool teleport, int acc_bonus)
exDamBonus = (exDamBonus * (3 * baseDam + ammoDamBonus)) / 30;
}
- if (wepClass == OBJ_MISSILES && wepType == MI_DART)
+ if (wepClass == OBJ_MISSILES)
{
- // give an appropriate 'tohit' & damage
- baseHit = 2;
- baseDam = property( item, PWPN_DAMAGE );
-
- exHitBonus = you.skills[SK_DARTS] * 2;
- 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));
+ switch (wepType)
+ {
+ case MI_DART:
+ // give an appropriate 'tohit' & damage
+ baseHit = 2;
+ baseDam = property( item, PWPN_DAMAGE );
+
+ exHitBonus = you.skills[SK_DARTS] * 2;
+ 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));
+ break;
+ case MI_JAVELIN:
+ // Javelins use polearm and throwing skills.
+ baseHit = -1;
+ baseDam = property( item, PWPN_DAMAGE );
+ exHitBonus += (skill_bump(SK_RANGED_COMBAT) * 3
+ + skill_bump(SK_POLEARMS));
+ exDamBonus += you.skills[SK_RANGED_COMBAT] / 5;
+ exDamBonus += you.skills[SK_POLEARMS] * 2 / 5;
+
+ // Adjust for strength and dex.
+ exDamBonus = str_adjust_thrown_damage(exDamBonus);
+ exHitBonus = dex_adjust_thrown_tohit(exHitBonus);
+
+ // High dex helps damage a bit, too (aim for weak spots).
+ exDamBonus = stat_adjust(exDamBonus, you.dex, 20, 150, 100);
+
+ // exercise skills
+ exercise(SK_POLEARMS, 1 + random2avg(4, 2));
+ break;
+ }
}
// [dshaligram] The defined base damage applies only when used
// for launchers. Hand-thrown stones and darts do only half
// base damage. Yet another evil 4.0ism.
if (wepClass == OBJ_MISSILES
- && (wepType == MI_DART || wepType == MI_STONE))
+ && (wepType == MI_DART || wepType == MI_STONE
+ || wepType == MI_SLING_BULLET))
baseDam = div_rand_round(baseDam, 2);
// exercise skill
@@ -1886,7 +1948,7 @@ bool throw_it(struct bolt &pbolt, int throw_2, bool teleport, int acc_bonus)
}
// range, dexterity bonus, possible skill increase for silly throwing
- if (thrown || launched)
+ if (projected)
{
if (wepType == MI_LARGE_ROCK)
{
@@ -1904,7 +1966,7 @@ bool throw_it(struct bolt &pbolt, int throw_2, bool teleport, int acc_bonus)
exHitBonus += you.dex / 2;
// slaying bonuses
- if (!(launched && wepType == MI_NEEDLE))
+ if (projected != LRET_LAUNCHED || wepType != MI_NEEDLE)
{
slayDam = slaying_bonus(PWPN_DAMAGE);
slayDam = slayDam < 0? -random2(1 - slayDam)
@@ -1961,7 +2023,7 @@ bool throw_it(struct bolt &pbolt, int throw_2, bool teleport, int acc_bonus)
pbolt.damage.size += slayDam;
// only add bonuses if we're throwing something sensible
- if (thrown || launched || wepClass == OBJ_WEAPONS)
+ if (projected || wepClass == OBJ_WEAPONS)
{
pbolt.hit += ammoHitBonus + lnchHitBonus;
pbolt.damage.size += ammoDamBonus + lnchDamBonus;
@@ -1981,7 +2043,7 @@ bool throw_it(struct bolt &pbolt, int throw_2, bool teleport, int acc_bonus)
#endif
// create message
- mprf( "You %s %s.", launched ? "shoot" : "throw",
+ mprf( "You %s %s.", projected == LRET_LAUNCHED ? "shoot" : "throw",
item.name(DESC_NOCAP_A).c_str() );
// ensure we're firing a 'missile'-type beam
@@ -2014,7 +2076,7 @@ bool throw_it(struct bolt &pbolt, int throw_2, bool teleport, int acc_bonus)
dec_inv_item_quantity( throw_2, 1 );
// throwing and blowguns are silent
- if (launched && lnchType != WPN_BLOWGUN)
+ if (projected == LRET_LAUNCHED && lnchType != WPN_BLOWGUN)
noisy( 6, you.x_pos, you.y_pos );
// but any monster nearby can see that something has been thrown: