summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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