summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2007-08-20 22:22:04 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2007-08-20 22:22:04 +0000
commit037b6326b7b553ff7610b9ef70207aee35d9defa (patch)
tree3cff8782010bb1450e5a31c377a40066d3db6404 /crawl-ref/source
parent5b618acbca35621d699dc4ba3064f2a3228a5131 (diff)
downloadcrawl-ref-037b6326b7b553ff7610b9ef70207aee35d9defa.tar.gz
crawl-ref-037b6326b7b553ff7610b9ef70207aee35d9defa.zip
Throwing nets again.
Added a number of functions that allow to differentiate between a net that currently traps a monster and one that doesn't, even if they are on the same square. This usually works but can fail if there's already a net lying on the target square. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2021 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/acr.cc22
-rw-r--r--crawl-ref/source/beam.cc8
-rw-r--r--crawl-ref/source/enum.h4
-rw-r--r--crawl-ref/source/itemprop.cc18
-rw-r--r--crawl-ref/source/itemprop.h5
-rw-r--r--crawl-ref/source/items.cc6
-rw-r--r--crawl-ref/source/misc.cc98
-rw-r--r--crawl-ref/source/misc.h2
-rw-r--r--crawl-ref/source/mon-util.cc21
-rw-r--r--crawl-ref/source/monstuff.cc15
-rw-r--r--crawl-ref/source/mstuff2.cc5
-rw-r--r--crawl-ref/source/output.cc16
-rw-r--r--crawl-ref/source/player.cc3
-rw-r--r--crawl-ref/source/spells1.cc12
-rw-r--r--crawl-ref/source/spells4.cc9
15 files changed, 175 insertions, 69 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index 306a9ab252..ff03888328 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -1010,6 +1010,13 @@ static void go_upstairs()
return;
}
+
+ if (you.attribute[ATTR_CAUGHT])
+ {
+ mpr("You're trapped in a net!");
+ return;
+ }
+
if (ygrd == DNGN_ENTER_SHOP)
{
if ( you.duration[DUR_BERSERKER] )
@@ -1037,6 +1044,11 @@ static void go_downstairs()
return;
}
+ if (you.attribute[ATTR_CAUGHT])
+ {
+ mpr("You're trapped in a net!");
+ return;
+ }
tag_followers(); // only those beside us right now can follow
start_delay( DELAY_DESCENDING_STAIRS,
1 + (you.burden_state > BS_UNENCUMBERED),
@@ -1244,6 +1256,11 @@ void process_command( command_type cmd )
canned_msg(MSG_PRESENT_FORM);
break;
}
+ else if (you.attribute[ATTR_CAUGHT])
+ {
+ mpr("You cannot throw anything while trapped in a net!");
+ break;
+ }
if (Options.tutorial_left)
Options.tut_throw_counter++;
throw_anything();
@@ -1255,6 +1272,11 @@ void process_command( command_type cmd )
canned_msg(MSG_PRESENT_FORM);
break;
}
+ else if (you.attribute[ATTR_CAUGHT])
+ {
+ mpr("You cannot shoot anything while trapped in a net!");
+ break;
+ }
if (Options.tutorial_left)
Options.tut_throw_counter++;
shoot_thing();
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index 6cc016e777..134ae2709c 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -2393,6 +2393,14 @@ void beam_drop_object( bolt &beam, item_def *item, int x, int y )
if (item->sub_type == MI_THROWING_NET)
{
copy_item_to_grid( *item, x, y, 1 );
+
+ if (you.x_pos == x && you.y_pos == y && !you.attribute[ATTR_CAUGHT]
+ || mgrd[x][y] == NON_MONSTER || !mons_is_caught(&menv[mgrd[x][y]]))
+ {
+ return;
+ }
+
+ mark_net_trapping(x,y);
return;
}
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index fe0ed78ae7..cfffdf0567 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -1522,8 +1522,8 @@ enum item_status_flag_type // per item flags: ie. ident status, cursed status
ISFLAG_EQ_JEWELLERY_MASK = 0x0000000F, // mask of flags for known jewellery
ISFLAG_CURSED = 0x00000100, // cursed
- ISFLAG_RESERVED_1 = 0x00000200, // reserved
- ISFLAG_RESERVED_2 = 0x00000400, // reserved
+ ISFLAG_STATIONARY = 0x00000200, // cannot be picked up (traps)
+ ISFLAG_RESERVED_2 = 0x00000400, // reserved
ISFLAG_RESERVED_3 = 0x00000800, // reserved
ISFLAG_CURSE_MASK = 0x00000F00, // mask of all curse related flags
diff --git a/crawl-ref/source/itemprop.cc b/crawl-ref/source/itemprop.cc
index c2fa3e1f9a..4526448db4 100644
--- a/crawl-ref/source/itemprop.cc
+++ b/crawl-ref/source/itemprop.cc
@@ -452,6 +452,24 @@ void do_uncurse_item( item_def &item )
}
//
+// Is item stationary (cannot be picked up?)
+//
+void set_item_stationary( item_def &item )
+{
+ item.flags |= ISFLAG_STATIONARY;
+}
+
+void remove_item_stationary( item_def &item )
+{
+ item.flags &= (~ISFLAG_STATIONARY);
+}
+
+bool item_is_stationary( const item_def &item )
+{
+ return (item.flags & ISFLAG_STATIONARY);
+}
+
+//
// Item identification status:
//
bool item_ident( const item_def &item, unsigned long flags )
diff --git a/crawl-ref/source/itemprop.h b/crawl-ref/source/itemprop.h
index 35912509f7..7c051d0b70 100644
--- a/crawl-ref/source/itemprop.h
+++ b/crawl-ref/source/itemprop.h
@@ -26,6 +26,11 @@ bool item_known_uncursed( const item_def &item );
void do_curse_item( item_def &item );
void do_uncurse_item( item_def &item );
+// stationary:
+void set_item_stationary( item_def &item );
+void remove_item_stationary( item_def &item );
+bool item_is_stationary( const item_def &item );
+
// ident:
bool item_ident( const item_def &item, unsigned long flags );
void set_ident_flags( item_def &item, unsigned long flags );
diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc
index a33c1a41dc..495113a637 100644
--- a/crawl-ref/source/items.cc
+++ b/crawl-ref/source/items.cc
@@ -1302,12 +1302,10 @@ int find_free_slot(const item_def &i)
int move_item_to_player( int obj, int quant_got, bool quiet )
{
if (you.attribute[ATTR_CAUGHT] && mitm[obj].base_type == OBJ_MISSILES
- && mitm[obj].sub_type == MI_THROWING_NET)
+ && mitm[obj].sub_type == MI_THROWING_NET && item_is_stationary(mitm[obj]))
{
- quant_got--;
mpr("You cannot pick up the net that traps you!");
- if (!quant_got)
- return (1);
+ return (1);
}
int retval = quant_got;
diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc
index c62e5db7f5..1632e17a0f 100644
--- a/crawl-ref/source/misc.cc
+++ b/crawl-ref/source/misc.cc
@@ -812,6 +812,65 @@ void curare_hits_player(int agent, int degree)
}
}
+// returns the number of a net on a given square
+// if trapped only stationary ones are counted
+// otherwise the first net found is returned
+int get_trapping_net(int x, int y, bool trapped)
+{
+ int net, next;
+
+ for (net = igrd[x][y]; net != NON_ITEM; net = next)
+ {
+ next = mitm[net].link;
+
+ if (mitm[net].base_type == OBJ_MISSILES
+ && mitm[net].sub_type == MI_THROWING_NET
+ && (!trapped || item_is_stationary(mitm[net])))
+ {
+ return (net);
+ }
+ }
+ return (NON_ITEM);
+}
+
+// if there are more than one net on this square
+// split off one of them for checking/setting values
+static void maybe_split_nets(item_def &item, int x, int y)
+{
+ if (item.quantity == 1)
+ {
+ set_item_stationary(item);
+ return;
+ }
+
+ item_def it;
+
+ it.base_type = item.base_type;
+ it.sub_type = item.sub_type;
+ it.plus = item.plus;
+ it.plus2 = item.plus2;
+ it.flags = item.flags;
+ it.special = item.special;
+ it.quantity = --item.quantity;
+ item_colour(it);
+
+ item.quantity = 1;
+ set_item_stationary(item);
+
+ copy_item_to_grid( it, x, y );
+}
+
+void mark_net_trapping(int x, int y)
+{
+ int net = get_trapping_net(x,y);
+ if (net == NON_ITEM)
+ {
+ net = get_trapping_net(x,y, false);
+ if (net != NON_ITEM)
+ maybe_split_nets(mitm[net], x, y);
+ }
+}
+
void monster_caught_in_net(monsters *mon)
{
if (mon->body_size(PSIZE_BODY) >= SIZE_GIANT)
@@ -1704,6 +1763,9 @@ void handle_traps(char trt, int i, bool trap_known)
}
trap_item( OBJ_MISSILES, MI_THROWING_NET, env.trap[i].x, env.trap[i].y );
+ if (you.attribute[ATTR_CAUGHT])
+ mark_net_trapping(you.x_pos, you.y_pos);
+
grd[env.trap[i].x][env.trap[i].y] = DNGN_FLOOR;
env.trap[i].type = TRAP_UNASSIGNED;
}
@@ -1815,18 +1877,8 @@ void remove_net_from(monsters *mon)
{
you.turn_is_over = true;
- int net, next;
+ int net = get_trapping_net(mon->x, mon->y);
- for (net = igrd[mon->x][mon->y]; net != NON_ITEM; net = next)
- {
- next = mitm[net].link;
-
- if (mitm[net].base_type == OBJ_MISSILES
- && mitm[net].sub_type == MI_THROWING_NET)
- {
- break;
- }
- }
if (net == NON_ITEM)
{
mon->del_ench(ENCH_CAUGHT, true);
@@ -1853,11 +1905,9 @@ void remove_net_from(monsters *mon)
if (mitm[net].plus < -7)
{
mpr("Whoops! The net comes apart in your hands!");
- net_destroyed = true;
- dec_mitm_item_quantity( net, 1 );
-
mon->del_ench(ENCH_CAUGHT, true);
-
+ destroy_item(net);
+ net_destroyed = true;
}
}
@@ -1878,6 +1928,8 @@ void remove_net_from(monsters *mon)
}
mon->del_ench(ENCH_CAUGHT, true);
+ remove_item_stationary(mitm[net]);
+
if (player_monster_visible(mon))
mprf("You free %s.", mon->name(DESC_NOCAP_THE).c_str());
else
@@ -1887,17 +1939,7 @@ void remove_net_from(monsters *mon)
void free_self_from_net(bool damage_net)
{
- int net, next;
-
- for (net = igrd[you.x_pos][you.y_pos]; net != NON_ITEM; net = next)
- {
- next = mitm[net].link;
- if (mitm[net].base_type == OBJ_MISSILES
- && mitm[net].sub_type == MI_THROWING_NET)
- {
- break;
- }
- }
+ int net = get_trapping_net(you.x_pos, you.y_pos);
if (net == NON_ITEM) // really shouldn't happen!
{
@@ -1953,6 +1995,7 @@ void free_self_from_net(bool damage_net)
{
mpr("You break free from the net!");
you.attribute[ATTR_CAUGHT] = 0;
+ remove_item_stationary(mitm[net]);
return;
}
}
@@ -2245,7 +2288,8 @@ bool trap_item(object_class_type base_type, char sub_type,
// don't want to go overboard here. Will only generate up to three
// separate trap items, or less if there are other items present.
- if (mitm[ igrd[beam_x][beam_y] ].link != NON_ITEM)
+ if (mitm[ igrd[beam_x][beam_y] ].link != NON_ITEM
+ && (item.base_type != OBJ_MISSILES || item.sub_type != MI_THROWING_NET))
{
if (mitm[ mitm[ igrd[beam_x][beam_y] ].link ].link != NON_ITEM)
return (false);
diff --git a/crawl-ref/source/misc.h b/crawl-ref/source/misc.h
index c8ddf6ffee..4ad5afc033 100644
--- a/crawl-ref/source/misc.h
+++ b/crawl-ref/source/misc.h
@@ -62,6 +62,8 @@ bool fall_into_a_pool( int entry_x, int entry_y, bool allow_shift,
* called from: acr - misc
* *********************************************************************** */
void handle_traps(char trt, int i, bool trap_known);
+int get_trapping_net(int x, int y, bool trapped = true);
+void mark_net_trapping(int x, int y);
void monster_caught_in_net(monsters *mon);
void player_caught_in_net(void);
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index dd2a7b36d0..2c1c048aa3 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -3662,10 +3662,15 @@ void monsters::remove_enchantment_effect(const mon_enchant &me, bool quiet)
break;
case ENCH_CAUGHT:
+ {
+ int net = get_trapping_net(x,y);
+ if (net != NON_ITEM)
+ remove_item_stationary(mitm[net]);
+
if (!quiet)
simple_monster_message(this, " breaks free.");
break;
-
+ }
case ENCH_ABJ:
case ENCH_SHORT_LIVED:
add_ench( mon_enchant(ENCH_ABJ) );
@@ -3896,17 +3901,7 @@ void monsters::apply_enchantment(const mon_enchant &me)
if (mons_is_paralysed(this) || this->behaviour == BEH_SLEEP)
break;
- int net, next;
- for (net = igrd[x][y]; net != NON_ITEM; net = next)
- {
- next = mitm[net].link;
-
- if (mitm[net].base_type == OBJ_MISSILES
- && mitm[net].sub_type == MI_THROWING_NET)
- {
- break;
- }
- }
+ int net = get_trapping_net(x,y);
if (net == NON_ITEM) // really shouldn't happen!
{
@@ -3998,7 +3993,7 @@ void monsters::apply_enchantment(const mon_enchant &me)
mpr("All of a sudden the net rips apart!");
}
}
- dec_mitm_item_quantity( net, 1 );
+ destroy_item(net);
del_ench(ENCH_CAUGHT, true);
}
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index f722a5a23a..442a63333b 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -1171,18 +1171,9 @@ bool monster_polymorph( monsters *monster, monster_type targetc,
{
if (monster->body_size(PSIZE_BODY) >= SIZE_GIANT)
{
- int net, next;
- for (net = igrd[monster->x][monster->y]; net != NON_ITEM; net = next)
- {
- next = mitm[net].link;
-
- if (mitm[net].base_type == OBJ_MISSILES
- && mitm[net].sub_type == MI_THROWING_NET)
- {
- break;
- }
- }
- dec_mitm_item_quantity( net, 1 );
+ int net = get_trapping_net(monster->x, monster->y);
+ if (net != NON_ITEM)
+ destroy_item(net);
if (see_grid(monster->x, monster->y))
{
diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc
index 6aa6820bac..758e826cab 100644
--- a/crawl-ref/source/mstuff2.cc
+++ b/crawl-ref/source/mstuff2.cc
@@ -233,9 +233,12 @@ void mons_trap(struct monsters *monster)
monster_caught_in_net(monster);
}
}
-
trap_item( OBJ_MISSILES, MI_THROWING_NET,
env.trap[which_trap].x, env.trap[which_trap].y );
+
+ if (mons_is_caught(monster))
+ mark_net_trapping(monster->x, monster->y);
+
grd[env.trap[which_trap].x][env.trap[which_trap].y] = DNGN_FLOOR;
env.trap[which_trap].type = TRAP_UNASSIGNED;
break;
diff --git a/crawl-ref/source/output.cc b/crawl-ref/source/output.cc
index decafc3ccd..1ce982851a 100644
--- a/crawl-ref/source/output.cc
+++ b/crawl-ref/source/output.cc
@@ -1466,6 +1466,15 @@ std::string status_mut_abilities()
else if (!you.duration[DUR_HASTE] && you.duration[DUR_SWIFTNESS])
text += "swift, ";
+ if (you.disease
+ || you.species == SP_VAMPIRE && you.hunger_state < HS_HUNGRY)
+ {
+ text += "non-regenerating, ";
+ }
+
+ if (you.attribute[ATTR_CAUGHT])
+ text += "trapped, ";
+
const int mr = player_res_magic();
snprintf(info, INFO_SIZE, "%s resistant to magic, ",
(mr < 10) ? "not" :
@@ -1475,6 +1484,7 @@ std::string status_mut_abilities()
(mr < 120) ? "very" :
(mr < 140) ? "extremely" :
"incredibly");
+
text += info;
// character evaluates their ability to sneak around:
@@ -1493,12 +1503,6 @@ std::string status_mut_abilities()
text += info;
- if (you.disease
- || you.species == SP_VAMPIRE && you.hunger_state < HS_HUNGRY)
- {
- text += "non-regenerating";
- }
-
switch (you.attribute[ATTR_TRANSFORMATION])
{
case TRAN_SPIDER:
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index 2858bb44d1..a9386da1f0 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -3295,6 +3295,9 @@ void display_char_status()
if (player_is_levitating())
mpr( "You are hovering above the floor." );
+ if (you.attribute[ATTR_CAUGHT])
+ mpr( "You are trapped in a net." );
+
if (you.duration[DUR_POISONING])
{
mprf("You are %s poisoned.",
diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc
index 2ff342aa70..e44ca7b58c 100644
--- a/crawl-ref/source/spells1.cc
+++ b/crawl-ref/source/spells1.cc
@@ -118,7 +118,13 @@ int blink(int pow, bool high_level_controlled_blink)
else
{
if (you.attribute[ATTR_CAUGHT])
+ {
+ int net = get_trapping_net(you.x_pos, you.y_pos);
+ if (net != NON_ITEM)
+ remove_item_stationary(mitm[net]);
+
you.attribute[ATTR_CAUGHT] = 0;
+ }
move_player_to_grid(beam.tx, beam.ty, false, true, true);
@@ -169,7 +175,13 @@ void random_blink(bool allow_partial_control, bool override_abyss)
mpr("You blink.");
if (you.attribute[ATTR_CAUGHT])
+ {
+ int net = get_trapping_net(you.x_pos, you.y_pos);
+ if (net != NON_ITEM)
+ remove_item_stationary(mitm[net]);
+
you.attribute[ATTR_CAUGHT] = 0;
+ }
succ = true;
you.moveto(tx, ty);
diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc
index d1d7bf83f8..b5878d5094 100644
--- a/crawl-ref/source/spells4.cc
+++ b/crawl-ref/source/spells4.cc
@@ -2992,13 +2992,14 @@ int cast_apportation(int pow)
// if we apport a net, free the monster under it
if (mitm[item].base_type == OBJ_MISSILES
- && mitm[item].sub_type == MI_THROWING_NET)
+ && mitm[item].sub_type == MI_THROWING_NET
+ && item_is_stationary(mitm[item]))
{
int mon = mgrd[ beam.tx ][ beam.ty ];
- if (mon != NON_MONSTER && mons_is_caught(&menv[mon]))
- {
+ remove_item_stationary(mitm[item]);
+
+ if (mon != NON_MONSTER)
(&menv[mon])->del_ench(ENCH_CAUGHT, true);
- }
}
}
else