summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
authorAdam Borowski <kilobyte@angband.pl>2009-10-09 14:46:00 +0200
committerAdam Borowski <kilobyte@angband.pl>2009-10-09 14:46:00 +0200
commit6fb64ab3ac64b81a0891bdbbdd5c0b5d2d9b933c (patch)
tree890a713803c73b7412c3dc3192f40998a827ec0f /crawl-ref/source
parent477b8798b39a01bf4a73697eefe0ae131a12d47d (diff)
downloadcrawl-ref-6fb64ab3ac64b81a0891bdbbdd5c0b5d2d9b933c.tar.gz
crawl-ref-6fb64ab3ac64b81a0891bdbbdd5c0b5d2d9b933c.zip
Trees -- a new wall type, can be seen through (2nd square blocks LOS).
Available as 't' for vault builders. Can be ignited using wands of fire, but the fire can't be controlled.
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/beam.cc34
-rw-r--r--crawl-ref/source/cloud.cc44
-rw-r--r--crawl-ref/source/directn.cc2
-rw-r--r--crawl-ref/source/dungeon.cc2
-rw-r--r--crawl-ref/source/enum.h7
-rw-r--r--crawl-ref/source/losparam.cc2
-rw-r--r--crawl-ref/source/mapdef.cc2
-rw-r--r--crawl-ref/source/monstuff.cc3
-rw-r--r--crawl-ref/source/view.cc30
9 files changed, 108 insertions, 18 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index 39bd4313ec..3fb98b446c 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -1709,8 +1709,9 @@ void bolt::digging_wall_effect()
void bolt::fire_wall_effect()
{
- // Fire only affects wax walls.
- if (grd(pos()) != DNGN_WAX_WALL)
+ dungeon_feature_type feat;
+ // Fire only affects wax walls and trees.
+ if ((feat=grd(pos())) != DNGN_WAX_WALL && (feat != DNGN_TREES))
{
finish_beam();
return;
@@ -1719,7 +1720,7 @@ void bolt::fire_wall_effect()
if (!is_superhot())
{
// No actual effect.
- if (flavour != BEAM_HELLFIRE)
+ if (flavour != BEAM_HELLFIRE && feat == DNGN_WAX_WALL)
{
if (see_grid(pos()))
{
@@ -1734,12 +1735,27 @@ void bolt::fire_wall_effect()
{
// Destroy the wall.
grd(pos()) = DNGN_FLOOR;
- if (see_grid(pos()))
- emit_message(MSGCH_PLAIN, "The wax bubbles and burns!");
- else if (player_can_smell())
- emit_message(MSGCH_PLAIN, "You smell burning wax.");
+ if (feat == DNGN_WAX_WALL)
+ {
+ if (see_grid(pos()))
+ emit_message(MSGCH_PLAIN, "The wax bubbles and burns!");
+ else if (player_can_smell())
+ emit_message(MSGCH_PLAIN, "You smell burning wax.");
+ place_cloud(CLOUD_FIRE, pos(), random2(10)+15, whose_kill(), killer());
+ }
+ else
+ {
+ if (see_grid(pos()))
+ emit_message(MSGCH_PLAIN, "The tree burns like a torch!");
+ else if (player_can_smell())
+ emit_message(MSGCH_PLAIN, "You smell burning wood.");
+ if (whose_kill() == KC_YOU)
+ did_god_conduct(DID_KILL_PLANT, 1, effect_known, 0);
+ else if (whose_kill() == KC_FRIENDLY)
+ did_god_conduct(DID_ALLY_KILLED_PLANT, 1, effect_known, 0);
+ place_cloud(CLOUD_FOREST_FIRE, pos(), random2(30)+25, whose_kill(), killer(), 5);
+ }
- place_cloud(CLOUD_FIRE, pos(), random2(10)+15, whose_kill(), killer());
obvious_effect = true;
}
@@ -3102,7 +3118,7 @@ bool bolt::affects_wall(dungeon_feature_type wall) const
if (flavour == BEAM_DISINTEGRATION && damage.num >= 3)
return (true);
- if (is_fiery() && wall == DNGN_WAX_WALL)
+ if (is_fiery() && (wall == DNGN_WAX_WALL || wall == DNGN_TREES))
return (true);
// eye of devastation?
diff --git a/crawl-ref/source/cloud.cc b/crawl-ref/source/cloud.cc
index d2c9f5c30b..40f92bb4e4 100644
--- a/crawl-ref/source/cloud.cc
+++ b/crawl-ref/source/cloud.cc
@@ -25,6 +25,7 @@ REVISION("$Rev$");
#include "terrain.h"
#include "view.h"
#include "mutation.h"
+#include "los.h"
static int _actual_spread_rate(cloud_type type, int spread_rate)
{
@@ -130,13 +131,45 @@ static int _spread_cloud(const cloud_struct &cloud)
return (extra_decay);
}
+static void _spread_fire(const cloud_struct &cloud)
+{
+ int make_flames = one_chance_in(5);
+
+ for ( adjacent_iterator ai(cloud.pos); ai; ++ai )
+ {
+ if (!in_bounds(*ai)
+ || env.cgrid(*ai) != EMPTY_CLOUD
+ || is_sanctuary(*ai))
+ continue;
+
+ // burning trees produce flames all around
+ if (!grid_is_solid(*ai) && make_flames)
+ _place_new_cloud( CLOUD_FIRE, *ai, cloud.decay/2+1, cloud.whose,
+ cloud.killer, cloud.spread_rate );
+
+ // forest fire doesn't spread in all directions at once,
+ // every neighbouring square gets a separate roll
+ if (grd(*ai) == DNGN_TREES && one_chance_in(20))
+ {
+ if (see_grid(*ai))
+ mpr("The forest fire spreads!");
+ grd(*ai) = DNGN_FLOOR;
+ _place_new_cloud( cloud.type, *ai, random2(30)+25, cloud.whose,
+ cloud.killer, cloud.spread_rate );
+ }
+
+ }
+}
+
static void _dissipate_cloud(int cloudidx, int dissipate)
{
cloud_struct &cloud = env.cloud[cloudidx];
// Apply calculated rate to the actual cloud.
cloud.decay -= dissipate;
- if (x_chance_in_y(cloud.spread_rate, 100))
+ if (cloud.type == CLOUD_FOREST_FIRE)
+ _spread_fire(cloud);
+ else if (x_chance_in_y(cloud.spread_rate, 100))
{
cloud.spread_rate -= div_rand_round(cloud.spread_rate, 10);
cloud.decay -= _spread_cloud(cloud);
@@ -349,8 +382,7 @@ bool is_opaque_cloud(unsigned char cloud_idx)
return (false);
const int ctype = env.cloud[cloud_idx].type;
- return (ctype == CLOUD_BLACK_SMOKE
- || ctype >= CLOUD_GREY_SMOKE && ctype <= CLOUD_STEAM);
+ return (ctype >= CLOUD_OPAQUE_FIRST && ctype <= CLOUD_OPAQUE_LAST);
}
cloud_type cloud_type_at(const coord_def &c)
@@ -420,6 +452,7 @@ beam_type cloud2beam(cloud_type flavour)
default:
case CLOUD_NONE: return BEAM_NONE;
case CLOUD_FIRE: return BEAM_FIRE;
+ case CLOUD_FOREST_FIRE: return BEAM_FIRE;
case CLOUD_STINK: return BEAM_POTION_STINKING_CLOUD;
case CLOUD_COLD: return BEAM_COLD;
case CLOUD_POISON: return BEAM_POISON;
@@ -456,6 +489,7 @@ int max_cloud_damage(cloud_type cl_type, int power)
switch (cl_type)
{
case CLOUD_FIRE:
+ case CLOUD_FOREST_FIRE:
if (you.duration[DUR_FIRE_SHIELD])
return (0);
resist = player_res_fire();
@@ -542,6 +576,7 @@ void in_a_cloud()
switch (env.cloud[cl].type)
{
case CLOUD_FIRE:
+ case CLOUD_FOREST_FIRE:
if (you.duration[DUR_FIRE_SHIELD])
return;
@@ -710,6 +745,7 @@ bool is_damaging_cloud(cloud_type type, bool temp)
{
// always harmful...
case CLOUD_FIRE:
+ case CLOUD_FOREST_FIRE:
// ... unless a Ring of Flames is up and it's a fire cloud.
if (temp && you.duration[DUR_FIRE_SHIELD])
return (false);
@@ -759,6 +795,8 @@ std::string cloud_name(cloud_type type)
{
case CLOUD_FIRE:
return "flame";
+ case CLOUD_FOREST_FIRE:
+ return "fire";
case CLOUD_STINK:
return "noxious fumes";
case CLOUD_COLD:
diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc
index 1882388af6..c15a6f09a8 100644
--- a/crawl-ref/source/directn.cc
+++ b/crawl-ref/source/directn.cc
@@ -2654,6 +2654,8 @@ static std::string _base_feature_desc(dungeon_feature_type grid,
return ("translucent stone wall");
case DNGN_CLEAR_PERMAROCK_WALL:
return ("translucent unnaturally hard rock wall");
+ case DNGN_TREES:
+ return ("Trees");
case DNGN_ORCISH_IDOL:
if (you.species == SP_HILL_ORC)
return ("idol of Beogh");
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index ee1571569b..4f07e96f12 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -4836,6 +4836,7 @@ dungeon_feature_type map_feature(map_def *map, const coord_def &c, int rawfeat)
(rawfeat == 'm') ? DNGN_CLEAR_ROCK_WALL :
(rawfeat == 'n') ? DNGN_CLEAR_STONE_WALL :
(rawfeat == 'o') ? DNGN_CLEAR_PERMAROCK_WALL :
+ (rawfeat == 't') ? DNGN_TREES :
(rawfeat == '+') ? DNGN_CLOSED_DOOR :
(rawfeat == '=') ? DNGN_SECRET_DOOR :
(rawfeat == 'w') ? DNGN_DEEP_WATER :
@@ -4923,6 +4924,7 @@ static void _vault_grid( vault_placement &place,
(vgrid == 'm') ? DNGN_CLEAR_ROCK_WALL :
(vgrid == 'n') ? DNGN_CLEAR_STONE_WALL :
(vgrid == 'o') ? DNGN_CLEAR_PERMAROCK_WALL :
+ (vgrid == 't') ? DNGN_TREES :
(vgrid == '+') ? DNGN_CLOSED_DOOR :
(vgrid == '=') ? DNGN_SECRET_DOOR :
(vgrid == 'w') ? DNGN_DEEP_WATER :
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 5ef53a802a..58c2c95b13 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -431,6 +431,11 @@ enum cloud_type
CLOUD_GREY_SMOKE,
CLOUD_BLUE_SMOKE,
CLOUD_PURP_SMOKE,
+ CLOUD_FOREST_FIRE,
+
+ CLOUD_OPAQUE_FIRST = CLOUD_BLACK_SMOKE,
+ CLOUD_OPAQUE_LAST = CLOUD_FOREST_FIRE,
+
CLOUD_STEAM,
CLOUD_MIASMA,
CLOUD_MIST,
@@ -945,6 +950,7 @@ enum dungeon_char_type
DCHAR_ITEM_GOLD,
DCHAR_ITEM_AMULET, // 30
DCHAR_CLOUD, // 31
+ DCHAR_TREES,
DCHAR_SPACE,
DCHAR_FIRED_FLASK,
@@ -1016,6 +1022,7 @@ enum dungeon_feature_type
// Highest grid value which can't be reached through.
DNGN_MAX_NONREACH = DNGN_CLEAR_PERMAROCK_WALL,
+ DNGN_TREES,
DNGN_OPEN_SEA, // Shoals equivalent for permarock
// Can be seen through and reached past.
diff --git a/crawl-ref/source/losparam.cc b/crawl-ref/source/losparam.cc
index c0a3ed0298..f19412616e 100644
--- a/crawl-ref/source/losparam.cc
+++ b/crawl-ref/source/losparam.cc
@@ -97,6 +97,8 @@ opacity_type los_param_base::opacity(const coord_def& p) const
return OPC_OPAQUE;
else if (is_opaque_cloud(cloud_idx(p)))
return OPC_HALF;
+ else if (f == DNGN_TREES)
+ return OPC_HALF;
else
return OPC_CLEAR;
}
diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc
index db17585693..49ea350a1a 100644
--- a/crawl-ref/source/mapdef.cc
+++ b/crawl-ref/source/mapdef.cc
@@ -844,7 +844,7 @@ int map_lines::glyph(const coord_def &c) const
bool map_lines::is_solid(int gly) const
{
- return (gly == 'x' || gly == 'c' || gly == 'b' || gly == 'v');
+ return (gly == 'x' || gly == 'c' || gly == 'b' || gly == 'v' || gly == 't');
}
void map_lines::check_borders()
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index de0534aeb7..37224b5310 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -5446,6 +5446,7 @@ bool mons_avoids_cloud(const monsters *monster, cloud_type cl_type,
return (!mons_res_rotting(monster));
case CLOUD_FIRE:
+ case CLOUD_FOREST_FIRE:
if (mons_res_fire(monster) > 1)
return (false);
@@ -8822,6 +8823,7 @@ static bool _mon_can_move_to_pos(const monsters *monster,
if (monster->type == MONS_WATER_ELEMENTAL
&& (target_grid == DNGN_LAVA
|| targ_cloud_type == CLOUD_FIRE
+ || targ_cloud_type == CLOUD_FOREST_FIRE
|| targ_cloud_type == CLOUD_STEAM))
{
return (false);
@@ -9329,6 +9331,7 @@ static void _mons_in_cloud(monsters *monster)
return;
case CLOUD_FIRE:
+ case CLOUD_FOREST_FIRE:
if (monster->type == MONS_FIRE_VORTEX
|| monster->type == MONS_EFREET
|| monster->type == MONS_FIRE_ELEMENTAL)
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index 5fea829d23..931324c5d1 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -423,6 +423,16 @@ static bool _show_bloodcovered(const coord_def& where)
return (!is_critical_feature(grid) && !grid_is_trap(grid));
}
+static unsigned short _tree_colour(const coord_def& where)
+{
+ uint32_t h = where.x;
+ h+=h<<10; h^=h>>6;
+ h += where.y;
+ h+=h<<10; h^=h>>6;
+ h+=h<<3; h^=h>>11; h+=h<<15;
+ return (h>>30) ? GREEN : LIGHTGREEN;
+}
+
static void _get_symbol( const coord_def& where,
int object, unsigned *ch,
unsigned short *colour,
@@ -503,6 +513,8 @@ static void _get_symbol( const coord_def& where,
// already set.
if (fdef.colour != BLACK)
*colour = fdef.colour | colmask;
+ else if (object == DNGN_TREES)
+ *colour = _tree_colour(where) | colmask;
if (fdef.em_colour != fdef.colour && fdef.em_colour)
{
@@ -1640,6 +1652,7 @@ inline static void _update_cloud_grid(int cloudno)
switch (env.cloud[cloudno].type)
{
case CLOUD_FIRE:
+ case CLOUD_FOREST_FIRE:
if (env.cloud[cloudno].decay <= 20)
which_colour = RED;
else if (env.cloud[cloudno].decay <= 40)
@@ -3004,7 +3017,7 @@ static const unsigned dchar_table[ NUM_CSET ][ NUM_DCHAR_TYPES ] =
'#', '*', '.', ',', '\'', '+', '^', '>', '<', // wall .. stairs up
'_', '\\', '}', '{', '8', '~', '~', // altar .. item detect
'0', ')', '[', '/', '%', '?', '=', '!', '(', // orb .. missile
- ':', '|', '}', '%', '$', '"', '#', // book .. cloud
+ ':', '|', '}', '%', '$', '"', '#', '@', // book .. trees
' ', '!', '#', '%', ':', ')', '*', '+', // space .. fired_burst
'/', '=', '?', 'X', '[', '`', '#' // fi_stick .. explosion
},
@@ -3014,7 +3027,7 @@ static const unsigned dchar_table[ NUM_CSET ][ NUM_DCHAR_TYPES ] =
177, 176, 249, 250, '\'', 254, '^', '>', '<', // wall .. stairs up
220, 239, 244, 247, '8', '~', '~', // altar .. item detect
'0', ')', '[', '/', '%', '?', '=', '!', '(', // orb .. missile
- '+', '\\', '}', '%', '$', '"', '#', // book .. cloud
+ '+', '\\', '}', '%', '$', '"', '#', 234, // book .. trees
' ', '!', '#', '%', '+', ')', '*', '+', // space .. fired_burst
'/', '=', '?', 'X', '[', '`', '#' // fi_stick .. explosion
},
@@ -3024,7 +3037,7 @@ static const unsigned dchar_table[ NUM_CSET ][ NUM_DCHAR_TYPES ] =
225, 224, 254, ':', '\'', 238, '^', '>', '<', // wall .. stairs up
251, 182, 167, 187, '8', 171, 168, // altar .. item detect
'0', ')', '[', '/', '%', '?', '=', '!', '(', // orb .. missile
- '+', '\\', '}', '%', '$', '"', '#', // book .. cloud
+ '+', '\\', '}', '%', '$', '"', '#', '@', // book .. trees
' ', '!', '#', '%', '+', ')', '*', '+', // space .. fired_burst
'/', '=', '?', 'X', '[', '`', '#' // fi_stick .. explosion
},
@@ -3034,7 +3047,7 @@ static const unsigned dchar_table[ NUM_CSET ][ NUM_DCHAR_TYPES ] =
0x2592, 0x2591, 0xB7, 0x25E6, '\'', 0x25FC, '^', '>', '<',
'_', 0x2229, 0x2320, 0x2248, '8', '~', '~',
'0', ')', '[', '/', '%', '?', '=', '!', '(',
- '+', '|', '}', '%', '$', '"', '#',
+ '+', '|', '}', '%', '$', '"', '#', 0x2663,
' ', '!', '#', '%', '+', ')', '*', '+', // space .. fired_burst
'/', '=', '?', 'X', '[', '`', '#' // fi_stick .. explosion
},
@@ -3050,7 +3063,7 @@ dungeon_char_type dchar_by_name(const std::string &name)
"item_orb", "item_weapon", "item_armour", "item_wand", "item_food",
"item_scroll", "item_ring", "item_potion", "item_missile", "item_book",
"item_stave", "item_miscellany", "item_corpse", "item_gold",
- "item_amulet", "cloud"
+ "item_amulet", "cloud", "trees",
};
for (unsigned i = 0; i < sizeof(dchar_names) / sizeof(*dchar_names); ++i)
@@ -3146,6 +3159,13 @@ void init_feature_table( void )
Feature[i].minimap = MF_WALL;
break;
+ case DNGN_TREES:
+ Feature[i].dchar = DCHAR_TREES;
+ Feature[i].magic_symbol = Options.char_table[ DCHAR_WALL_MAGIC ];
+ Feature[i].colour = BLACK; // overridden later
+ Feature[i].minimap = MF_WALL;
+ break;
+
case DNGN_OPEN_SEA:
#ifdef USE_TILE
Feature[i].dchar = DCHAR_WAVY;