summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/beam.cc6
-rw-r--r--crawl-ref/source/beam.h4
-rw-r--r--crawl-ref/source/debug.cc7
-rw-r--r--crawl-ref/source/describe.cc5
-rw-r--r--crawl-ref/source/enum.h1
-rw-r--r--crawl-ref/source/externs.h2
-rw-r--r--crawl-ref/source/initfile.cc4
-rw-r--r--crawl-ref/source/item_use.cc54
-rw-r--r--crawl-ref/source/item_use.h2
-rw-r--r--crawl-ref/source/spells4.cc23
-rw-r--r--crawl-ref/source/spells4.h2
-rw-r--r--crawl-ref/source/spl-book.cc4
-rw-r--r--crawl-ref/source/spl-cast.cc5
-rw-r--r--crawl-ref/source/spl-data.h11
14 files changed, 91 insertions, 39 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index ad8ebf0fd8..3bd13ae45d 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -68,14 +68,12 @@ static int spready[] = { -1, 1, 0, 0 };
static int opdir[] = { 2, 1, 4, 3 };
static FixedArray < bool, 19, 19 > explode_map;
-// helper functions (some of these, esp. affect(), should probably
-// be public):
+// helper functions (some of these should probably be public):
static void sticky_flame_monster( int mn, kill_category who, int hurt_final );
static bool affects_wall(const bolt &beam, int wall_feature);
static bool isBouncy(bolt &beam, unsigned char gridtype);
static int beam_source(const bolt &beam);
static std::string beam_zapper(const bolt &beam);
-static void beam_drop_object( bolt &beam, item_def *item, int x, int y );
static bool beam_term_on_target(bolt &beam, int x, int y);
static void beam_explodes(bolt &beam, int x, int y);
static int affect_wall(bolt &beam, int x, int y);
@@ -2363,7 +2361,7 @@ static bool beam_term_on_target(bolt &beam, int x, int y)
return (false);
}
-static void beam_drop_object( bolt &beam, item_def *item, int x, int y )
+void beam_drop_object( bolt &beam, item_def *item, int x, int y )
{
ASSERT( item != NULL );
diff --git a/crawl-ref/source/beam.h b/crawl-ref/source/beam.h
index 1b7b164e18..3ba47b3abc 100644
--- a/crawl-ref/source/beam.h
+++ b/crawl-ref/source/beam.h
@@ -96,6 +96,8 @@ void mimic_alert( struct monsters *mimic );
void zapping( zap_type ztype, int power, struct bolt &pbolt );
-int affect(struct bolt &beam, int x, int y);
+int affect(bolt &beam, int x, int y);
+
+void beam_drop_object( bolt &beam, item_def *item, int x, int y );
#endif
diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc
index 1c84aaf047..35847b7c6a 100644
--- a/crawl-ref/source/debug.cc
+++ b/crawl-ref/source/debug.cc
@@ -1522,8 +1522,13 @@ static bool fsim_ranged_combat(FILE *out, int wskill, int mi,
mon.hit_points = mon.max_hit_points;
bolt beam;
you.time_taken = player_speed();
- if (throw_it(beam, thrown, &mon))
+
+ // throw_it() will decrease quantity by 1
+ inc_inv_item_quantity(thrown, 1);
+
+ if (throw_it(beam, thrown, true))
hits++;
+
you.hunger = hunger;
time_taken += you.time_taken;
diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc
index 1bb2ab3626..b7378bd2f4 100644
--- a/crawl-ref/source/describe.cc
+++ b/crawl-ref/source/describe.cc
@@ -4526,6 +4526,11 @@ void describe_spell(spell_type spelled)
"power will cause some of the items to be lost in the "
"infinite void.";
break;
+
+ case SPELL_PORTALED_PROJECTILE:
+ description += "teleports a missile directly to its target, "
+ "greatly increasing its accuracy (but not damage.)";
+ break;
default:
DEBUGSTR("Bad spell");
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 6452a0c2fd..7d3bdff599 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -3458,6 +3458,7 @@ enum spell_type
SPELL_CONJURE_BALL_LIGHTNING,
SPELL_CHAIN_LIGHTNING,
SPELL_EXCRUCIATING_WOUNDS,
+ SPELL_PORTALED_PROJECTILE,
// Mostly monster-only spells after this point:
SPELL_HELLFIRE_BURST, // 205
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index 25ce05cba4..7fb356ff5c 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -1553,7 +1553,7 @@ public:
// creating macros
int fire_items_start; // index of first item for fire command
- FixedVector<int, NUM_FIRE_TYPES> fire_order; // order for 'f' command
+ FixedVector<fire_type, NUM_FIRE_TYPES> fire_order; // order for 'f' command
bool auto_list; // automatically jump to appropriate item lists
diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc
index 3e48ec5640..86e169d2a9 100644
--- a/crawl-ref/source/initfile.cc
+++ b/crawl-ref/source/initfile.cc
@@ -243,7 +243,7 @@ std::string weapon_to_str( int weapon )
}
}
-static unsigned int str_to_fire_types( const std::string &str )
+static fire_type str_to_fire_types( const std::string &str )
{
if (str == "launcher")
return (FIRE_LAUNCHER);
@@ -264,7 +264,7 @@ static unsigned int str_to_fire_types( const std::string &str )
}
static void str_to_fire_order( const std::string &str,
- FixedVector< int, NUM_FIRE_TYPES > &list )
+ FixedVector< fire_type, NUM_FIRE_TYPES > &list )
{
int i;
size_t pos = 0;
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index 100077b5d4..d8fa35541e 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -1347,17 +1347,16 @@ static bool determines_ammo_brand(int bow_brand, int ammo_brand)
// throw_it - currently handles player throwing only. Monster
// throwing is handled in mstuff2:mons_throw()
-// Note: If dummy_target is non-NULL, throw_it fakes a bolt and calls
-// affect() on the monster's square.
+// Note: If teleport is true, assume that pbolt is already set up,
+// and teleport the projectile onto the square.
//
// Return value is only relevant if dummy_target is non-NULL, and returns
// true if dummy_target is hit.
-bool throw_it(struct bolt &pbolt, int throw_2, monsters *dummy_target)
+bool throw_it(struct bolt &pbolt, int throw_2, bool teleport, int acc_bonus)
{
struct dist thr;
char shoot_skill = 0;
- char wepClass, wepType; // ammo class and type
char lnchClass, lnchType; // launcher class and type
int baseHit = 0, baseDam = 0; // from thrown or ammo
@@ -1370,25 +1369,18 @@ bool throw_it(struct bolt &pbolt, int throw_2, monsters *dummy_target)
bool thrown = false; // item is sensible thrown item
int slayDam = 0;
- if (dummy_target)
- {
- thr.isValid = true;
- thr.isCancel = false;
- thr.tx = dummy_target->x;
- thr.ty = dummy_target->y;
- }
- else
+ if (!teleport)
{
message_current_target();
direction( thr, DIR_NONE, TARG_ENEMY );
- }
- if (!thr.isValid)
- {
- if (thr.isCancel)
- canned_msg(MSG_OK);
-
- return (false);
+ if (!thr.isValid)
+ {
+ if (thr.isCancel)
+ canned_msg(MSG_OK);
+
+ return (false);
+ }
}
// Must unwield before fire_beam() makes a copy in order to remove things
@@ -1415,7 +1407,8 @@ bool throw_it(struct bolt &pbolt, int throw_2, monsters *dummy_target)
// even though direction is allowed, we're throwing so we
// want to use tx, ty to make the missile fly to map edge.
- pbolt.set_target(thr);
+ if ( !teleport )
+ pbolt.set_target(thr);
pbolt.flavour = BEAM_MISSILE;
// pbolt.range is set below
@@ -1449,8 +1442,8 @@ bool throw_it(struct bolt &pbolt, int throw_2, monsters *dummy_target)
pbolt.aux_source.clear();
// get the ammo/weapon type. Convenience.
- wepClass = item.base_type;
- wepType = item.sub_type;
+ const object_class_type wepClass = item.base_type;
+ const int wepType = item.sub_type;
// get the launcher class,type. Convenience.
if (you.equip[EQ_WEAPON] < 0)
@@ -1964,6 +1957,9 @@ bool throw_it(struct bolt &pbolt, int throw_2, monsters *dummy_target)
pbolt.damage.size += ammoDamBonus + lnchDamBonus;
}
+ // Add in bonus (only from Portaled Projectile for now)
+ pbolt.hit += acc_bonus;
+
scale_dice( pbolt.damage );
#if DEBUG_DIAGNOSTICS
@@ -1988,15 +1984,21 @@ bool throw_it(struct bolt &pbolt, int throw_2, monsters *dummy_target)
item.flags |= ISFLAG_THROWN;
bool hit = false;
- // using copy, since the launched item might be differect (venom blowgun)
- if (dummy_target)
- hit = (affect( pbolt, dummy_target->x, dummy_target->y ) != 0);
+ if (teleport)
+ {
+ // Violating encapsulation somewhat...oh well.
+ hit = (affect( pbolt, pbolt.target_x, pbolt.target_y ) != 0);
+ beam_drop_object( pbolt, &item, pbolt.target_x, pbolt.target_y );
+ }
else
{
+ // Dropping item copy, since the launched item might be different
+ // (e.g. venom blowgun)
fire_beam( pbolt, &item );
- dec_inv_item_quantity( throw_2, 1 );
}
+ dec_inv_item_quantity( throw_2, 1 );
+
// throwing and blowguns are silent
if (launched && lnchType != WPN_BLOWGUN)
noisy( 6, you.x_pos, you.y_pos );
diff --git a/crawl-ref/source/item_use.h b/crawl-ref/source/item_use.h
index d177433c72..721ea9678b 100644
--- a/crawl-ref/source/item_use.h
+++ b/crawl-ref/source/item_use.h
@@ -137,7 +137,7 @@ bool puton_item(int slot, bool prompt_finger = true);
bool enchant_weapon( int which_stat, bool quiet = false );
-bool throw_it(struct bolt &pbolt, int throw_2, monsters *dummy_target = NULL);
+bool throw_it(bolt &pbolt, int throw_2, bool teleport=false, int acc_bonus=0);
void inscribe_item();
int launcher_shield_slowdown(const item_def &launcher,
diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc
index dc389c983f..0f25c9dee1 100644
--- a/crawl-ref/source/spells4.cc
+++ b/crawl-ref/source/spells4.cc
@@ -30,6 +30,7 @@
#include "dungeon.h"
#include "effects.h"
#include "it_use2.h"
+#include "item_use.h"
#include "itemname.h"
#include "itemprop.h"
#include "items.h"
@@ -2707,6 +2708,28 @@ void cast_twist(int pow)
return;
} // end cast_twist()
+bool cast_portaled_projectile(int pow, bolt& beam)
+{
+ if ( pow > 50 )
+ pow = 50;
+
+ if ( grid_is_solid(beam.target_x, beam.target_y) )
+ {
+ mpr("You can't shoot at gazebos.");
+ return false;
+ }
+
+ const int idx = get_fire_item_index();
+ if ( idx == ENDOFPACK )
+ {
+ mpr("No suitable missiles.");
+ return false;
+ }
+
+ throw_it( beam, idx, true, random2(pow/4) );
+ return true;
+}
+
//
// This version of far strike is a bit too creative for level one, in
// order to make it work we needed to put a lot of restrictions on it
diff --git a/crawl-ref/source/spells4.h b/crawl-ref/source/spells4.h
index 17ad71f76e..5429741883 100644
--- a/crawl-ref/source/spells4.h
+++ b/crawl-ref/source/spells4.h
@@ -60,6 +60,6 @@ void cast_shuggoth_seed(int powc);
void make_shuggoth(int x, int y, int hp);
int cast_semi_controlled_blink(int pow);
-
+bool cast_portaled_projectile(int pow, bolt& beam);
#endif
diff --git a/crawl-ref/source/spl-book.cc b/crawl-ref/source/spl-book.cc
index a4bc67ef4a..45dafb7a78 100644
--- a/crawl-ref/source/spl-book.cc
+++ b/crawl-ref/source/spl-book.cc
@@ -158,13 +158,13 @@ static spell_type spellbook_template_array[NUMBER_SPELLBOOKS][SPELLBOOK_SIZE] =
},
// 11 - Book of Spatial Translocations
{SPELL_APPORTATION,
+ SPELL_PORTALED_PROJECTILE,
SPELL_BLINK,
SPELL_RECALL,
SPELL_TELEPORT_OTHER,
SPELL_TELEPORT_SELF,
SPELL_CONTROL_TELEPORT,
SPELL_NO_SPELL,
- SPELL_NO_SPELL,
},
// 12 - Book of Enchantments (fourth one)
{SPELL_LEVITATION,
@@ -435,7 +435,7 @@ static spell_type spellbook_template_array[NUMBER_SPELLBOOKS][SPELLBOOK_SIZE] =
SPELL_NO_SPELL,
SPELL_NO_SPELL,
},
- // 37 - Book of Mutations //jmf: now Morphology
+ // 37 - Book of Morphology
{SPELL_FRAGMENTATION,
SPELL_POLYMORPH_OTHER,
SPELL_ALTER_SELF,
diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc
index ec26318882..9112404f9c 100644
--- a/crawl-ref/source/spl-cast.cc
+++ b/crawl-ref/source/spl-cast.cc
@@ -1793,6 +1793,11 @@ spret_type your_spells( spell_type spc2, int powc, bool allow_fail )
return (SPRET_ABORT);
break;
+ case SPELL_PORTALED_PROJECTILE:
+ if ( !cast_portaled_projectile(powc, beam) )
+ return SPRET_ABORT;
+ break;
+
default:
mpr("Invalid spell!");
break;
diff --git a/crawl-ref/source/spl-data.h b/crawl-ref/source/spl-data.h
index 1bb796bb13..2dea41640e 100644
--- a/crawl-ref/source/spl-data.h
+++ b/crawl-ref/source/spl-data.h
@@ -2160,6 +2160,17 @@
},
{
+ SPELL_PORTALED_PROJECTILE, "Portaled Projectile",
+ SPTYP_TRANSLOCATION,
+ SPFLAG_TARGET,
+ 2,
+ 50,
+ NULL,
+ false,
+ false
+},
+
+{
SPELL_STRIKING, "Striking",
0,
SPFLAG_DIR_OR_TARGET,