summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/misc.cc
diff options
context:
space:
mode:
authorzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2007-09-15 23:33:50 +0000
committerzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2007-09-15 23:33:50 +0000
commitfa763ba1bc7285247a5b1438d59633383a80cf6c (patch)
treef4b632fea66f43dc6c1415fdaa4feead0b6ff90d /crawl-ref/source/misc.cc
parent4d88632cb99d368956dec86732f7d275ffb941e8 (diff)
downloadcrawl-ref-fa763ba1bc7285247a5b1438d59633383a80cf6c.tar.gz
crawl-ref-fa763ba1bc7285247a5b1438d59633383a80cf6c.zip
Split off portions of externs.h and enum.h into other files. The
crawl_environment, player and monsters classes have been left in externs.h, which necessitates that all of the enums references by those classes stay in enums.h, since you can't forward declare an enum. However, it's a start. Also, portions of misc.{cc,h} have been split off into traps.{cc,h}, place.{cc,h} and terrain.{cc,h} git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2095 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/misc.cc')
-rw-r--r--crawl-ref/source/misc.cc1358
1 files changed, 10 insertions, 1348 deletions
diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc
index 3811cb6a61..4b3a6a8f4a 100644
--- a/crawl-ref/source/misc.cc
+++ b/crawl-ref/source/misc.cc
@@ -35,48 +35,42 @@
#endif
#include "externs.h"
+#include "misc.h"
#include "abyss.h"
#include "branch.h"
-#include "chardump.h"
-#include "cloud.h"
#include "clua.h"
+#include "cloud.h"
#include "delay.h"
#include "dgnevent.h"
-#include "fight.h"
+#include "direct.h"
+#include "dungeon.h"
#include "files.h"
#include "food.h"
-#include "hiscores.h"
#include "it_use2.h"
-#include "items.h"
#include "itemprop.h"
+#include "items.h"
#include "lev-pand.h"
-#include "macro.h"
-#include "makeitem.h"
-#include "mapmark.h"
-#include "monplace.h"
+#include "message.h"
#include "mon-util.h"
#include "monstuff.h"
-#include "mstuff2.h"
-#include "notes.h"
#include "ouch.h"
-#include "overmap.h"
+#include "place.h"
#include "player.h"
#include "religion.h"
#include "shopping.h"
#include "skills.h"
#include "skills2.h"
#include "spells3.h"
-#include "spl-cast.h"
+#include "stash.h"
#include "stuff.h"
+#include "terrain.h"
#include "transfor.h"
+#include "traps.h"
#include "travel.h"
#include "tutorial.h"
#include "view.h"
-bool scramble(void);
-static void dart_trap(bool trap_known, int trapped, bolt &pbolt, bool poison);
-
// void place_chunks(int mcls, unsigned char rot_status, unsigned char chx,
// unsigned char chy, unsigned char ch_col)
void turn_corpse_into_chunks( item_def &item )
@@ -151,246 +145,6 @@ void turn_corpse_into_chunks( item_def &item )
}
} // end place_chunks()
-bool grid_is_wall( dungeon_feature_type grid )
-{
- return (grid == DNGN_ROCK_WALL
- || grid == DNGN_STONE_WALL
- || grid == DNGN_METAL_WALL
- || grid == DNGN_GREEN_CRYSTAL_WALL
- || grid == DNGN_WAX_WALL
- || grid == DNGN_PERMAROCK_WALL);
-}
-
-bool grid_is_stone_stair(dungeon_feature_type grid)
-{
- switch (grid)
- {
- case DNGN_STONE_STAIRS_UP_I:
- case DNGN_STONE_STAIRS_UP_II:
- case DNGN_STONE_STAIRS_UP_III:
- case DNGN_STONE_STAIRS_DOWN_I:
- case DNGN_STONE_STAIRS_DOWN_II:
- case DNGN_STONE_STAIRS_DOWN_III:
- return (true);
- default:
- return (false);
- }
-}
-
-bool grid_is_rock_stair(dungeon_feature_type grid)
-{
- switch (grid)
- {
- case DNGN_ROCK_STAIRS_UP:
- case DNGN_ROCK_STAIRS_DOWN:
- return (true);
- default:
- return (false);
- }
-}
-
-bool grid_sealable_portal(dungeon_feature_type grid)
-{
- switch (grid)
- {
- case DNGN_ENTER_HELL:
- case DNGN_ENTER_ABYSS:
- case DNGN_ENTER_PANDEMONIUM:
- case DNGN_ENTER_LABYRINTH:
- case DNGN_ENTER_PORTAL_VAULT:
- return (true);
- default:
- return (false);
- }
-}
-
-bool grid_is_portal(dungeon_feature_type grid)
-{
- return (grid == DNGN_ENTER_PORTAL_VAULT || grid == DNGN_EXIT_PORTAL_VAULT);
-}
-
-command_type grid_stair_direction(dungeon_feature_type grid)
-{
- switch (grid)
- {
- case DNGN_STONE_STAIRS_UP_I:
- case DNGN_STONE_STAIRS_UP_II:
- case DNGN_STONE_STAIRS_UP_III:
- case DNGN_ROCK_STAIRS_UP:
- case DNGN_RETURN_FROM_ORCISH_MINES:
- case DNGN_RETURN_FROM_HIVE:
- case DNGN_RETURN_FROM_LAIR:
- case DNGN_RETURN_FROM_SLIME_PITS:
- case DNGN_RETURN_FROM_VAULTS:
- case DNGN_RETURN_FROM_CRYPT:
- case DNGN_RETURN_FROM_HALL_OF_BLADES:
- case DNGN_RETURN_FROM_ZOT:
- case DNGN_RETURN_FROM_TEMPLE:
- case DNGN_RETURN_FROM_SNAKE_PIT:
- case DNGN_RETURN_FROM_ELVEN_HALLS:
- case DNGN_RETURN_FROM_TOMB:
- case DNGN_RETURN_FROM_SWAMP:
- case DNGN_RETURN_FROM_SHOALS:
- case DNGN_RETURN_RESERVED_2:
- case DNGN_RETURN_RESERVED_3:
- case DNGN_RETURN_RESERVED_4:
- case DNGN_ENTER_SHOP:
- case DNGN_EXIT_HELL:
- case DNGN_EXIT_PORTAL_VAULT:
- return (CMD_GO_UPSTAIRS);
-
- case DNGN_ENTER_PORTAL_VAULT:
- case DNGN_ENTER_HELL:
- case DNGN_ENTER_LABYRINTH:
- case DNGN_STONE_STAIRS_DOWN_I:
- case DNGN_STONE_STAIRS_DOWN_II:
- case DNGN_STONE_STAIRS_DOWN_III:
- case DNGN_ROCK_STAIRS_DOWN:
- case DNGN_ENTER_DIS:
- case DNGN_ENTER_GEHENNA:
- case DNGN_ENTER_COCYTUS:
- case DNGN_ENTER_TARTARUS:
- case DNGN_ENTER_ABYSS:
- case DNGN_EXIT_ABYSS:
- case DNGN_ENTER_PANDEMONIUM:
- case DNGN_EXIT_PANDEMONIUM:
- case DNGN_TRANSIT_PANDEMONIUM:
- case DNGN_ENTER_ORCISH_MINES:
- case DNGN_ENTER_HIVE:
- case DNGN_ENTER_LAIR:
- case DNGN_ENTER_SLIME_PITS:
- case DNGN_ENTER_VAULTS:
- case DNGN_ENTER_CRYPT:
- case DNGN_ENTER_HALL_OF_BLADES:
- case DNGN_ENTER_ZOT:
- case DNGN_ENTER_TEMPLE:
- case DNGN_ENTER_SNAKE_PIT:
- case DNGN_ENTER_ELVEN_HALLS:
- case DNGN_ENTER_TOMB:
- case DNGN_ENTER_SWAMP:
- case DNGN_ENTER_SHOALS:
- case DNGN_ENTER_RESERVED_2:
- case DNGN_ENTER_RESERVED_3:
- case DNGN_ENTER_RESERVED_4:
- return (CMD_GO_DOWNSTAIRS);
-
- default:
- return (CMD_NO_CMD);
- }
-}
-
-bool grid_is_opaque( dungeon_feature_type grid )
-{
- return (grid < DNGN_MINSEE && grid != DNGN_ORCISH_IDOL);
-}
-
-bool grid_is_solid( dungeon_feature_type grid )
-{
- return (grid < DNGN_MINMOVE);
-}
-
-bool grid_is_solid( int x, int y )
-{
- return (grid_is_solid(grd[x][y]));
-}
-
-bool grid_is_solid(const coord_def &c)
-{
- return (grid_is_solid(grd(c)));
-}
-
-bool grid_is_trap(dungeon_feature_type grid)
-{
- return (grid == DNGN_TRAP_MECHANICAL || grid == DNGN_TRAP_MAGICAL
- || grid == DNGN_TRAP_III);
-}
-
-bool grid_is_water( dungeon_feature_type grid )
-{
- return (grid == DNGN_SHALLOW_WATER || grid == DNGN_DEEP_WATER);
-}
-
-bool grid_is_watery( dungeon_feature_type grid )
-{
- return (grid_is_water(grid) || grid == DNGN_BLUE_FOUNTAIN);
-}
-
-bool grid_destroys_items( dungeon_feature_type grid )
-{
- return (grid == DNGN_LAVA || grid == DNGN_DEEP_WATER);
-}
-
-// returns 0 if grid is not an altar, else it returns the GOD_* type
-god_type grid_altar_god( dungeon_feature_type grid )
-{
- if (grid >= DNGN_ALTAR_ZIN && grid <= DNGN_ALTAR_BEOGH)
- return (static_cast<god_type>( grid - DNGN_ALTAR_ZIN + 1 ));
-
- return (GOD_NO_GOD);
-}
-
-// returns DNGN_FLOOR for non-gods, otherwise returns the altar for
-// the god.
-dungeon_feature_type altar_for_god( god_type god )
-{
- if (god == GOD_NO_GOD || god >= NUM_GODS)
- return (DNGN_FLOOR); // Yeah, lame. Tell me about it.
-
- return static_cast<dungeon_feature_type>(DNGN_ALTAR_ZIN + god - 1);
-}
-
-bool grid_is_branch_stairs( dungeon_feature_type grid )
-{
- return ((grid >= DNGN_ENTER_ORCISH_MINES && grid <= DNGN_ENTER_RESERVED_4)
- || (grid >= DNGN_ENTER_DIS && grid <= DNGN_ENTER_TARTARUS));
-}
-
-int grid_secret_door_appearance( int gx, int gy )
-{
- int ret = DNGN_FLOOR;
-
- for (int dx = -1; dx <= 1; dx++)
- {
- for (int dy = -1; dy <= 1; dy++)
- {
- // only considering orthogonal grids
- if ((abs(dx) + abs(dy)) % 2 == 0)
- continue;
-
- const dungeon_feature_type targ = grd[gx + dx][gy + dy];
-
- if (!grid_is_wall( targ ))
- continue;
-
- if (ret == DNGN_FLOOR)
- ret = targ;
- else if (ret != targ)
- ret = ((ret < targ) ? ret : targ);
- }
- }
-
- return ((ret == DNGN_FLOOR) ? DNGN_ROCK_WALL
- : ret);
-}
-
-const char *grid_item_destruction_message( dungeon_feature_type grid )
-{
- return grid == DNGN_DEEP_WATER? "You hear a splash."
- : grid == DNGN_LAVA ? "You hear a sizzling splash."
- : "You hear a crunching noise.";
-}
-
-// Returns true if exits from this type of level involve going upstairs.
-bool level_type_exits_up(level_area_type type)
-{
- return (type == LEVEL_LABYRINTH || type == LEVEL_PORTAL_VAULT);
-}
-
-bool level_type_exits_down(level_area_type type)
-{
- return (type == LEVEL_PANDEMONIUM || type == LEVEL_ABYSS);
-}
-
void search_around( bool only_adjacent )
{
int i;
@@ -454,181 +208,6 @@ void search_around( bool only_adjacent )
return;
} // end search_around()
-static coord_def dgn_find_nearest_square(
- const coord_def &pos,
- bool (*acceptable)(const coord_def &),
- bool (*traversable)(const coord_def &) = NULL)
-{
- memset(travel_point_distance, 0, sizeof(travel_distance_grid_t));
-
- std::list<coord_def> points[2];
- int iter = 0;
- points[iter].push_back(pos);
-
- while (!points[iter].empty())
- {
- for (std::list<coord_def>::iterator i = points[iter].begin();
- i != points[iter].end(); ++i)
- {
- const coord_def &p = *i;
-
- if (p != pos && acceptable(p))
- return (p);
-
- travel_point_distance[p.x][p.y] = 1;
- for (int yi = -1; yi <= 1; ++yi)
- {
- for (int xi = -1; xi <= 1; ++xi)
- {
- if (!xi && !yi)
- continue;
-
- const coord_def np = p + coord_def(xi, yi);
- if (!in_bounds(np) || travel_point_distance[np.x][np.y])
- continue;
-
- if (traversable && !traversable(np))
- continue;
-
- points[!iter].push_back(np);
- }
- }
- }
-
- points[iter].clear();
- iter = !iter;
- }
-
- coord_def unfound;
- return (unfound);
-}
-
-static bool item_safe_square(const coord_def &pos)
-{
- const dungeon_feature_type feat = grd(pos);
- return (is_traversable(feat) && !grid_destroys_items(feat));
-}
-
-// Moves an item on the floor to the nearest adjacent floor-space.
-static bool dgn_shift_item(const coord_def &pos, item_def &item)
-{
- const coord_def np = dgn_find_nearest_square(pos, item_safe_square);
- if (in_bounds(np) && np != pos)
- {
- int index = item.index();
- move_item_to_grid(&index, np.x, np.y);
- return (true);
- }
- return (false);
-}
-
-static bool is_critical_feature(dungeon_feature_type feat)
-{
- return (grid_stair_direction(feat) != CMD_NO_CMD
- || grid_altar_god(feat) != GOD_NO_GOD);
-}
-
-static bool is_feature_shift_target(const coord_def &pos)
-{
- return (grd(pos) == DNGN_FLOOR && !dungeon_events.has_listeners_at(pos));
-}
-
-static bool dgn_shift_feature(const coord_def &pos)
-{
- const dungeon_feature_type dfeat = grd(pos);
- if (!is_critical_feature(dfeat) && !env.markers.find(pos, MAT_ANY))
- return (false);
-
- const coord_def dest =
- dgn_find_nearest_square(pos, is_feature_shift_target);
- if (in_bounds(dest) && dest != pos)
- {
- grd(dest) = dfeat;
-
- if (dfeat == DNGN_ENTER_SHOP)
- {
- if (shop_struct *s = get_shop(pos.x, pos.y))
- {
- s->x = dest.x;
- s->y = dest.y;
- }
- }
- env.markers.move(pos, dest);
- dungeon_events.move_listeners(pos, dest);
- }
- return (true);
-}
-
-static void dgn_check_terrain_items(const coord_def &pos, bool preserve_items)
-{
- const dungeon_feature_type grid = grd(pos);
- if (grid_is_solid(grid) || grid_destroys_items(grid))
- {
- int item = igrd(pos);
- bool did_destroy = false;
- while (item != NON_ITEM)
- {
- const int curr = item;
- item = mitm[item].link;
-
- // Game-critical item.
- if (preserve_items || item_is_critical(mitm[curr]))
- dgn_shift_item(pos, mitm[curr]);
- else
- {
- destroy_item(curr);
- did_destroy = true;
- }
- }
- if (did_destroy && player_can_hear(pos))
- mprf(MSGCH_SOUND, grid_item_destruction_message(grid));
- }
-}
-
-static void dgn_check_terrain_monsters(const coord_def &pos)
-{
- const int mindex = mgrd(pos);
- if (mindex != NON_MONSTER)
- {
- monsters *mons = &menv[mindex];
- if (grid_is_solid(grd(pos)))
- monster_teleport(mons, true, false);
- else
- mons_check_pool(mons, KILL_MISC, -1);
- }
-}
-
-void dungeon_terrain_changed(const coord_def &pos,
- dungeon_feature_type nfeat,
- bool affect_player,
- bool preserve_features,
- bool preserve_items)
-{
- if (nfeat != DNGN_UNSEEN)
- {
- if (preserve_features)
- dgn_shift_feature(pos);
- unnotice_feature(level_pos(level_id::current(), pos));
- grd(pos) = nfeat;
- env.grid_colours(pos) = BLACK;
- if (is_notable_terrain(nfeat) && see_grid(pos))
- seen_notable_thing(nfeat, pos.x, pos.y);
- }
-
- dgn_check_terrain_items(pos, preserve_items);
- if (affect_player && pos == you.pos())
- {
- if (!grid_is_solid(grd(pos)))
- {
- if (!you.flies())
- move_player_to_grid(pos.x, pos.y, false, true, false);
- }
- else
- you_teleport_now(true, false);
- }
- dgn_check_terrain_monsters(pos);
-}
-
void in_a_cloud()
{
int cl = env.cgrid[you.x_pos][you.y_pos];
@@ -817,133 +396,6 @@ 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, bolt &pbolt)
-{
- if (mon->body_size(PSIZE_BODY) >= SIZE_GIANT)
- return;
-
- if (mons_is_insubstantial(mon->type))
- {
- if (mons_near(mon) && player_monster_visible(mon))
- mprf("The net passes right through %s!", mon->name(DESC_NOCAP_THE).c_str());
- return;
- }
-
- const monsters* mons = static_cast<const monsters*>(mon);
- bool mon_flies = mons->flies();
- if (mon_flies && !mons_is_confused(mons))
- {
- simple_monster_message(mon, " darts out from under the net!");
- return;
- }
-
- if (mons->type == MONS_OOZE || mons->type == MONS_PULSATING_LUMP)
- {
- simple_monster_message(mon, " oozes right through the net!");
- return;
- }
-
- if (!mons_is_caught(mon) && mon->add_ench(ENCH_HELD))
- {
- if (mons_near(mon) && !player_monster_visible(mon))
- mpr("Something gets caught in the net!");
- else
- simple_monster_message(mon, " is caught in the net!");
-
- if (mon_flies)
- {
- simple_monster_message(mon, " falls like a stone!");
- mons_check_pool(mon, pbolt.killer(), pbolt.beam_source);
- }
- }
-}
-
-void player_caught_in_net()
-{
- if (you.body_size(PSIZE_BODY) >= SIZE_GIANT)
- return;
-
- if (you.flies() && !you.confused())
- {
- mpr("You dart out from under the net!");
- return;
- }
-
- if (!you.attribute[ATTR_HELD])
- {
- you.attribute[ATTR_HELD] = 10;
- mpr("You become entangled in the net!");
-
- // I guess levitation works differently, keeping both you
- // and the net hovering above the floor
- if (you.flies())
- {
- mpr("You fall like a stone!");
- fall_into_a_pool(you.x_pos, you.y_pos, false, grd[you.x_pos][you.y_pos]);
- }
- }
-
-}
-
void merfolk_start_swimming(void)
{
if (you.attribute[ATTR_TRANSFORMATION] != TRAN_NONE)
@@ -1619,449 +1071,6 @@ void new_level(void)
#endif
}
-static void dart_trap(bool trap_known, int trapped, bolt &pbolt, bool poison)
-{
- int damage_taken = 0;
- int trap_hit, your_dodge;
-
- if (one_chance_in(5) || (trap_known && !one_chance_in(4)))
- {
- mprf( "You avoid triggering a%s trap.", pbolt.name.c_str() );
- return;
- }
-
- if (you.equip[EQ_SHIELD] != -1 && one_chance_in(3))
- exercise( SK_SHIELDS, 1 );
-
- std::string msg = "A" + pbolt.name + " shoots out and ";
-
- if (random2( 20 + 5 * you.shield_blocks * you.shield_blocks )
- < player_shield_class())
- {
- you.shield_blocks++;
- msg += "hits your shield.";
- mpr(msg.c_str());
- }
- else
- {
- // note that this uses full ( not random2limit(foo,40) )
- // player_evasion.
- trap_hit = (20 + (you.your_level * 2)) * random2(200) / 100;
-
- your_dodge = player_evasion() + random2(you.dex) / 3
- - 2 + (you.duration[DUR_REPEL_MISSILES] * 10);
-
- if (trap_hit >= your_dodge && you.duration[DUR_DEFLECT_MISSILES] == 0)
- {
- msg += "hits you!";
- mpr(msg.c_str());
-
- if (poison && random2(100) < 50 - (3 * player_AC()) / 2
- && !player_res_poison())
- {
- poison_player( 1 + random2(3) );
- }
-
- damage_taken = roll_dice( pbolt.damage );
- damage_taken -= random2( player_AC() + 1 );
-
- if (damage_taken > 0)
- ouch( damage_taken, 0, KILLED_BY_TRAP, pbolt.name.c_str() );
- }
- else
- {
- msg += "misses you.";
- mpr(msg.c_str());
- }
-
- if (player_light_armour(true) && coinflip())
- exercise( SK_DODGING, 1 );
- }
-
- pbolt.target_x = you.x_pos;
- pbolt.target_y = you.y_pos;
-
- if (coinflip())
- itrap( pbolt, trapped );
-} // end dart_trap()
-
-//
-// itrap takes location from target_x, target_y of bolt strcture.
-//
-
-void itrap( struct bolt &pbolt, int trapped )
-{
- object_class_type base_type = OBJ_MISSILES;
- int sub_type = MI_DART;
-
- switch (env.trap[trapped].type)
- {
- case TRAP_DART:
- base_type = OBJ_MISSILES;
- sub_type = MI_DART;
- break;
- case TRAP_ARROW:
- base_type = OBJ_MISSILES;
- sub_type = MI_ARROW;
- break;
- case TRAP_BOLT:
- base_type = OBJ_MISSILES;
- sub_type = MI_BOLT;
- break;
- case TRAP_SPEAR:
- base_type = OBJ_WEAPONS;
- sub_type = WPN_SPEAR;
- break;
- case TRAP_AXE:
- base_type = OBJ_WEAPONS;
- sub_type = WPN_HAND_AXE;
- break;
- case TRAP_NEEDLE:
- base_type = OBJ_MISSILES;
- sub_type = MI_NEEDLE;
- break;
- case TRAP_NET:
- base_type = OBJ_MISSILES;
- sub_type = MI_THROWING_NET;
- break;
- default:
- return;
- }
-
- trap_item( base_type, sub_type, pbolt.target_x, pbolt.target_y );
-
- return;
-} // end itrap()
-
-void handle_traps(char trt, int i, bool trap_known)
-{
- struct bolt beam;
-
- switch (trt)
- {
- case TRAP_DART:
- beam.name = " dart";
- beam.damage = dice_def( 1, 4 + (you.your_level / 2) );
- dart_trap(trap_known, i, beam, false);
- break;
-
- case TRAP_NEEDLE:
- beam.name = " needle";
- beam.damage = dice_def( 1, 0 );
- dart_trap(trap_known, i, beam, true);
- break;
-
- case TRAP_ARROW:
- beam.name = "n arrow";
- beam.damage = dice_def( 1, 7 + you.your_level );
- dart_trap(trap_known, i, beam, false);
- break;
-
- case TRAP_BOLT:
- beam.name = " bolt";
- beam.damage = dice_def( 1, 13 + you.your_level );
- dart_trap(trap_known, i, beam, false);
- break;
-
- case TRAP_SPEAR:
- beam.name = " spear";
- beam.damage = dice_def( 1, 10 + you.your_level );
- dart_trap(trap_known, i, beam, false);
- break;
-
- case TRAP_AXE:
- beam.name = "n axe";
- beam.damage = dice_def( 1, 15 + you.your_level );
- dart_trap(trap_known, i, beam, false);
- break;
-
- case TRAP_TELEPORT:
- mpr("You enter a teleport trap!");
-
- if (scan_randarts(RAP_PREVENT_TELEPORTATION))
- mpr("You feel a weird sense of stasis.");
- else
- you_teleport_now( true );
- break;
-
- case TRAP_AMNESIA:
- mpr("You feel momentarily disoriented.");
- if (!wearing_amulet(AMU_CLARITY))
- forget_map(random2avg(100, 2));
- break;
-
- case TRAP_BLADE:
- if (trap_known && one_chance_in(3))
- mpr("You avoid triggering a blade trap.");
- else if (random2limit(player_evasion(), 40)
- + (random2(you.dex) / 3) + (trap_known ? 3 : 0) > 8)
- {
- mpr("A huge blade swings just past you!");
- }
- else
- {
- mpr("A huge blade swings out and slices into you!");
- ouch( (you.your_level * 2) + random2avg(29, 2)
- - random2(1 + player_AC()), 0, KILLED_BY_TRAP, " blade" );
- }
- break;
-
- case TRAP_NET:
-
- if (trap_known && one_chance_in(3))
- mpr("A net swings high above you.");
- else
- {
- if (random2limit(player_evasion(), 40)
- + (random2(you.dex) / 3) + (trap_known ? 3 : 0) > 12)
- {
- mpr("A net drops to the ground!");
- }
- else
- {
- mpr("A large net falls onto you!");
- player_caught_in_net();
- }
-
- trap_item( OBJ_MISSILES, MI_THROWING_NET, env.trap[i].x, env.trap[i].y );
- if (you.attribute[ATTR_HELD])
- 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;
- }
- break;
-
- case TRAP_ZOT:
- default:
- mpr((trap_known) ? "You enter the Zot trap."
- : "Oh no! You have blundered into a Zot trap!");
- miscast_effect( SPTYP_RANDOM, random2(30) + you.your_level,
- 75 + random2(100), 3, "a Zot trap" );
- break;
- }
- learned_something_new(TUT_SEEN_TRAP, you.x_pos, you.y_pos);
-} // end handle_traps()
-
-void disarm_trap( struct dist &disa )
-{
- if (you.duration[DUR_BERSERKER])
- {
- canned_msg(MSG_TOO_BERSERK);
- return;
- }
-
- int i, j;
-
- for (i = 0; i < MAX_TRAPS; i++)
- {
- if (env.trap[i].x == you.x_pos + disa.dx
- && env.trap[i].y == you.y_pos + disa.dy)
- {
- break;
- }
-
- if (i == MAX_TRAPS - 1)
- {
- mpr("Error - couldn't find that trap.");
- return;
- }
- }
-
- if (trap_category(env.trap[i].type) == DNGN_TRAP_MAGICAL)
- {
- mpr("You can't disarm that trap.");
- return;
- }
-
- if (random2(you.skills[SK_TRAPS_DOORS] + 2) <= random2(you.your_level + 5))
- {
- mpr("You failed to disarm the trap.");
-
- you.turn_is_over = true;
-
- if (random2(you.dex) > 5 + random2(5 + you.your_level))
- exercise(SK_TRAPS_DOORS, 1 + random2(you.your_level / 5));
- else
- {
- if (env.trap[i].type == TRAP_NET &&
- (env.trap[i].x != you.x_pos || env.trap[i].y != you.y_pos))
- {
- if (coinflip())
- return;
-
- mpr("You stumble into the trap!");
- move_player_to_grid( env.trap[i].x, env.trap[i].y, true, false, true);
- }
- else
- handle_traps(env.trap[i].type, i, false);
-
- if (coinflip())
- exercise(SK_TRAPS_DOORS, 1);
- }
-
- return;
- }
-
- mpr("You have disarmed the trap.");
-
- struct bolt beam;
-
- beam.target_x = you.x_pos + disa.dx;
- beam.target_y = you.y_pos + disa.dy;
-
- if (env.trap[i].type == TRAP_NET)
- trap_item( OBJ_MISSILES, MI_THROWING_NET, beam.target_x, beam.target_y );
- else if (env.trap[i].type != TRAP_BLADE
- && trap_category(env.trap[i].type) == DNGN_TRAP_MECHANICAL)
- {
- const int num_to_make = 10 + random2(you.skills[SK_TRAPS_DOORS]);
- for (j = 0; j < num_to_make; j++)
- {
- // places items (eg darts), which will automatically stack
- itrap(beam, i);
- }
- }
-
- grd[you.x_pos + disa.dx][you.y_pos + disa.dy] = DNGN_FLOOR;
- env.trap[i].type = TRAP_UNASSIGNED;
- you.turn_is_over = true;
-
- // reduced from 5 + random2(5)
- exercise(SK_TRAPS_DOORS, 1 + random2(5) + (you.your_level / 5));
-} // end disarm_trap()
-
-// attempts to take a net off a given monster
-// Do not expect gratitude for this!
-// ----------------------------------
-void remove_net_from(monsters *mon)
-{
- you.turn_is_over = true;
-
- int net = get_trapping_net(mon->x, mon->y);
-
- if (net == NON_ITEM)
- {
- mon->del_ench(ENCH_HELD, true);
- return;
- }
-
- // factor in whether monster is paralysed or invisible
- int paralys = 0;
- if (mons_is_paralysed(mon)) // makes this easier
- paralys = random2(5);
-
- int invis = 0;
- if (!player_monster_visible(mon)) // makes this harder
- invis = 3 + random2(5);
-
- bool net_destroyed = false;
- if ( random2(you.skills[SK_TRAPS_DOORS] + 2) + paralys
- <= random2( 2*mon->body_size(PSIZE_BODY) + 3 ) + invis)
- {
- if (one_chance_in(you.skills[SK_TRAPS_DOORS] + you.dex/2))
- {
- mitm[net].plus--;
- mpr("You tear at the net.");
- if (mitm[net].plus < -7)
- {
- mpr("Whoops! The net comes apart in your hands!");
- mon->del_ench(ENCH_HELD, true);
- destroy_item(net);
- net_destroyed = true;
- }
- }
-
- if (!net_destroyed)
- {
- if (player_monster_visible(mon))
- {
- mprf("You fail to remove the net from %s.",
- mon->name(DESC_NOCAP_THE).c_str());
- }
- else
- mpr("You fail to remove the net.");
- }
-
- if (random2(you.dex) > 5 + random2( 2*mon->body_size(PSIZE_BODY) ))
- exercise(SK_TRAPS_DOORS, 1 + random2(mon->body_size(PSIZE_BODY)/2));
- return;
- }
-
- mon->del_ench(ENCH_HELD, true);
- remove_item_stationary(mitm[net]);
-
- if (player_monster_visible(mon))
- mprf("You free %s.", mon->name(DESC_NOCAP_THE).c_str());
- else
- mpr("You loosen the net.");
-
-}
-
-void free_self_from_net(bool damage_net)
-{
- int net = get_trapping_net(you.x_pos, you.y_pos);
-
- if (net == NON_ITEM) // really shouldn't happen!
- {
- you.attribute[ATTR_HELD] = 0;
- return;
- }
- int hold = mitm[net].plus;
-
- if (damage_net)
- {
- mpr("You struggle against the net.");
- int damage = 1;
-
- // extra damage for cutting weapons
- if (you.equip[EQ_WEAPON] != -1
- && can_cut_meat(you.inv[you.equip[EQ_WEAPON]]))
- {
- damage++;
- }
-
- if (you.body_size(PSIZE_BODY) > SIZE_MEDIUM)
- damage++;
-
- if (hold < 0 && !one_chance_in(-hold/2))
- damage++;
-
- if (you.duration[DUR_BERSERKER])
- damage *= 2;
-
- mitm[net].plus -= damage;
-
- if (mitm[net].plus < -7)
- {
- mpr("You rip the net and break free!");
- dec_mitm_item_quantity( net, 1 );
-
- you.attribute[ATTR_HELD] = 0;
- return;
- }
- }
- else // you try to escape
- {
- mpr("You struggle to escape from the net.");
- you.attribute[ATTR_HELD]--;
-
- if (you.body_size(PSIZE_BODY) < SIZE_MEDIUM)
- you.attribute[ATTR_HELD]--;
-
- if (hold < 0 && !one_chance_in(-hold/2))
- you.attribute[ATTR_HELD]--;
-
- if (you.attribute[ATTR_HELD] <= 0)
- {
- mpr("You break free from the net!");
- you.attribute[ATTR_HELD] = 0;
- remove_item_stationary(mitm[net]);
- return;
- }
- }
-}
-
std::string weird_writing()
{
int temp_rand; // for probability determinations {dlb}
@@ -2121,114 +1130,6 @@ std::string weird_writing()
return result;
}
-// returns true if we manage to scramble free.
-bool fall_into_a_pool( int entry_x, int entry_y, bool allow_shift,
- unsigned char terrain )
-{
- bool escape = false;
- FixedVector< char, 2 > empty;
-
- if (you.species == SP_MERFOLK && terrain == DNGN_DEEP_WATER)
- {
- // These can happen when we enter deep water directly -- bwr
- merfolk_start_swimming();
- return (false);
- }
-
- // sanity check
- if (terrain != DNGN_LAVA && beogh_water_walk())
- return (false);
-
- mprf("You fall into the %s!",
- (terrain == DNGN_LAVA) ? "lava" :
- (terrain == DNGN_DEEP_WATER) ? "water"
- : "programming rift");
-
- more();
- mesclr();
-
- if (terrain == DNGN_LAVA)
- {
- const int resist = player_res_fire();
-
- if (resist <= 0)
- {
- mpr( "The lava burns you to a cinder!" );
- ouch( INSTANT_DEATH, 0, KILLED_BY_LAVA );
- }
- else
- {
- // should boost # of bangs per damage in the future {dlb}
- mpr( "The lava burns you!" );
- ouch( (10 + roll_dice(2,50)) / resist, 0, KILLED_BY_LAVA );
- }
-
- expose_player_to_element( BEAM_LAVA, 14 );
- }
-
- // a distinction between stepping and falling from you.duration[DUR_LEVITATION]
- // prevents stepping into a thin stream of lava to get to the other side.
- if (scramble())
- {
- if (allow_shift)
- {
- if (empty_surrounds( you.x_pos, you.y_pos, DNGN_FLOOR, 1,
- false, empty ))
- {
- escape = true;
- }
- else
- {
- escape = false;
- }
- }
- else
- {
- // back out the way we came in, if possible
- if (grid_distance( you.x_pos, you.y_pos, entry_x, entry_y ) == 1
- && (entry_x != empty[0] || entry_y != empty[1])
- && mgrd[entry_x][entry_y] == NON_MONSTER)
- {
- escape = true;
- empty[0] = entry_x;
- empty[1] = entry_y;
- }
- else // zero or two or more squares away, with no way back
- {
- escape = false;
- }
- }
- }
- else
- {
- mpr("You try to escape, but your burden drags you down!");
- }
-
- if (escape)
- {
- const coord_def pos(empty[0], empty[1]);
- if (in_bounds(pos) && !is_grid_dangerous(grd(pos)))
- {
- mpr("You manage to scramble free!");
- move_player_to_grid( empty[0], empty[1], false, false, true );
-
- if (terrain == DNGN_LAVA)
- expose_player_to_element( BEAM_LAVA, 14 );
-
- return (true);
- }
- }
-
- mpr("You drown...");
-
- if (terrain == DNGN_LAVA)
- ouch( INSTANT_DEATH, 0, KILLED_BY_LAVA );
- else if (terrain == DNGN_DEEP_WATER)
- ouch( INSTANT_DEATH, 0, KILLED_BY_WATER );
-
- return (false);
-} // end fall_into_a_pool()
-
bool scramble(void)
{
int max_carry = carrying_capacity();
@@ -2316,101 +1217,6 @@ bool go_berserk(bool intentional)
return true;
} // end go_berserk()
-bool trap_item(object_class_type base_type, char sub_type,
- char beam_x, char beam_y)
-{
- item_def item;
-
- item.base_type = base_type;
- item.sub_type = sub_type;
- item.plus = 0;
- item.plus2 = 0;
- item.flags = 0;
- item.special = 0;
- item.quantity = 1;
-
- if (base_type == OBJ_MISSILES)
- {
- if (sub_type == MI_NEEDLE)
- set_item_ego_type( item, OBJ_MISSILES, SPMSL_POISONED );
- else
- set_item_ego_type( item, OBJ_MISSILES, SPMSL_NORMAL );
- }
- else
- {
- set_item_ego_type( item, OBJ_WEAPONS, SPWPN_NORMAL );
- }
-
- item_colour(item);
-
- if (igrd[beam_x][beam_y] != NON_ITEM)
- {
- if (items_stack( item, mitm[ igrd[beam_x][beam_y] ] ))
- {
- inc_mitm_item_quantity( igrd[beam_x][beam_y], 1 );
- return (false);
- }
-
- // 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
- && (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);
- }
- } // end of if igrd != NON_ITEM
-
- return (!copy_item_to_grid( item, beam_x, beam_y, 1 ));
-} // end trap_item()
-
-// returns appropriate trap symbol for a given trap type {dlb}
-dungeon_feature_type trap_category(trap_type type)
-{
- switch (type)
- {
- case TRAP_TELEPORT:
- case TRAP_AMNESIA:
- case TRAP_ZOT:
- return (DNGN_TRAP_MAGICAL);
-
- case TRAP_DART:
- case TRAP_ARROW:
- case TRAP_SPEAR:
- case TRAP_AXE:
- case TRAP_BLADE:
- case TRAP_BOLT:
- case TRAP_NEEDLE:
- case TRAP_NET:
- default: // what *would* be the default? {dlb}
- return (DNGN_TRAP_MECHANICAL);
- }
-} // end trap_category()
-
-// returns index of the trap for a given (x,y) coordinate pair {dlb}
-int trap_at_xy(int which_x, int which_y)
-{
-
- for (int which_trap = 0; which_trap < MAX_TRAPS; which_trap++)
- {
- if (env.trap[which_trap].x == which_x &&
- env.trap[which_trap].y == which_y &&
- env.trap[which_trap].type != TRAP_UNASSIGNED)
- {
- return (which_trap);
- }
- }
-
- // no idea how well this will be handled elsewhere: {dlb}
- return (-1);
-} // end trap_at_xy()
-
-trap_type trap_type_at_xy(int x, int y)
-{
- const int idx = trap_at_xy(x, y);
- return (idx == -1? NUM_TRAPS : env.trap[idx].type);
-}
-
bool is_damaging_cloud(cloud_type type)
{
switch (type)
@@ -2559,150 +1365,6 @@ bool i_feel_safe(bool announce, bool want_move)
return true;
}
-// Do not attempt to use level_id if level_type != LEVEL_DUNGEON
-std::string short_place_name(level_id id)
-{
- return id.describe();
-}
-
-int place_branch(unsigned short place)
-{
- const unsigned branch = (unsigned) ((place >> 8) & 0xFF);
- const int lev = place & 0xFF;
- return lev == 0xFF? -1 : (int) branch;
-}
-
-int place_depth(unsigned short place)
-{
- const int lev = place & 0xFF;
- return lev == 0xFF? -1 : lev;
-}
-
-unsigned short get_packed_place( branch_type branch, int subdepth,
- level_area_type level_type )
-{
- unsigned short place = (unsigned short)
- ( (static_cast<int>(branch) << 8) | (subdepth & 0xFF) );
- if (level_type != LEVEL_DUNGEON)
- place = (unsigned short) ( (static_cast<int>(level_type) << 8) | 0xFF );
- return place;
-}
-
-unsigned short get_packed_place()
-{
- return get_packed_place( you.where_are_you,
- subdungeon_depth(you.where_are_you, you.your_level),
- you.level_type );
-}
-
-bool single_level_branch( branch_type branch )
-{
- return
- branch >= 0 && branch < NUM_BRANCHES
- && branches[branch].depth == 1;
-}
-
-std::string place_name( unsigned short place, bool long_name,
- bool include_number )
-{
-
- unsigned char branch = (unsigned char) ((place >> 8) & 0xFF);
- int lev = place & 0xFF;
-
- std::string result;
- if (lev == 0xFF)
- {
- switch (branch)
- {
- case LEVEL_ABYSS:
- return ( long_name ? "The Abyss" : "Abyss" );
- case LEVEL_PANDEMONIUM:
- return ( long_name ? "Pandemonium" : "Pan" );
- case LEVEL_LABYRINTH:
- return ( long_name ? "a Labyrinth" : "Lab" );
- case LEVEL_PORTAL_VAULT:
- return ( long_name ? "a Portal Chamber" : "Port" );
- default:
- return ( long_name ? "Buggy Badlands" : "Bug" );
- }
- }
-
- result = (long_name ?
- branches[branch].longname : branches[branch].abbrevname);
-
- if ( include_number && branches[branch].depth != 1 )
- {
- char buf[200];
- if ( long_name )
- {
- // decapitalize 'the'
- if ( result.find("The") == 0 )
- result[0] = 't';
- snprintf( buf, sizeof buf, "Level %d of %s",
- lev, result.c_str() );
- }
- else if (lev)
- snprintf( buf, sizeof buf, "%s:%d", result.c_str(), lev );
- else
- snprintf( buf, sizeof buf, "%s:$", result.c_str() );
-
- result = buf;
- }
- return result;
-}
-
-// Takes a packed 'place' and returns a compact stringified place name.
-// XXX: This is done in several other places; a unified function to
-// describe places would be nice.
-std::string short_place_name(unsigned short place)
-{
- return place_name( place, false, true );
-}
-
-// Prepositional form of branch level name. For example, "in the
-// Abyss" or "on level 3 of the Main Dungeon".
-std::string prep_branch_level_name(unsigned short packed_place)
-{
- std::string place = place_name( packed_place, true, true );
- if (place.length() && place != "Pandemonium")
- place[0] = tolower(place[0]);
- return (place.find("level") == 0?
- "on " + place
- : "in " + place);
-}
-
-// Use current branch and depth
-std::string prep_branch_level_name()
-{
- return prep_branch_level_name( get_packed_place() );
-}
-
-int absdungeon_depth(branch_type branch, int subdepth)
-{
- if (branch >= BRANCH_VESTIBULE_OF_HELL && branch <= BRANCH_THE_PIT)
- return subdepth + 27 - (branch == BRANCH_VESTIBULE_OF_HELL);
- else
- {
- --subdepth;
- while ( branch != BRANCH_MAIN_DUNGEON )
- {
- subdepth += branches[branch].startdepth;
- branch = branches[branch].parent_branch;
- }
- }
- return subdepth;
-}
-
-int subdungeon_depth(branch_type branch, int depth)
-{
- return depth - absdungeon_depth(branch, 0);
-}
-
-int player_branch_depth()
-{
- return subdungeon_depth(you.where_are_you, you.your_level);
-}
-
static const char *shop_types[] = {
"weapon",
"armour",