summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Cline <zelgadis@sourceforge.net>2009-10-13 02:09:47 -0700
committerMatthew Cline <zelgadis@sourceforge.net>2009-10-13 02:09:47 -0700
commit3ecee91a571ddbcaa7fb2dc8f041bfe75dadee4d (patch)
treeabdfcaa2ffff40a6a72ece8cebf6775c684bd838
parenta17dd5628fa9bf8734f4ee9c74f78d75e46c638a (diff)
parent7cb4b819399d86effcf5890498f3e89dcb8a7178 (diff)
downloadcrawl-ref-3ecee91a571ddbcaa7fb2dc8f041bfe75dadee4d.tar.gz
crawl-ref-3ecee91a571ddbcaa7fb2dc8f041bfe75dadee4d.zip
Merge branch 'master' of ssh://zelgadis@crawl-ref.git.sourceforge.net/gitroot/crawl-ref/crawl-ref
-rw-r--r--crawl-ref/docs/crawl_manual.txt5
-rw-r--r--crawl-ref/docs/develop/level_design.txt1
-rw-r--r--crawl-ref/source/abl-show.cc35
-rw-r--r--crawl-ref/source/acr.cc2
-rw-r--r--crawl-ref/source/artefact.cc2
-rw-r--r--crawl-ref/source/beam.cc125
-rw-r--r--crawl-ref/source/cloud.cc46
-rw-r--r--crawl-ref/source/dat/clua/loadmaps.lua2
-rw-r--r--crawl-ref/source/dat/database/quotes.txt24
-rw-r--r--crawl-ref/source/dat/descript/features.txt16
-rw-r--r--crawl-ref/source/dat/descript/monsters.txt4
-rw-r--r--crawl-ref/source/dat/hells.des71
-rw-r--r--crawl-ref/source/dat/mini.des30
-rw-r--r--crawl-ref/source/dat/shoals.des13
-rw-r--r--crawl-ref/source/dat/zot.des42
-rw-r--r--crawl-ref/source/describe.cc5
-rw-r--r--crawl-ref/source/directn.cc2
-rw-r--r--crawl-ref/source/dungeon.cc2
-rw-r--r--crawl-ref/source/enum.h10
-rw-r--r--crawl-ref/source/externs.h3
-rw-r--r--crawl-ref/source/fight.cc11
-rw-r--r--crawl-ref/source/hiscores.cc2
-rw-r--r--crawl-ref/source/invent.cc12
-rw-r--r--crawl-ref/source/invent.h12
-rw-r--r--crawl-ref/source/los.cc2
-rw-r--r--crawl-ref/source/losparam.cc7
-rw-r--r--crawl-ref/source/losparam.h12
-rw-r--r--crawl-ref/source/mapdef.cc2
-rw-r--r--crawl-ref/source/mon-data.h11
-rw-r--r--crawl-ref/source/mon-util.cc15
-rw-r--r--crawl-ref/source/monstuff.cc58
-rw-r--r--crawl-ref/source/monstuff.h4
-rw-r--r--crawl-ref/source/ouch.cc2
-rw-r--r--crawl-ref/source/output.cc9
-rw-r--r--crawl-ref/source/player.cc1
-rw-r--r--crawl-ref/source/religion.cc92
-rw-r--r--crawl-ref/source/tags.cc4
-rw-r--r--crawl-ref/source/tags.h3
-rw-r--r--crawl-ref/source/transfor.cc10
-rw-r--r--crawl-ref/source/travel.cc2
-rw-r--r--crawl-ref/source/view.cc30
41 files changed, 570 insertions, 171 deletions
diff --git a/crawl-ref/docs/crawl_manual.txt b/crawl-ref/docs/crawl_manual.txt
index 91423389c0..b9dbc93e2f 100644
--- a/crawl-ref/docs/crawl_manual.txt
+++ b/crawl-ref/docs/crawl_manual.txt
@@ -1900,7 +1900,8 @@ Berserkers:
Berserkers are hardy warriors who worship Trog the Wrathful, from whom
they get the power to go berserk (as well as a number of other powers,
should they prove worthy), but who forbids the use of spell magic. They
-usually enter the dungeon with an axe and dressed in animal skins.
+usually enter the dungeon with a mace or axe, and dressed in animal
+skins.
Paladins:
---------
@@ -1913,7 +1914,7 @@ Priests:
Priests serve either Zin, the ancient and revered God of Law, or
Yredelemnul, the rather less pleasant God of Death. In addition, Hill
Orcs may choose to follow the Orc god Beogh instead. Priests enter the
-dungeon with a traditional weapon, and a priestly robe. Those who serve
+dungeon with a traditional weapon and a priestly robe. Those who serve
Zin also get a few healing potions.
Healers:
diff --git a/crawl-ref/docs/develop/level_design.txt b/crawl-ref/docs/develop/level_design.txt
index 6c973d6220..0ddde1d32b 100644
--- a/crawl-ref/docs/develop/level_design.txt
+++ b/crawl-ref/docs/develop/level_design.txt
@@ -156,6 +156,7 @@ Terrain
v - metal wall - grounds electricity (DNGN_METAL_WALL)
b - crystal wall - reflects cold and fire (DNGN_GREEN_CRYSTAL_WALL)
a - wax wall - can melt (DNGN_WAX_WALL)
+ t - trees - a single square doesn't block LOS (DNGN_TREES)
. - floor (DNGN_FLOOR)
+ - closed door (DNGN_CLOSED_DOOR)
diff --git a/crawl-ref/source/abl-show.cc b/crawl-ref/source/abl-show.cc
index 005e83db52..be34c67611 100644
--- a/crawl-ref/source/abl-show.cc
+++ b/crawl-ref/source/abl-show.cc
@@ -322,7 +322,7 @@ static const ability_def Ability_List[] =
// Jiyva
{ ABIL_JIYVA_CALL_JELLY, "Request Jelly", 2, 0, 20, 1, ABFLAG_NONE },
{ ABIL_JIYVA_JELLY_SHIELD, "Jelly Shield", 0, 0, 0, 0, ABFLAG_PIETY },
- { ABIL_JIYVA_SLIMIFY, "Slimify", 4, 0, 100, 3, ABFLAG_NONE },
+ { ABIL_JIYVA_SLIMIFY, "Slimify", 4, 0, 100, 8, ABFLAG_NONE },
{ ABIL_JIYVA_CURE_BAD_MUTATION, "Cure Bad Mutation",
8, 0, 200, 15, ABFLAG_NONE },
@@ -2042,22 +2042,27 @@ static bool _do_ability(const ability_def& abil)
break;
case ABIL_JIYVA_SLIMIFY:
- beam.range = LOS_RADIUS;
- if (!spell_direction(spd, beam))
- return (false);
+ {
+ std::string msg;
+ int has_weapon = you.equip[EQ_WEAPON];
- if (beam.target == you.pos())
- {
- mpr("You cannot slimify yourself!");
- return (false);
- }
- if (!zapping(ZAP_SLIME, 16 + you.skills[SK_INVOCATIONS] * 8, beam,
- true))
+ if (has_weapon == -1)
+ msg = "your " + you.hand_name(true);
+ else
{
- return (false);
+ item_def& weapon = *you.weapon();
+ msg = weapon.name(DESC_NOCAP_YOUR);
}
+
+ mprf(MSGCH_DURATION, "A thick mucus forms on %s.", msg.c_str());
+ you.duration[DUR_SLIMIFY] += you.skills[SK_INVOCATIONS] * 3 / 2 + 3;
+
+ if (you.duration[DUR_SLIMIFY] > 100)
+ you.duration[DUR_SLIMIFY] = 100;
+
exercise(SK_INVOCATIONS, 3 + random2(5));
break;
+ }
case ABIL_JIYVA_CURE_BAD_MUTATION:
if (jiyva_remove_bad_mutation())
@@ -2349,8 +2354,12 @@ std::vector<talent> your_talents(bool check_confused)
if (player_mutation_level(MUT_SMITE))
_add_talent(talents, ABIL_BOLT_OF_DRAINING, check_confused);
- if (you.duration[DUR_TRANSFORMATION] && you.attribute[ATTR_TRANSFORMATION]!=TRAN_PIG)
+ if (you.duration[DUR_TRANSFORMATION]
+ && you.attribute[ATTR_TRANSFORMATION] != TRAN_PIG
+ && you.transform_cancellable)
+ {
_add_talent(talents, ABIL_END_TRANSFORMATION, check_confused);
+ }
if (player_mutation_level(MUT_BLINK))
_add_talent(talents, ABIL_BLINK, check_confused);
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index 988da0c579..b20c9794f1 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -2273,6 +2273,8 @@ static void _decrement_durations()
_decrement_a_duration(DUR_BARGAIN, "You feel less charismatic.");
_decrement_a_duration(DUR_CONF, "You feel less confused.");
_decrement_a_duration(DUR_LOWERED_MR, "You feel more resistant to magic.");
+ _decrement_a_duration(DUR_SLIMIFY, "You feel less slimy.",
+ coinflip(), "Your slime is starting to congeal.");
if (you.duration[DUR_PARALYSIS] || you.duration[DUR_PETRIFIED])
{
diff --git a/crawl-ref/source/artefact.cc b/crawl-ref/source/artefact.cc
index 0d8597433c..4ca42dc402 100644
--- a/crawl-ref/source/artefact.cc
+++ b/crawl-ref/source/artefact.cc
@@ -310,7 +310,7 @@ static std::string _replace_name_parts(const std::string name_in,
// Functions defined in art-func.h are referenced in art-data.h
#include "art-func.h"
-static unrandart_entry unranddata[] = {
+static unrandart_entry unranddata[UNRAND_LAST] = {
#include "art-data.h"
};
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index 50cf568e9a..39d700aa8c 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -1268,21 +1268,6 @@ const zap_info zap_data[] = {
},
{
- ZAP_SLIME,
- "0",
- 100,
- NULL,
- NULL,
- GREEN,
- true,
- BEAM_SLIME,
- DCHAR_SPACE,
- false,
- false,
- false
- },
-
- {
ZAP_PORKALATOR,
"porkalator",
100,
@@ -1708,8 +1693,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;
@@ -1718,7 +1704,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()))
{
@@ -1733,12 +1719,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;
}
@@ -2213,25 +2214,16 @@ int mons_adjust_flavoured(monsters *monster, bolt &pbolt, int hurted,
if (doFlavouredEffects)
simple_monster_message(monster, " resists.");
}
- else if (original < hurted)
+ else if (original < hurted && doFlavouredEffects)
{
if (mons_is_icy(monster->type))
- {
- if (doFlavouredEffects)
- simple_monster_message(monster, " melts!");
- }
+ simple_monster_message(monster, " melts!");
+ else if (monster->type == MONS_BUSH)
+ simple_monster_message(monster, " is on fire!");
+ else if (pbolt.flavour == BEAM_FIRE)
+ simple_monster_message(monster, " is burned terribly!");
else
- {
- if (doFlavouredEffects)
- {
- if (pbolt.flavour == BEAM_FIRE)
- simple_monster_message(monster,
- " is burned terribly!");
- else
- simple_monster_message(monster,
- " is scalded terribly!");
- }
- }
+ simple_monster_message(monster, " is scalded terribly!");
}
break;
@@ -3107,7 +3099,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?
@@ -4584,6 +4576,13 @@ void bolt::affect_monster(monsters* mon)
return;
}
+ // Missiles go past bushes.
+ if (!is_beam && mon->type == MONS_BUSH)
+ {
+ apply_hit_funcs(mon, 0);
+ return;
+ }
+
// Fire storm creates these, so we'll avoid affecting them
if (name == "great blast of fire" && mon->type == MONS_FIRE_VORTEX)
{
@@ -4889,11 +4888,6 @@ bool _ench_flavour_affects_monster(beam_type flavour, const monsters* mon)
|| (mons_holiness(mon) == MH_NATURAL && mon->type != MONS_HOG);
break;
- case BEAM_SLIME:
- rc = (mons_holiness(mon) == MH_NATURAL
- || mons_holiness(mon) == MH_UNDEAD);
- break;
-
default:
break;
}
@@ -5074,46 +5068,6 @@ mon_resist_type bolt::apply_enchantment_to_monster(monsters* mon)
behaviour_event(mon, ME_ALERT, MHITNOT);
return (MON_AFFECTED);
- case BEAM_SLIME:
- if (mon->hit_dice * 8 / 2 >= random2(ench_power))
- return (MON_RESIST);
-
- obvious_effect = true;
-
- if (mons_holiness(mon) == MH_UNDEAD)
- monster_polymorph(mon, MONS_DEATH_OOZE);
- else
- {
- const int x = mon->hit_dice + (coinflip() ? 1 : -1) * random2(5);
-
- if (x < 3)
- monster_polymorph(mon, MONS_OOZE);
- else if (x >= 3 && x < 5)
- monster_polymorph(mon, MONS_JELLY);
- else if (x >= 5 && x < 7)
- monster_polymorph(mon, MONS_BROWN_OOZE);
- else if (x >= 7 && x <= 11)
- {
- if (coinflip())
- monster_polymorph(mon, MONS_SLIME_CREATURE);
- else
- monster_polymorph(mon, MONS_GIANT_AMOEBA);
- }
- else
- {
- if (coinflip())
- monster_polymorph(mon, MONS_ACID_BLOB);
- else
- monster_polymorph(mon, MONS_AZURE_JELLY);
- }
- }
-
- if (!mons_eats_items(mon))
- mon->add_ench(ENCH_EAT_ITEMS);
-
- mon->attitude = ATT_STRICT_NEUTRAL;
- return (MON_AFFECTED);
-
case BEAM_PAIN: // pain/agony
if (simple_monster_message(mon, " convulses in agony!"))
obvious_effect = true;
@@ -6017,7 +5971,6 @@ std::string beam_type_name(beam_type type)
case BEAM_PETRIFY: return ("petrify");
case BEAM_BACKLIGHT: return ("backlight");
case BEAM_PORKALATOR: return ("porkalator");
- case BEAM_SLIME: return ("slime");
case BEAM_SLEEP: return ("sleep");
case BEAM_BERSERK: return ("berserk");
case BEAM_POTION_BLACK_SMOKE: return ("black smoke");
diff --git a/crawl-ref/source/cloud.cc b/crawl-ref/source/cloud.cc
index 0da8010083..4e66215059 100644
--- a/crawl-ref/source/cloud.cc
+++ b/crawl-ref/source/cloud.cc
@@ -23,6 +23,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)
{
@@ -132,13 +133,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);
@@ -195,7 +228,7 @@ void delete_cloud( int cloud )
&& one_chance_in(3))
// Don't drown the player!
feat = DNGN_DEEP_WATER;
- else
+ else
feat = grd(c.pos);
if (grd(c.pos) != feat)
@@ -379,8 +412,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)
@@ -452,6 +484,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;
@@ -489,6 +522,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();
@@ -575,6 +609,7 @@ void in_a_cloud()
switch (env.cloud[cl].type)
{
case CLOUD_FIRE:
+ case CLOUD_FOREST_FIRE:
if (you.duration[DUR_FIRE_SHIELD])
return;
@@ -750,6 +785,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);
@@ -823,6 +859,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/dat/clua/loadmaps.lua b/crawl-ref/source/dat/clua/loadmaps.lua
index c6d197e335..1dde1ad737 100644
--- a/crawl-ref/source/dat/clua/loadmaps.lua
+++ b/crawl-ref/source/dat/clua/loadmaps.lua
@@ -18,7 +18,7 @@ local des_files = {
"altar.des", "bazaar.des", "bailey.des", "entry.des", "elf.des",
"float.des", "hells.des", "hive.des", "icecave.des", "lab.des",
"lair.des", "large.des", "layout.des", "mini.des", "ossuary.des",
- "orc.des", "pan.des", "sewer.des", "temple.des", "trove.des",
+ "orc.des", "pan.des", "sewer.des", "shoals.des", "temple.des", "trove.des",
"vaults.des", "crypt.des", "ziggurat.des", "zot.des", "rooms.des"
}
diff --git a/crawl-ref/source/dat/database/quotes.txt b/crawl-ref/source/dat/database/quotes.txt
index 0bd7e9391a..1de77e5784 100644
--- a/crawl-ref/source/dat/database/quotes.txt
+++ b/crawl-ref/source/dat/database/quotes.txt
@@ -52,6 +52,18 @@ A one-way gate to the infinite horrors of the Abyss
the abyss gazes also into you."
-Friedrich Nietzsche, "Beyond Good and Evil"
%%%%
+A portal to a secret trove of treasure
+
+"'Stop thief! Stop thief!' There is a magic in the sound. The tradesman
+ leaves his counter, and the car-man his waggon; the butcher throws down
+ his tray; the baker his basket; the milkman his pail; the errand-boy
+ his parcels; the school-boy his marbles; the paviour his pickaxe; the
+ child his battledore. Away they run, pell-mell, helter-skelter, slap-dash:
+ tearing, yelling, screaming, knocking down the passengers as they turn
+ the corners, rousing up the dogs, and astonishing the fowls: and streets,
+ squares, and courts, re-echo with the sound."
+ -Charles Dickens, "Oliver Twist"
+%%%%
A rock wall
"I know not whether Laws be right,
@@ -75,6 +87,11 @@ controlling them; then pray that your grieves may slumber, and the
brotherhood of remorse not break their chain."
-Nathaniel Hawthorne
%%%%
+Trees
+
+"Only YOU can prevent forest fires!"
+ -Smokey the Bear
+%%%%
####################################################
# Items
####################################################
@@ -529,6 +546,13 @@ bumblebee
From every opening Flower!"
-Isaac Watts. 1715.
%%%%
+bush
+
+"And the angel of the LORD appeared unto him in a flame of fire out of the
+ midst of a bush: and he looked, and, behold, the bush burned with fire, and
+ the bush was not consumed."
+ -KJV Bible, Ex3:2.
+%%%%
butterfly
"Happiness is a butterfly, which when pursued, is always just beyond your
diff --git a/crawl-ref/source/dat/descript/features.txt b/crawl-ref/source/dat/descript/features.txt
index b8c58e3797..a3e40a5869 100644
--- a/crawl-ref/source/dat/descript/features.txt
+++ b/crawl-ref/source/dat/descript/features.txt
@@ -139,18 +139,6 @@ A one-way gate to the infinite horrors of the Abyss
A one-way gate to a demon-haunted realm, riven by chaos, its very substance impermanent and whimsical, filled with creatures out of nightmare.
%%%%
-A portal to a secret trove of treasure
-
-"'Stop thief! Stop thief!' There is a magic in the sound. The tradesman
- leaves his counter, and the car-man his waggon; the butcher throws down
- his tray; the baker his basket; the milkman his pail; the errand-boy
- his parcels; the school-boy his marbles; the paviour his pickaxe; the
- child his battledore. Away they run, pell-mell, helter-skelter, slap-dash:
- tearing, yelling, screaming, knocking down the passengers as they turn
- the corners, rousing up the dogs, and astonishing the fowls: and streets,
- squares, and courts, re-echo with the sound."
- -Charles Dickens, "Oliver Twist"
-%%%%
A rock wall
This wall consists of simple rock.
@@ -347,3 +335,7 @@ Some shallow water
This waist-deep, misty water makes movement and combat cumbersome for landlubbers - sometimes dangerous, but never directly fatal.
%%%%
+Trees
+
+While the dungeon is filled with dim magic light, in most places it is not bright enough to sustain any larger plants. It is uneven, though, and there are spots where, with the grace of Feawn, trees as big as those on the surface can grow underground.
+%%%%
diff --git a/crawl-ref/source/dat/descript/monsters.txt b/crawl-ref/source/dat/descript/monsters.txt
index 0908bacdc5..618a85040a 100644
--- a/crawl-ref/source/dat/descript/monsters.txt
+++ b/crawl-ref/source/dat/descript/monsters.txt
@@ -412,6 +412,10 @@ brown ooze
A viscous liquid, flowing along the floor in search of organic matter to corrode.
%%%%
+bush
+
+A woody plant that, unlike trees, can be removed even with bare hands. It looks dry enough to be easily set on fire, and it isn't very dense so arrows are likely to go past it.
+%%%%
water moccasin
A largish venomous brown snake. It usually lives near water, and is an able swimmer.
diff --git a/crawl-ref/source/dat/hells.des b/crawl-ref/source/dat/hells.des
index acd4a65e9f..52e3da2991 100644
--- a/crawl-ref/source/dat/hells.des
+++ b/crawl-ref/source/dat/hells.des
@@ -382,6 +382,77 @@ ENDMAP
##############################################################################
+# Dispater - new map by Mu, featuring iron golems and iron trolls
+##############################################################################
+
+NAME: castle_dis_mu
+PLACE: Dis:7
+TAGS: dis
+ORIENT: north
+TAGS: no_rotate
+LFLAGS: no_tele_control
+
+### make granite statues into iron statues
+{{
+ dgn.set_feature_desc_short("granite statue", "iron statue")
+ dgn.set_feature_desc_long("granite statue", "A heavy-looking iron statue. You " ..
+ "can't help but feel like it's watching you.")
+}}
+KFEAT: o = granite_statue
+MARKER: O = lua:item_pickup_change_flags { \
+ level_flags="!no_tele_control", item="iron rune of Zot" \
+ }
+MONS: Dispater
+MONS: fiend
+MONS: ice fiend
+MONS: iron devil
+MONS: metal gargoyle
+MONS: iron dragon
+MONS: iron troll
+KMONS: 8 = iron golem
+KFEAT: 8 = .
+SHUFFLE: 23
+SUBST: 4 = 4:20 7
+SUBST: 8 = 8o
+COLOUR: o : cyan
+MAP
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvxxxxxx
+xxxxxxv..................................................................vxxxxxx
+xxxxxxv..............................................v5v..v5v............vxxxxxx
+xxxxxxv..............................................vvvvvvvv............vxxxxxx
+xxxxxxv..........v5v5v...v5v5v...v5v5v...v5v5v.....vvv...4..vvv..........vxxxxxx
+xxxxxxv..........vvvvv...vvvvv...vvvvv...vvvvv...vvv.+..88..+.vvv........vxxxxxx
+xxxxxxv..........v||3v...v2||v...v$$$v...v$$$v..vv...v...4..v...vv.......vxxxxxx
+xxxxxxv..........v|..v...v..|v...v$|$v...v$|$v.vv..vvvvvvvvvvvv..vv......vxxxxxx
+xxxxxxv..........v...vvvvv...vvvvv.6.vvvvv.6.vvv..vvvvvvvvvvvvvv..vv.....vxxxxxx
+xxxxxxv........vvvv+vvW8Wvv+vvvvvv...+...+...vv..vvv.........vvvv..v.....vxxxxxx
+xxxxxxv.......vv.v...........vvvvvvvvv...vvvvvv.vvvv$$$$$vv...vvvv.vv....vxxxxxx
+xxxxxxv.....vvv..+.......44..vv|$|vvv.....vvvv..vvvv$$$vvv....vvvv..v....vxxxxxx
+xxxxxxv....vv....v...........vv$$$vv..vvv..vvv+vvvvv||vv.......vvvv+vvv..vxxxxxx
+xxxxxxv..vvv.8W..vvvvvvvvvvvvvv$$$v...v.v...v...vvvv|vv..v4v4v.vvv...v5..vxxxxxx
+xxxxxxv..5vv.WW..vv5vv5vv5vv5vvv=vv.........+...vvvv|vv.........vv...vv..vxxxxxx
+xxxxxxv..vvv.WW..+................+..v...v..v...vvvvOv1...2.....+....v...vxxxxxx
+xxxxxxv..vvv.WW..+................+..5.W.5..v...vvvv|v6...3.....+....v...vxxxxxx
+xxxxxxv..5vv.WW..vv5vv5vv5vv5vvv=vv..v.W.v..v...vvvv|vv.........vv...vv..vxxxxxx
+xxxxxxv..vvv.8W..vvvvvvvvvvvvvv$$$v..5.W.5..v...vvvv|vv..v4v4v.vvv...v5..vxxxxxx
+xxxxxxv....vv....v.......v...vv$$$v..v...v..vv+vvvvv||vv.......vvvv+vvv..vxxxxxx
+xxxxxxv.....vv...+.......+...vv|$|v.........vv..vvvv$$$vvv....vvvv..v....vxxxxxx
+xxxxxxv......vvv.v.......v...vvvvvv..vv+vv..vvv.vvvv$$$$$vv...vvvv.vv....vxxxxxx
+xxxxxxv........vvvv+vvW8Wv$$$vvvvvv..v...v..vvv..vvv.........vvvv..v.....vxxxxxx
+xxxxxxv..........v...vvvvv$$$vvvvvvvvv...vvvvvvv..vvvvvvvvvvvvvv..vv.....vxxxxxx
+xxxxxxv..........v$2$v...v$3$v...vvvvv...vvvvv.vv..vvvvvvvvvvvv..vv......vxxxxxx
+xxxxxxv..........v|||v...v|||v...vvvvv...vvvvv..vv...v...4..v...vv.......vxxxxxx
+xxxxxxv..........vvvvv...vvvvv...vvv8v+++v8vvv...vvv.+..88..+.vvv........vxxxxxx
+xxxxxxv..........v5v5v...v5v5v...v.v.v...v.v.v.....vvv...4..vvv..........vxxxxxx
+xxxxxxv..............................................vvvvvvvv............vxxxxxx
+xxxxxxv...........................7...........7......v5v..v5v............vxxxxxx
+xxxxxxv..........................7....{.[.(....7.........................vxxxxxx
+xxxxxxv...........................7...........7..........................vxxxxxx
+ENDMAP
+
+
+##############################################################################
# Asmodeus
##############################################################################
diff --git a/crawl-ref/source/dat/mini.des b/crawl-ref/source/dat/mini.des
index 2c5e8c78d4..1de16335d9 100644
--- a/crawl-ref/source/dat/mini.des
+++ b/crawl-ref/source/dat/mini.des
@@ -2425,3 +2425,33 @@ xxxxx"x........x+xxxxx........x"xxxxx
........xx'x...xm+++mx...x'xx........
..................@..................
ENDMAP
+
+#################################################################
+# And for now, something woody (1KB)
+#
+NAME: forest_paths
+DEPTH: D, Lair
+MAP
+tttttttttttttttttttttttttt@tttttttttttttttttttttt
+tttttttttttttttttttttttttt...tttttttttttttttttttt
+tttttttttttttttttttttttttttt..tttttttttttttt0}ttt
+ttttttttt.tt......ttttttttttt..tttttttttttt..tttt
+tttttttt.t...ttt.0.tttttttttt.tttttttttt...tttttt
+tt......tttttttt...ttttttttttt.tttttt...ttttttttt
+t.ttttttttttttttt....tttttttttt.tttt.tttttttttttt
+@ttttttttttttttt..tttttttttttt..tt...tttttttttttt
+ttttttttttttttt..tttttttttttttt....tttttttttttttt
+tttttttttttttttt..ttttttttttttttt.ttttttttttttttt
+tttttttttttttttt....tttttttttttt.tttttttttt...ttt
+tttttttttttttttttt.....tttttttttt..ttttttt..*..tt
+ttttttttttttttttttttt....ttttttttt.ttttttt.000.tt
+ttttttttttttttttttttttt...tttttttt.ttttt......ttt
+ttttttttttttttttttttttttt....tttt.ttttttt.tt.t0tt
+tttttttttttttttttttttttttttt.....tttttttt.ttttttt
+....ttttttttttttttttttttttt...tttttttttt.tttttttt
+@....tttttttt...ttttttttttt...tttttttt..ttttttttt
+ttttt..ttt....tt...tt........0.ttttt..ttttttttttt
+ttttttt....ttttttt....ttttttt..ttt..ttttttttttttt
+tttttttttttttttttttttttttttttt....ttttttttttttttt
+ttttttttttttttttttttttttttttttttttttttttttttttttt
+ENDMAP
diff --git a/crawl-ref/source/dat/shoals.des b/crawl-ref/source/dat/shoals.des
index 12e6803c84..8928e8009d 100644
--- a/crawl-ref/source/dat/shoals.des
+++ b/crawl-ref/source/dat/shoals.des
@@ -94,6 +94,19 @@ MAP
...
ENDMAP
+NAME: yaktaur_hedge
+DEPTH: Shoal
+MONS: bush
+MONS: yaktaur
+MAP
+.......
+.11111.
+.1...1.
+.1.1.1.
+.1.121.
+.1.111.
+.......
+ENDMAP
##############################################################################
# Branch ends.
diff --git a/crawl-ref/source/dat/zot.des b/crawl-ref/source/dat/zot.des
index b43c34251b..f2f1a3ce22 100644
--- a/crawl-ref/source/dat/zot.des
+++ b/crawl-ref/source/dat/zot.des
@@ -281,6 +281,48 @@ llll...x.x44444x.x...llll
ll>ll
ENDMAP
+######################################
+# Circus (by mu)
+# full of klowns, caged animals outside
+NAME: circus_mu
+DEPTH: Zot:1-4
+ORIENT: float
+TAGS: no_rotate no_hmirror no_monster_gen
+MONS: killer klown
+MONS: elephant slug
+MONS: human ; whip | demon whip
+SUBST: 1 = 1 2:5 3:20
+SUBST: 2 = 2 .
+SUBST: % = !:20 ?:5 $ .:20
+KITEM: ! = banana
+KITEM: ? = wand of random effects
+KITEM: $ = potion of water
+COLOUR: " : yellow
+MAP
+ ................
+ .....xxxxx.............
+ .....xx...xx.............
+ .....xx..%..xx.....mmmmm...
+ .....xx..%.%..xx....m222m....
+.....xx.%..1..%.xx...m+mmm.....
+....xx...%.%.%...xx............
+...xx..%1"""""1%..xx....mmmmm..
+..xx..%.""..."".%..xx...m222m..
+.xx..%%.".....".%%..xx..m+mmm..
+.x.%1..1"..1.."1..1%.x.........
+.xx..%%.".....".%%..xx..3......
+..xx..%.""..."".%..xx..........
+...xx..%1"""""1%..xx...mmmmm...
+....xx...%.%.%...xx....m222m...
+.....xx.%..1..%.xx.....m+mmm..
+ .....xx...%...xx............
+ .....xx.%.%.xx............
+ .....xx+++xx.....
+ .....xx+xx.....
+ .............
+ENDMAP
+
+
##############################################################################
# hall_of_Zot_5
diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc
index 9f78b628d8..aff6afc172 100644
--- a/crawl-ref/source/describe.cc
+++ b/crawl-ref/source/describe.cc
@@ -2688,6 +2688,9 @@ static std::string _monster_stat_description(const monsters& mon)
if (mons_immune_magic(&mon))
result << pronoun << " is immune to magical enchantments.$";
+ if (mons_class_flag(mon.type, M_STATIONARY))
+ result << pronoun << " cannot move.$";
+
// These differ between ghost demon monsters, so would be spoily.
if (!mons_is_ghost_demon(mon.type))
{
@@ -2699,7 +2702,7 @@ static std::string _monster_stat_description(const monsters& mon)
// Unusual monster speed.
const int speed = mons_base_speed(&mon);
- if (speed != 10)
+ if (speed != 10 && speed != 0)
{
result << pronoun << " is ";
if (speed < 7)
diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc
index d119668aae..e3d758a195 100644
--- a/crawl-ref/source/directn.cc
+++ b/crawl-ref/source/directn.cc
@@ -2653,6 +2653,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 c8103e2f1a..1a22de6180 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -4831,6 +4831,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 :
@@ -4918,6 +4919,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 6a602a2c8f..58376fb08c 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -245,7 +245,6 @@ enum beam_type // beam[].flavour
BEAM_PETRIFY,
BEAM_BACKLIGHT, // 45
BEAM_PORKALATOR,
- BEAM_SLIME,
BEAM_SLEEP,
BEAM_BERSERK,
BEAM_LAST_ENCHANTMENT = BEAM_BERSERK,
@@ -432,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,
@@ -946,6 +950,7 @@ enum dungeon_char_type
DCHAR_ITEM_GOLD,
DCHAR_ITEM_AMULET, // 30
DCHAR_CLOUD, // 31
+ DCHAR_TREES,
DCHAR_SPACE,
DCHAR_FIRED_FLASK,
@@ -1017,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.
@@ -1253,6 +1259,7 @@ enum duration_type
DUR_LOWERED_MR,
DUR_REPEL_STAIRS_MOVE,
DUR_REPEL_STAIRS_CLIMB,
+ DUR_SLIMIFY,
NUM_DURATIONS
};
@@ -1863,6 +1870,7 @@ enum monster_type // (int) menv[].type
MONS_FLAMING_CORPSE,
MONS_HARPY,
MONS_TOADSTOOL, // 198
+ MONS_BUSH,
//jmf: end new monsters
MONS_WHITE_IMP = 220, // 220
MONS_LEMURE,
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index c675520e37..732f4fe497 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -836,6 +836,7 @@ public:
game_direction_type char_direction;
bool opened_zot;
bool royal_jelly_dead;
+ bool transform_cancellable;
unsigned short pet_target;
@@ -1335,7 +1336,7 @@ public:
void scale_hp(int num, int den);
bool gain_exp(int exp);
- void react_to_damage(int damage, beam_type flavour);
+ void react_to_damage(int damage, beam_type flavour, kill_category whose);
void forget_random_spell();
diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc
index 1426d83ad6..2f3d899835 100644
--- a/crawl-ref/source/fight.cc
+++ b/crawl-ref/source/fight.cc
@@ -858,6 +858,17 @@ bool melee_attack::player_attack()
player_calc_hit_damage();
}
+ if (you.duration[DUR_SLIMIFY]
+ && mon_can_be_slimified(defender_as_monster()))
+ {
+ // Bail out after sliming so we don't get aux unarmed and
+ // attack a fellow slime.
+ damage_done = 0;
+ slimify_monster(defender_as_monster());
+ you.duration[DUR_SLIMIFY] = 0;
+ return (true);
+ }
+
bool hit_woke_orc = false;
if (you.religion == GOD_BEOGH
&& defender->mons_species() == MONS_ORC
diff --git a/crawl-ref/source/hiscores.cc b/crawl-ref/source/hiscores.cc
index f094715974..6df297a618 100644
--- a/crawl-ref/source/hiscores.cc
+++ b/crawl-ref/source/hiscores.cc
@@ -300,7 +300,7 @@ void hiscores_print_list( int display_count, int format )
}
// Trying to supply an appropriate verb for the attack type. -- bwr
-static const char *const _range_type_verb( const char *const aux )
+static const char *_range_type_verb( const char *const aux )
{
if (strncmp( aux, "Shot ", 5 ) == 0) // launched
return ("shot");
diff --git a/crawl-ref/source/invent.cc b/crawl-ref/source/invent.cc
index aad492a8cf..7d5df507e4 100644
--- a/crawl-ref/source/invent.cc
+++ b/crawl-ref/source/invent.cc
@@ -105,12 +105,12 @@ const std::string &InvEntry::get_fullname() const
return (text);
}
-const bool InvEntry::is_item_cursed() const
+bool InvEntry::is_item_cursed() const
{
return (item_ident(*item, ISFLAG_KNOW_CURSE) && item_cursed(*item));
}
-const bool InvEntry::is_item_glowing() const
+bool InvEntry::is_item_glowing() const
{
return (!item_ident(*item, ISFLAG_KNOW_TYPE)
&& (get_equip_desc(*item)
@@ -121,7 +121,7 @@ const bool InvEntry::is_item_glowing() const
|| item->base_type == OBJ_BOOKS))));
}
-const bool InvEntry::is_item_ego() const
+bool InvEntry::is_item_ego() const
{
return (item_ident(*item, ISFLAG_KNOW_TYPE) && !is_artefact(*item)
&& item->special != 0
@@ -130,12 +130,12 @@ const bool InvEntry::is_item_ego() const
|| item->base_type == OBJ_ARMOUR));
}
-const bool InvEntry::is_item_art() const
+bool InvEntry::is_item_art() const
{
return (item_ident(*item, ISFLAG_KNOW_TYPE) && is_artefact(*item));
}
-const bool InvEntry::is_item_equipped() const
+bool InvEntry::is_item_equipped() const
{
if (item->link == -1 || item->pos.x != -1 || item->pos.y != -1)
return(false);
@@ -149,7 +149,7 @@ const bool InvEntry::is_item_equipped() const
// Returns values < 0 for edible chunks (non-rotten except for Saprovores),
// 0 for non-chunks, and values > 0 for rotten chunks for non-Saprovores.
-const int InvEntry::item_freshness() const
+int InvEntry::item_freshness() const
{
if (item->base_type != OBJ_FOOD || item->sub_type != FOOD_CHUNK)
return 0;
diff --git a/crawl-ref/source/invent.h b/crawl-ref/source/invent.h
index 443ca070d0..04001440c0 100644
--- a/crawl-ref/source/invent.h
+++ b/crawl-ref/source/invent.h
@@ -86,12 +86,12 @@ public:
const std::string &get_basename() const;
const std::string &get_qualname() const;
const std::string &get_fullname() const;
- const bool is_item_cursed() const;
- const bool is_item_glowing() const;
- const bool is_item_ego() const;
- const bool is_item_art() const;
- const bool is_item_equipped() const;
- const int item_freshness() const;
+ bool is_item_cursed() const;
+ bool is_item_glowing() const;
+ bool is_item_ego() const;
+ bool is_item_art() const;
+ bool is_item_equipped() const;
+ int item_freshness() const;
virtual int highlight_colour() const
{
diff --git a/crawl-ref/source/los.cc b/crawl-ref/source/los.cc
index 64f04818dc..2b00e30b20 100644
--- a/crawl-ref/source/los.cc
+++ b/crawl-ref/source/los.cc
@@ -91,7 +91,7 @@ bool double_is_zero(const double x)
return (x > -EPSILON_VALUE) && (x < EPSILON_VALUE);
}
-struct los_ray : ray_def
+struct los_ray : public ray_def
{
unsigned int start;
unsigned int length;
diff --git a/crawl-ref/source/losparam.cc b/crawl-ref/source/losparam.cc
index c0a3ed0298..833ee04003 100644
--- a/crawl-ref/source/losparam.cc
+++ b/crawl-ref/source/losparam.cc
@@ -1,6 +1,6 @@
/*
* File: losparam.h
- * Summary: Parameters for the LOS algorithm
+ * Summary: Parameters for the LOS algorithm
*/
#include "AppHdr.h"
@@ -92,11 +92,16 @@ unsigned short los_param_base::cloud_idx(const coord_def& p) const
opacity_type los_param_base::opacity(const coord_def& p) const
{
+ int m;
dungeon_feature_type f = feature(p);
if (grid_is_opaque(f))
return OPC_OPAQUE;
else if (is_opaque_cloud(cloud_idx(p)))
return OPC_HALF;
+ else if (f == DNGN_TREES)
+ return OPC_HALF;
+ else if ((m = mgrd(trans(p))) != NON_MONSTER && menv[m].type == MONS_BUSH)
+ return OPC_HALF;
else
return OPC_CLEAR;
}
diff --git a/crawl-ref/source/losparam.h b/crawl-ref/source/losparam.h
index 69e043e5fb..6dfac41dde 100644
--- a/crawl-ref/source/losparam.h
+++ b/crawl-ref/source/losparam.h
@@ -11,7 +11,7 @@ enum opacity_type
OPC_CLEAR,
OPC_HALF, // for opaque clouds; two or more block
OPC_OPAQUE,
-
+
NUM_OPACITIES
};
@@ -35,7 +35,7 @@ struct los_param
};
// Provides translation to given center and bounds checking.
-struct los_param_trans : los_param
+struct los_param_trans : public los_param
{
coord_def center;
@@ -47,7 +47,7 @@ struct los_param_trans : los_param
};
// Everything is visible.
-struct los_param_permissive : los_param_trans
+struct los_param_permissive : public los_param_trans
{
los_param_permissive(const coord_def& c);
@@ -56,7 +56,7 @@ struct los_param_permissive : los_param_trans
};
// Standard visibility disregarding clouds.
-struct los_param_nocloud : los_param_trans
+struct los_param_nocloud : public los_param_trans
{
los_param_nocloud(const coord_def& c);
@@ -66,7 +66,7 @@ struct los_param_nocloud : los_param_trans
};
// Standard visibility.
-struct los_param_base : los_param_nocloud
+struct los_param_base : public los_param_nocloud
{
los_param_base(const coord_def& c);
@@ -76,7 +76,7 @@ struct los_param_base : los_param_nocloud
// Like los_param_base, but any solid object blocks.
// This includes clear walls and statues.
-struct los_param_solid : los_param_base
+struct los_param_solid : public los_param_base
{
los_param_solid(const coord_def& c);
diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc
index a9e1fc855d..face8ab8d7 100644
--- a/crawl-ref/source/mapdef.cc
+++ b/crawl-ref/source/mapdef.cc
@@ -843,7 +843,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/mon-data.h b/crawl-ref/source/mon-data.h
index 106987988f..830ee12274 100644
--- a/crawl-ref/source/mon-data.h
+++ b/crawl-ref/source/mon-data.h
@@ -2520,6 +2520,17 @@ static monsterentry mondata[] = {
HT_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, MONEAT_NOTHING, SIZE_SMALL
},
+{
+ MONS_BUSH, 'P', BROWN, "bush",
+ M_NO_EXP_GAIN | M_STATIONARY,
+ MR_RES_POISON | MR_VUL_FIRE | MR_RES_ASPHYX,
+ 0, 10, MONS_PLANT, MONS_BUSH, MH_PLANT, MAG_IMMUNE,
+ { AT_NO_ATK, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK },
+ { 20, 3, 5, 0 },
+ 30, 0, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT,
+ HT_LAND, 0, DEFAULT_ENERGY, MONUSE_NOTHING, MONEAT_NOTHING, SIZE_BIG
+},
+
// queen insects ('Q')
{
MONS_QUEEN_BEE, 'Q', YELLOW, "queen bee",
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index e5c4cca512..f1562b5df7 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -25,6 +25,7 @@ REVISION("$Rev$");
#include "artefact.h"
#include "beam.h"
+#include "cloud.h"
#include "database.h"
#include "debug.h"
#include "delay.h"
@@ -644,6 +645,7 @@ bool mons_is_slime(const monsters *mon)
bool mons_class_is_plant(int mc)
{
return (mons_genus(mc) == MONS_PLANT
+ || mons_genus(mc) == MONS_BUSH
|| mons_genus(mc) == MONS_FUNGUS);
}
@@ -6292,7 +6294,11 @@ int monsters::hurt(const actor *agent, int amount, beam_type flavour,
// Allow the victim to exhibit passive damage behaviour (royal
// jelly).
- react_to_damage(amount, flavour);
+ kill_category whose = (agent == NULL) ? KC_OTHER :
+ (agent->atype() == ACT_PLAYER) ? KC_YOU :
+ mons_friendly_real((monsters*)agent) ? KC_FRIENDLY :
+ KC_OTHER;
+ react_to_damage(amount, flavour, whose);
}
if (cleanup_dead && (hit_points <= 0 || hit_dice <= 0) && type != -1)
@@ -8441,7 +8447,7 @@ item_type_id_state_type monsters::drink_potion_effect(potion_type ptype)
return (ident);
}
-void monsters::react_to_damage(int damage, beam_type flavour)
+void monsters::react_to_damage(int damage, beam_type flavour, kill_category whose)
{
if (!alive())
return;
@@ -8507,6 +8513,11 @@ void monsters::react_to_damage(int damage, beam_type flavour)
menv[number].hurt(&you, damage, flavour);
}
}
+ else if (type == MONS_BUSH && flavour == BEAM_FIRE
+ && damage>8 && x_chance_in_y(damage, 20))
+ {
+ place_cloud(CLOUD_FIRE, pos(), 20+random2(15), whose, 5);
+ }
}
/////////////////////////////////////////////////////////////////////////
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 8df057e503..e2c53a68a7 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -2531,6 +2531,54 @@ bool monster_blink(monsters *monster, bool quiet)
return (true);
}
+bool mon_can_be_slimified(monsters *monster)
+{
+ return (mons_holiness(monster) == MH_UNDEAD
+ || mons_holiness(monster) == MH_NATURAL
+ && !mons_is_slime(monster));
+}
+
+void slimify_monster(monsters *mon, bool hostile)
+{
+ if (mons_holiness(mon) == MH_UNDEAD)
+ monster_polymorph(mon, MONS_DEATH_OOZE);
+ else
+ {
+ const int x = mon->hit_dice + (coinflip() ? 1 : -1) * random2(5);
+
+ if (x < 3)
+ monster_polymorph(mon, MONS_OOZE);
+ else if (x >= 3 && x < 5)
+ monster_polymorph(mon, MONS_JELLY);
+ else if (x >= 5 && x < 7)
+ monster_polymorph(mon, MONS_BROWN_OOZE);
+ else if (x >= 7 && x <= 11)
+ {
+ if (coinflip())
+ monster_polymorph(mon, MONS_SLIME_CREATURE);
+ else
+ monster_polymorph(mon, MONS_GIANT_AMOEBA);
+ }
+ else
+ {
+ if (coinflip())
+ monster_polymorph(mon, MONS_ACID_BLOB);
+ else
+ monster_polymorph(mon, MONS_AZURE_JELLY);
+ }
+ }
+
+ if (!mons_eats_items(mon))
+ mon->add_ench(ENCH_EAT_ITEMS);
+
+ if (!hostile)
+ mon->attitude = ATT_STRICT_NEUTRAL;
+ else
+ mon->attitude = ATT_HOSTILE;
+
+ mons_make_god_gift(mon, GOD_JIYVA);
+}
+
static void _set_random_target(monsters* mon)
{
mon->target = random_in_bounds(); // If we don't find anything better
@@ -5451,6 +5499,7 @@ bool mons_avoids_cloud(const monsters *monster, cloud_struct cloud,
return (!mons_res_rotting(monster));
case CLOUD_FIRE:
+ case CLOUD_FOREST_FIRE:
if (mons_res_fire(monster) > 1)
return (false);
@@ -5533,12 +5582,12 @@ bool mons_avoids_cloud(const monsters *monster, cloud_struct cloud,
if (monster->flight_mode() != FL_NONE)
return (false);
- // These don't care about deep water.
+ // These don't care about deep water.
if (monster_habitable_grid(monster, DNGN_DEEP_WATER))
return (false);
// This position could become deep water, and they might drown.
- if (grd(cloud.pos) == DNGN_SHALLOW_WATER)
+ if (grd(cloud.pos) == DNGN_SHALLOW_WATER)
return (true);
// Otherwise, it's safe for everyone else.
@@ -8844,6 +8893,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);
@@ -9351,6 +9401,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)
@@ -9458,8 +9509,7 @@ static void _mons_in_cloud(monsters *monster)
hurted += ((4 * random2(3)) - random2(monster->ac));
wake = true;
}
-
- break;
+ break;
case CLOUD_MUTAGENIC:
simple_monster_message(monster, " is engulfed in a mutagenic fog!");
diff --git a/crawl-ref/source/monstuff.h b/crawl-ref/source/monstuff.h
index 22b7c3bbdd..b4995ab97e 100644
--- a/crawl-ref/source/monstuff.h
+++ b/crawl-ref/source/monstuff.h
@@ -96,6 +96,10 @@ int place_monster_corpse(const monsters *monster, bool silent,
void slime_vault_change(bool glass);
+void slimify_monster(monsters *monster, bool hostile = false);
+
+bool mon_can_be_slimified(monsters *monster);
+
void mons_check_pool(monsters *monster, const coord_def &oldpos,
killer_type killer = KILL_NONE, int killnum = -1);
diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc
index 27b382fa6c..e52ed53ea6 100644
--- a/crawl-ref/source/ouch.cc
+++ b/crawl-ref/source/ouch.cc
@@ -953,7 +953,7 @@ void ouch(int dam, int death_source, kill_method_type death_type,
dam -= you.magic_points;
dec_mp(you.magic_points);
}
-
+
if (dam >= you.hp)
{
if (harm_protection_type hpt = god_protects_from_harm(you.religion))
diff --git a/crawl-ref/source/output.cc b/crawl-ref/source/output.cc
index 7ec43683b7..6779e355c7 100644
--- a/crawl-ref/source/output.cc
+++ b/crawl-ref/source/output.cc
@@ -711,6 +711,12 @@ static void _get_status_lights(std::vector<status_light>& out)
out.push_back(status_light(color, "RoF"));
}
+ if (you.duration[DUR_SLIMIFY])
+ {
+ int color = _dur_colour(GREEN, dur_expiring(DUR_SLIMIFY));
+ out.push_back(status_light(color, "Slime"));
+ }
+
if (you.duration[DUR_SURE_BLADE])
out.push_back(status_light(BLUE, "Blade"));
@@ -2523,6 +2529,9 @@ std::string _status_mut_abilities()
"confusing touch"));
}
+ if (you.duration[DUR_SLIMIFY])
+ status.push_back(_get_expiration_string(DUR_SLIMIFY, "slimy"));
+
if (you.duration[DUR_SURE_BLADE])
status.push_back("bonded with blade");
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index f86d010662..d5591ef803 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -3925,6 +3925,7 @@ int get_expiration_threshold(duration_type dur)
case DUR_LEVITATION:
case DUR_TRANSFORMATION: // not on status
case DUR_DEATHS_DOOR: // not on status
+ case DUR_SLIMIFY:
return (10);
// These get no messages when they "flicker".
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index 270a4ca04b..1efd7f2d49 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -74,6 +74,7 @@ REVISION("$Rev$");
#include "state.h"
#include "stuff.h"
#include "terrain.h"
+#include "transfor.h"
#include "tutorial.h"
#include "view.h"
#include "xom.h"
@@ -1088,6 +1089,11 @@ static void _inc_penance(god_type god, int val)
if (you.duration[DUR_DIVINE_VIGOUR])
remove_divine_vigour();
}
+ else if (god == GOD_JIYVA)
+ {
+ if (you.duration[DUR_SLIMIFY])
+ you.duration[DUR_SLIMIFY] = 0;
+ }
if (you.religion == god)
{
@@ -5376,7 +5382,73 @@ static bool _jiyva_retribution()
{
const god_type god = GOD_JIYVA;
- if (!you.can_safely_mutate() || one_chance_in(4))
+ if (you.can_safely_mutate() && one_chance_in(7))
+ {
+ const int mutat = 1 + random2(3);
+
+ god_speaks(god, "You feel Jiyva alter your body.");
+
+ for (int i = 0; i < mutat; ++i)
+ mutate(RANDOM_BAD_MUTATION, true, false, true);
+ }
+ else if (there_are_monsters_nearby() && coinflip())
+ {
+ int tries = 0;
+ bool found_one = false;
+ monsters *mon;
+
+ while (tries < 10)
+ {
+ mon = choose_random_nearby_monster(0);
+
+ if (!mon || !mon_can_be_slimified(mon)
+ || mon->attitude != ATT_HOSTILE)
+ {
+ tries++;
+ continue;
+ }
+ else
+ {
+ found_one = true;
+ break;
+ }
+ }
+
+ if (found_one)
+ {
+ mprf(MSGCH_GOD, "Jiyva's putrescence saturates the %s!",
+ mon->name(DESC_NOCAP_THE).c_str());
+
+ slimify_monster(mon, true);
+ }
+ }
+ else if (!one_chance_in(3))
+ {
+ god_speaks(god, "Mutagenic energy floods into your body!");
+ contaminate_player(random2(you.penance[GOD_JIYVA]) / 2);
+
+ if (coinflip())
+ {
+ transformation_type form = TRAN_NONE;
+
+ switch (random2(3))
+ {
+ case 0:
+ form = TRAN_BAT;
+ break;
+ case 1:
+ form = TRAN_STATUE;
+ break;
+ case 2:
+ form = TRAN_SPIDER;
+ break;
+ }
+
+ if (transform(random2(you.penance[GOD_JIYVA]) * 2, form, true))
+ you.transform_cancellable = false;
+ }
+ }
+ else
{
const monster_type slimes[] = {
MONS_GIANT_EYEBALL, MONS_EYE_OF_DRAINING,
@@ -5391,10 +5463,10 @@ static bool _jiyva_retribution()
bool success = false;
for (int i = 0; i < how_many; ++i)
{
- const monster_type mon = RANDOM_ELEMENT(slimes);
+ const monster_type slime = RANDOM_ELEMENT(slimes);
if (create_monster(
- mgen_data::hostile_at(static_cast<monster_type>(mon),
+ mgen_data::hostile_at(static_cast<monster_type>(slime),
you.pos(), 0, 0, true, god)) != -1)
{
success = true;
@@ -5404,15 +5476,6 @@ static bool _jiyva_retribution()
god_speaks(god, success ? "Some slimes ooze up out of the ground!"
: "The ground quivers slightly.");
}
- else
- {
- const int mutat = 1 + random2(4);
-
- god_speaks(god, "You feel Jiyva alter your body.");
-
- for (int i = 0; i < mutat; ++i)
- mutate(RANDOM_BAD_MUTATION, true, false, true);
- }
return (true);
}
@@ -6834,11 +6897,14 @@ void excommunication(god_type new_god)
case GOD_JIYVA:
_jiyva_slimes_abandon_you();
+ if (you.duration[DUR_SLIMIFY])
+ you.duration[DUR_SLIMIFY] = 0;
+
if (you.can_safely_mutate())
{
god_speaks(old_god, "You feel Jiyva alter your body.");
- for (int i = 0; i < 4; ++i)
+ for (int i = 0; i < 2; ++i)
mutate(RANDOM_BAD_MUTATION, true, false, true);
}
diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc
index 4729730a1f..da5980878b 100644
--- a/crawl-ref/source/tags.cc
+++ b/crawl-ref/source/tags.cc
@@ -837,6 +837,7 @@ static void tag_construct_you(writer &th)
marshallByte(th, you.char_direction);
marshallByte(th, you.opened_zot);
marshallByte(th, you.royal_jelly_dead);
+ marshallByte(th, you.transform_cancellable);
marshallByte(th, you.your_level);
marshallByte(th, you.is_undead);
marshallShort(th, you.unrand_reacts);
@@ -1261,6 +1262,9 @@ static void tag_read_you(reader &th, char minorVersion)
if (minorVersion >= TAG_MINOR_JELLY)
you.royal_jelly_dead = (bool) unmarshallByte(th);
+ if (minorVersion >= TAG_MINOR_TRANS)
+ you.transform_cancellable = (bool) unmarshallByte(th);
+
you.your_level = unmarshallByte(th);
you.is_undead = static_cast<undead_state_type>(unmarshallByte(th));
you.unrand_reacts = unmarshallShort(th);
diff --git a/crawl-ref/source/tags.h b/crawl-ref/source/tags.h
index 8bce7f4c81..f303cf5b69 100644
--- a/crawl-ref/source/tags.h
+++ b/crawl-ref/source/tags.h
@@ -70,7 +70,8 @@ enum tag_minor_version
TAG_ANNOTATE_EXCL = 20, // Store exclusion information for annotations.
TAG_MINOR_UGLY = 21, // More ghost bits for (very) ugly things.
TAG_MINOR_ROTTING = 22, // Added monster-specific rotting resistance.
- TAG_MINOR_VERSION = 22 // Current version. (Keep equal to max.)
+ TAG_MINOR_TRANS = 23, // Keep track of cancellable transformations.
+ TAG_MINOR_VERSION = 23 // Current version. (Keep equal to max.)
};
diff --git a/crawl-ref/source/transfor.cc b/crawl-ref/source/transfor.cc
index fcadaef4dd..3330fe472b 100644
--- a/crawl-ref/source/transfor.cc
+++ b/crawl-ref/source/transfor.cc
@@ -524,6 +524,14 @@ bool transform(int pow, transformation_type which_trans, bool force,
if (!force && crawl_state.is_god_acting())
force = true;
+ if (!force && !you.transform_cancellable)
+ {
+ // Jiyva's wrath-induced transformation is blocking the attempt.
+ // May need to be updated if transform_cancellable is used for
+ // other uses.
+ return (false);
+ }
+
if (you.species == SP_MERFOLK && player_is_swimming()
&& which_trans != TRAN_DRAGON && which_trans != TRAN_BAT)
{
@@ -961,6 +969,8 @@ void untransform(bool skip_wielding)
handle_interrupted_swap(true, false, true);
you.turn_is_over = true;
+ if (!you.transform_cancellable)
+ you.transform_cancellable = true;
}
// XXX: This whole system is a mess as it still relies on special
diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc
index fef14e202b..9715c41e33 100644
--- a/crawl-ref/source/travel.cc
+++ b/crawl-ref/source/travel.cc
@@ -276,7 +276,7 @@ bool is_traversable(dungeon_feature_type grid)
return (traversable_terrain[grid] == TRAVERSABLE);
}
-struct los_param_excl : los_param_trans
+struct los_param_excl : public los_param_trans
{
los_param_excl(const coord_def& c) : los_param_trans(c) {}
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index 5a2d319397..e9499f2181 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -419,6 +419,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,
@@ -499,6 +509,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)
{
@@ -1636,6 +1648,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)
@@ -3001,7 +3014,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
},
@@ -3011,7 +3024,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
},
@@ -3021,7 +3034,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
},
@@ -3031,7 +3044,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
},
@@ -3047,7 +3060,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)
@@ -3143,6 +3156,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;