diff options
-rw-r--r-- | crawl-ref/source/acr.cc | 22 | ||||
-rw-r--r-- | crawl-ref/source/beam.cc | 8 | ||||
-rw-r--r-- | crawl-ref/source/enum.h | 4 | ||||
-rw-r--r-- | crawl-ref/source/itemprop.cc | 18 | ||||
-rw-r--r-- | crawl-ref/source/itemprop.h | 5 | ||||
-rw-r--r-- | crawl-ref/source/items.cc | 6 | ||||
-rw-r--r-- | crawl-ref/source/misc.cc | 98 | ||||
-rw-r--r-- | crawl-ref/source/misc.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 21 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 15 | ||||
-rw-r--r-- | crawl-ref/source/mstuff2.cc | 5 | ||||
-rw-r--r-- | crawl-ref/source/output.cc | 16 | ||||
-rw-r--r-- | crawl-ref/source/player.cc | 3 | ||||
-rw-r--r-- | crawl-ref/source/spells1.cc | 12 | ||||
-rw-r--r-- | crawl-ref/source/spells4.cc | 9 |
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 |