simplistic, and it's not currently possible to make a "baited" shaft; also, there is no threshold weight, so even a single dart will open up (and thus reveal) a shaft trap. Breaks savefile compatibility.
Monsters which fall through a shaft now show up 100% of the time on the player's next visit to the shaft's destination level. Also, the monster is placed close to the spot where the player would end up if s/he went through the same shaft.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2988 c06c8d41-db1a-0410-9941-cceddc491573
475LL4U4ND6PTNV4XKC7WQAOJC7RF2VCCVX3DRILP2PKIBFYWE6QC HRUS4XOL5WZ5C7IIAIXCAP765ZTWCSDQ2VVOBRNXYXGEJ5PRKC6AC S2LIBA2CLTZ6ZU66AUZ2CCNLCDOBSGWQGTZ6HFAFP2XSWAALGLSQC TFZ4TER7O2Z4FOGF2RCPEPYIHBTUA4LG3ECXLR7XGLCC6GO6OOTAC SVY2PTCLXR3KNPQAWXVXTTGCC5DR334HOAKHYO3VDDRWM2BWMALAC 7KWDC7XFNMBLSUO2HISIROBINZBX5T67LJEEXTAORXW2YZ7VWFGAC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC AVCMVFA3MKCXHO6H44UK5KJNIHTGQV7UA7GYXM26VI6TXXU5ZN6QC W5VEC2PBIM5DMU5233HOWAZUEPTGWJRZZIA3H35YYQQW6BTP6XUAC LEY3EZGTCBV6CYX4L727KQ4ZXL2LZLT5WESN3WAF65VRMX4EDP4QC PJ7HBIWAV3H23LXGZAAD2QYJ7HMOFOIR5ZJ4U2UTHI766LOTRRWQC EOMCPVNQLX3IMLC46EAO67DPBH5KEG2FQTPBLGU62HIRWA3UQ7XQC MSQI3TH6T62JAXQGLL52QZCWAMC372TGB6ZNNRDGUGMJKBNNV2VAC 2WRXQTGYDBLV46WRNVIUKGNA5QS563XZNNW3N2L6PVOCHIP2YGHQC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC RYT42Z6CED4KV5CCJ45CHZ3DQGLFMDCVH6CSQZNXOILULDG4MXVQC GBUB77EAYHOFY6GQ5IY3ZSBC7FSQFZZKYNBD5QMCQFIKFLYLWHOQC UZ6N6HOUPGVSPC5NQROEEDWMEGJA5XUWUY2AKH5QG65AZ25PVXDAC }level_id generic_shaft_dest(level_pos lpos){level_id lid = lpos.id;coord_def pos = lpos.pos;if (lid.level_type != LEVEL_DUNGEON)return lid;int curr_depth = lid.depth;Branch &branch = branches[lid.branch];lid.depth += ((pos.x + pos.y) % 3) + 1;if (lid.depth > branch.depth)lid.depth = branch.depth;if (lid.depth == curr_depth)return lid;// Only shafts on the level immediately above a dangerous branch// bottom will take you to that dangerous bottom, and shafts can't// be created during level generation time.if (branch.dangerous_bottom_level&& lid.depth == branch.depth&& (branch.depth - curr_depth) > 1){lid.depth--;}return lid;}level_id generic_shaft_dest(coord_def pos){return generic_shaft_dest(level_pos(level_id::current(), pos));}void handle_items_on_shaft(int x, int y, bool open_shaft){if (!is_valid_shaft_level())return;coord_def pos(x, y);level_id dest = generic_shaft_dest(pos);if (dest == level_id::current())return;int o = igrd(pos);if (o == NON_ITEM)return;igrd(pos) = NON_ITEM;if (is_terrain_seen(pos) && open_shaft){mpr("A shaft opens up in the floor!");grd(pos) = DNGN_TRAP_NATURAL;}while (o != NON_ITEM){int next = mitm[o].link;if (is_valid_item( mitm[o] )){if (is_terrain_seen(pos)){mprf("%s falls through the shaft.",mitm[o].name(DESC_INVENTORY).c_str());}add_item_to_transit(dest, mitm[o]);mitm[o].base_type = OBJ_UNASSIGNED;mitm[o].quantity = 0;mitm[o].props.clear();}o = next;}
if (you.level_type != LEVEL_DUNGEON)return level_id::current();level_id lev = level_id::current();int curr_depth = subdungeon_depth(you.where_are_you, you.your_level);lev.depth += ((pos().x + pos().y) % 3) + 1;if (lev.depth > your_branch().depth)lev.depth = your_branch().depth;if (lev.depth == curr_depth)return lev;// Only shafts on the level immediately above a dangerous branch// bottom will take you to that dangerous bottom, and shafts can't// be created during level generation time.if (your_branch().dangerous_bottom_level&& lev.depth == your_branch().depth&& (your_branch().depth - curr_depth) > 1){lev.depth--;}return lev;
return generic_shaft_dest(pos());
}static void cull_lost_items(i_transit_list &ilist, int how_many){// First pass, drop non-artifacts.for (i_transit_list::iterator i = ilist.begin(); i != ilist.end(); ){i_transit_list::iterator finger = i++;if (!is_artefact(*finger)){ilist.erase(finger);if (--how_many <= MAX_LOST)return;}}// Second pass, drop randarts.for (i_transit_list::iterator i = ilist.begin(); i != ilist.end(); ){i_transit_list::iterator finger = i++;if (is_random_artefact(*finger)){ilist.erase(finger);if (--how_many <= MAX_LOST)return;}}// Third pass, drop unrandarts.for (i_transit_list::iterator i = ilist.begin(); i != ilist.end(); ){i_transit_list::iterator finger = i++;if (is_unrandom_artefact(*finger)){ilist.erase(finger);if (--how_many <= MAX_LOST)return;}}// If we're still over the limit (unlikely), just lose// the old ones.while (how_many-- > MAX_LOST && !ilist.empty())ilist.erase( ilist.begin() );
}}void add_item_to_transit(const level_id &lid, const item_def &i){i_transit_list &ilist = transiting_items[lid];ilist.push_back(i);#ifdef DEBUG_DIAGNOSTICSmprf(MSGCH_DIAGNOSTICS, "Item in transit: %s",i.name(DESC_PLAIN).c_str());#endifconst int how_many = ilist.size();if (how_many > MAX_LOST)cull_lost_items(ilist, how_many);}void place_transiting_items(){level_id c = level_id::current();items_in_transit::iterator i = transiting_items.find(c);if (i == transiting_items.end())return;i_transit_list &ilist = i->second;i_transit_list keep;i_transit_list::iterator item;for (item = ilist.begin(); item != ilist.end(); item++){coord_def pos(item->x, item->y);if (!in_bounds(pos)){pos.x = random_range(X_BOUND_1 + 1, X_BOUND_2 - 1);pos.y = random_range(Y_BOUND_1 + 1, Y_BOUND_2 - 1);}const coord_def where_to_go =dgn_find_nearby_stair(DNGN_ROCK_STAIRS_DOWN, pos, true);// List of items we couldn't placeif (!copy_item_to_grid(*item, where_to_go.x, where_to_go.y))keep.push_back(*item);
if (m.find_place_to_live(near_player))
bool placed = false;// In certain instances (currently, falling through a shaft)// try to place monster a close as possible to its previous// <x,y> coordinates.if (!near_player && you.level_type == LEVEL_DUNGEON&& in_bounds(m.pos())){const coord_def where_to_go =dgn_find_nearby_stair(DNGN_ROCK_STAIRS_DOWN,m.pos(), true);if (monster_habitable_grid(&m, grd(where_to_go))){if (where_to_go == you.pos())near_player = true;else{mgrd[where_to_go.x][where_to_go.y] = monster_index(&m);placed = true;}}}if (!placed)placed = m.find_place_to_live(near_player);if (placed)