summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authordolorous <dolorous@c06c8d41-db1a-0410-9941-cceddc491573>2007-12-08 18:28:38 +0000
committerdolorous <dolorous@c06c8d41-db1a-0410-9941-cceddc491573>2007-12-08 18:28:38 +0000
commit60bdc5258f24366aa9031738183841edafc8572b (patch)
treecffdcbe6cef4efd9d18e3f203e21cb67d075d8ad /crawl-ref
parente9c382cd386ff8f33a2927af3a7c6690abc9fdae (diff)
downloadcrawl-ref-60bdc5258f24366aa9031738183841edafc8572b.tar.gz
crawl-ref-60bdc5258f24366aa9031738183841edafc8572b.zip
Implement the returning brand for ammunition. This mostly uses the same
code as weapons of returning, but such ammunition has the same chance of being randomly destroyed when thrown as non-returning ammunition. Note that the brand is not actually generated anywhere yet. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3024 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/beam.cc68
-rw-r--r--crawl-ref/source/describe.cc4
-rw-r--r--crawl-ref/source/item_use.cc66
-rw-r--r--crawl-ref/source/item_use.h2
-rw-r--r--crawl-ref/source/itemname.cc3
-rw-r--r--crawl-ref/source/itemprop.h3
-rw-r--r--crawl-ref/source/mstuff2.cc36
-rw-r--r--crawl-ref/source/mstuff2.h3
8 files changed, 129 insertions, 56 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index 4e91ca5dfa..9ea7595ec6 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -39,6 +39,7 @@
#include "delay.h"
#include "effects.h"
#include "enum.h"
+#include "item_use.h"
#include "it_use2.h"
#include "items.h"
#include "itemname.h"
@@ -2433,62 +2434,25 @@ void beam_drop_object( bolt &beam, item_def *item, int x, int y )
if (beam.is_tracer || beam.flavour != BEAM_MISSILE)
return;
- if ( grid_destroys_items(grd[x][y]) )
+ if ((YOU_KILL(beam.thrower) &&
+ !thrown_object_destroyed(item, x, y, false)) ||
+ (MON_KILL(beam.thrower) &&
+ !mons_thrown_object_destroyed(item, x, y, false,
+ beam.beam_source)))
{
- // Too much message spam otherwise
- if ( YOU_KILL(beam.thrower) && player_can_hear(x, y) )
- mprf(MSGCH_SOUND, grid_item_destruction_message(grd[x][y]));
-
- item_was_destroyed(*item, beam.beam_source);
- return;
- }
-
- // doesn't get destroyed by throwing
- if (item->sub_type == MI_THROWING_NET)
- {
- // player or monster on position is caught in net
- if (you.x_pos == x && you.y_pos == y && you.attribute[ATTR_HELD]
- || mgrd[x][y] != NON_MONSTER && mons_is_caught(&menv[mgrd[x][y]]))
+ if (item->sub_type == MI_THROWING_NET)
{
- // if no trapping net found mark this one
- if (get_trapping_net(x,y, true) == NON_ITEM)
- set_item_stationary(*item);
- }
-
- copy_item_to_grid( *item, x, y, 1 );
- return;
- }
-
- if (YOU_KILL(beam.thrower)) // you threw it
- {
- int chance;
-
- // [dshaligram] Removed influence of Throwing on ammo preservation.
- // The effect is nigh impossible to perceive.
- switch (item->sub_type)
- {
- case MI_NEEDLE:
- chance = (get_ammo_brand(*item) == SPMSL_CURARE? 3 : 6);
- break;
- case MI_SLING_BULLET:
- case MI_STONE: chance = 4; break;
- case MI_DART: chance = 3; break;
- case MI_ARROW: chance = 4; break;
- case MI_BOLT: chance = 4; break;
- case MI_JAVELIN: chance = 10; break;
-
- case MI_LARGE_ROCK:
- default:
- chance = 25;
- break;
+ // player or monster on position is caught in net
+ if (you.x_pos == x && you.y_pos == y && you.attribute[ATTR_HELD]
+ || mgrd[x][y] != NON_MONSTER &&
+ mons_is_caught(&menv[mgrd[x][y]]))
+ {
+ // if no trapping net found mark this one
+ if (get_trapping_net(x,y, true) == NON_ITEM)
+ set_item_stationary(*item);
+ }
}
- if (item->base_type != OBJ_MISSILES || !one_chance_in(chance))
- copy_item_to_grid( *item, x, y, 1 );
- }
- else if (MON_KILL(beam.thrower)
- && (item->base_type != OBJ_MISSILES || coinflip()))
- {
copy_item_to_grid( *item, x, y, 1 );
}
}
diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc
index 252d04042b..2013187ce3 100644
--- a/crawl-ref/source/describe.cc
+++ b/crawl-ref/source/describe.cc
@@ -1399,6 +1399,10 @@ static std::string describe_ammo( const item_def &item )
case SPMSL_CURARE:
description += "$It is tipped with asphyxiating poison. ";
break;
+ case SPMSL_RETURNING:
+ description += "$A skilled user can throw it in such a way "
+ "that it will return to its owner. ";
+ break;
}
}
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index 3e62c8f41f..6abc5a71ea 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -2068,8 +2068,10 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus,
// CALCULATIONS FOR THROWN WEAPONS
if (projected == LRET_THROWN)
{
- returning = (get_weapon_brand(item) == SPWPN_RETURNING && !teleport &&
- !one_chance_in(1 + skill_bump(SK_THROWING)));
+ returning = ((get_weapon_brand(item) == SPWPN_RETURNING ||
+ get_ammo_brand(item) == SPMSL_RETURNING) &&
+ !teleport &&
+ !one_chance_in(1 + skill_bump(SK_THROWING)));
baseHit = 0;
// missiles only use inv_plus
@@ -2348,6 +2350,13 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus,
{
// Dropping item copy, since the launched item might be different.
fire_beam(pbolt, returning ? NULL : &item);
+
+ // The item can be destroyed before returning.
+ if (returning && thrown_object_destroyed(&item, pbolt.target_x,
+ pbolt.target_y, true))
+ {
+ returning = false;
+ }
}
if ( returning )
@@ -2379,6 +2388,59 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus,
return (hit);
} // end throw_it()
+bool thrown_object_destroyed( item_def *item, int x, int y, bool returning )
+{
+ ASSERT( item != NULL );
+
+ int chance = 0;
+ bool destroyed = false;
+ bool hostile_grid = false;
+
+ if (item->base_type == OBJ_MISSILES)
+ {
+ // [dshaligram] Removed influence of Throwing on ammo preservation.
+ // The effect is nigh impossible to perceive.
+ switch (item->sub_type)
+ {
+ case MI_NEEDLE:
+ chance = (get_ammo_brand(*item) == SPMSL_CURARE ? 3 : 6);
+ break;
+ case MI_SLING_BULLET:
+ case MI_STONE: chance = 4; break;
+ case MI_DART: chance = 3; break;
+ case MI_ARROW: chance = 4; break;
+ case MI_BOLT: chance = 4; break;
+ case MI_JAVELIN: chance = 10; break;
+ case MI_THROWING_NET: break; // doesn't get destroyed by throwing
+
+ case MI_LARGE_ROCK:
+ default:
+ chance = 25;
+ break;
+ }
+ }
+
+ destroyed = (chance == 0) ? false : one_chance_in(chance);
+ hostile_grid = grid_destroys_items(grd[x][y]);
+
+ // Non-returning items thrown into item-destroying grids are always
+ // destroyed. Returning items are only destroyed if they would have
+ // been randomly destroyed anyway.
+ if (returning && !destroyed)
+ hostile_grid = false;
+
+ if (hostile_grid)
+ {
+ if (player_can_hear(x, y))
+ mprf(MSGCH_SOUND, grid_item_destruction_message(grd[x][y]));
+
+ item_was_destroyed(*item, NON_MONSTER);
+ destroyed = true;
+ }
+
+ return destroyed;
+}
+
void jewellery_wear_effects(item_def &item)
{
item_type_id_state_type ident = ID_TRIED_TYPE;
diff --git a/crawl-ref/source/item_use.h b/crawl-ref/source/item_use.h
index f38953bb12..e191c6833d 100644
--- a/crawl-ref/source/item_use.h
+++ b/crawl-ref/source/item_use.h
@@ -170,6 +170,8 @@ bool enchant_weapon( enchant_stat_type which_stat, bool quiet = false );
bool throw_it(bolt &pbolt, int throw_2, bool teleport=false, int acc_bonus=0,
dist *target = NULL);
+bool thrown_object_destroyed( item_def *item, int x, int y, bool returning );
+
void inscribe_item();
int launcher_shield_slowdown(const item_def &launcher,
const item_def *shield);
diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc
index cbcee48703..394a1c7160 100644
--- a/crawl-ref/source/itemname.cc
+++ b/crawl-ref/source/itemname.cc
@@ -1118,6 +1118,9 @@ std::string item_def::name_aux( description_level_type desc,
case SPMSL_POISONED:
case SPMSL_CURARE:
break;
+ case SPMSL_RETURNING:
+ buff << ((terse) ? " (return)" : " of returning");
+ break;
default:
buff << " (buggy)";
}
diff --git a/crawl-ref/source/itemprop.h b/crawl-ref/source/itemprop.h
index 6616236128..4c5763afe9 100644
--- a/crawl-ref/source/itemprop.h
+++ b/crawl-ref/source/itemprop.h
@@ -354,7 +354,8 @@ enum special_missile_type // to separate from weapons in general {dlb}
SPMSL_ICE, // 2
SPMSL_POISONED, // 3
SPMSL_POISONED_II, // 4 - unused
- SPMSL_CURARE // 5
+ SPMSL_CURARE, // 5
+ SPMSL_RETURNING // 6
};
enum special_ring_type // jewellery mitm[].special values
diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc
index f8a5140bf5..487db44742 100644
--- a/crawl-ref/source/mstuff2.cc
+++ b/crawl-ref/source/mstuff2.cc
@@ -1085,7 +1085,8 @@ bool mons_throw(struct monsters *monster, struct bolt &pbolt, int hand_used)
// XXX: ugly hack, but avoids adding dynamic allocation to this code
char throw_buff[ ITEMNAME_SIZE ];
- bool returning = (get_weapon_brand(mitm[hand_used]) == SPWPN_RETURNING);
+ bool returning = (get_weapon_brand(mitm[hand_used]) == SPWPN_RETURNING ||
+ get_ammo_brand(mitm[hand_used]) == SPMSL_RETURNING);
int baseHit = 0, baseDam = 0; // from thrown or ammo
int ammoHitBonus = 0, ammoDamBonus = 0; // from thrown or ammo
@@ -1418,6 +1419,14 @@ bool mons_throw(struct monsters *monster, struct bolt &pbolt, int hand_used)
fire_beam( pbolt, really_returns ? NULL : &item );
+ // The item can be destroyed before returning.
+ if (really_returns && mons_thrown_object_destroyed(&item, pbolt.target_x,
+ pbolt.target_y, true,
+ pbolt.beam_source))
+ {
+ really_returns = false;
+ }
+
if ( really_returns )
{
// Fire beam in reverse
@@ -1441,6 +1450,31 @@ bool mons_throw(struct monsters *monster, struct bolt &pbolt, int hand_used)
return (true);
} // end mons_throw()
+bool mons_thrown_object_destroyed( item_def *item, int x, int y,
+ bool returning, int midx )
+{
+ ASSERT( item != NULL );
+
+ bool destroyed = ((item->base_type != OBJ_MISSILES ||
+ item->sub_type != MI_THROWING_NET) && coinflip());
+ bool hostile_grid = grid_destroys_items(grd[x][y]);
+
+ // Non-returning items thrown into item-destroying grids are always
+ // destroyed. Returning items are only destroyed if they would have
+ // been randomly destroyed anyway.
+ if (returning && !destroyed)
+ hostile_grid = false;
+
+ if (hostile_grid)
+ {
+ // No destruction sound here. Too much message spam otherwise.
+ item_was_destroyed(*item, midx);
+ destroyed = true;
+ }
+
+ return destroyed;
+}
+
// should really do something about mons_hit, but can't be bothered
void spore_goes_pop(struct monsters *monster)
{
diff --git a/crawl-ref/source/mstuff2.h b/crawl-ref/source/mstuff2.h
index 25cc10a3bf..ac2877a041 100644
--- a/crawl-ref/source/mstuff2.h
+++ b/crawl-ref/source/mstuff2.h
@@ -65,6 +65,9 @@ void setup_mons_cast(const monsters *monster, bolt &pbolt, int spell_cast);
* *********************************************************************** */
bool mons_throw(struct monsters *monster, struct bolt &pbolt, int hand_used);
+bool mons_thrown_object_destroyed( item_def *item, int x, int y,
+ bool returning, int midx );
+
// last updated 07jan2001 (gdl)
/* ***********************************************************************
* called from: monstuff