summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/dat/splev.des54
-rw-r--r--crawl-ref/source/dat/vaults.des19
-rw-r--r--crawl-ref/source/dungeon.cc35
-rw-r--r--crawl-ref/source/it_use3.cc22
-rw-r--r--crawl-ref/source/makefile.dos98
-rw-r--r--crawl-ref/source/makefile.mgw2
-rw-r--r--crawl-ref/source/makefile.unix8
-rw-r--r--crawl-ref/source/mapdef.cc10
-rw-r--r--crawl-ref/source/maps.cc40
-rw-r--r--crawl-ref/source/maps.h2
10 files changed, 244 insertions, 46 deletions
diff --git a/crawl-ref/source/dat/splev.des b/crawl-ref/source/dat/splev.des
index 0b8ebaca2d..660b1d6bd2 100644
--- a/crawl-ref/source/dat/splev.des
+++ b/crawl-ref/source/dat/splev.des
@@ -1,7 +1,7 @@
##############################################################################
# splev.des: special levels definitions.
#
-# If you want to define random vaults and minivaults they should go
+# If you want to define random vaults and minivaults, they should go
# to vaults.des.
#
# key:
@@ -80,12 +80,53 @@
# ps - remember to add one to the monster array value when placing monsters
# on each map (it is 1-7, not 0-6) {dlb}
#
+# [dshaligram] All special levels MUST have an ORIENT: attribute; if there's
+# no ORIENT: attribute, the level is considered to be a minivault, which is
+# usually not what you want.
+#
+# Special levels are selected either by PLACE: (for most special levels) or
+# TAGS: (for the Pandemonium demon lords). If you want to define alternate
+# levels, duplicate the selector and use different names. For instance, to
+# define an alternate Vestibule level, you could use something like this:
+#
+# NAME: vestibule_of_hell_alternate
+# PLACE: Hell
+#
+# To define an alternate level for Cerebov, you could do:
+#
+# NAME: cerebov_alternate
+# TAGS: cerebov
+#
+# You can also use CHANCE: to control the weight a level is assigned. For
+# instance, if you want to make cerebov_alternate five times more likely than
+# the standard cerebov level, you'd do:
+#
+# NAME: cerebov_alternate
+# TAGS: cerebov
+# CHANCE: 50
+#
+# (The default weight is 10 if CHANCE: is omitted.)
+#
##############################################################################
NAME: vestibule_of_hell
PLACE: Hell
ORIENT: encompass
+# [dshaligram] If modifying the Vestibule, ensure that:
+#
+# * The portal to Dis is surrounded by floor squares and nothing but floor
+# squares.
+# * The portal to Tartarus is surrounded only by floor, doors of any kind, and
+# at least one rock wall.
+# * The portal to Gehenna is surrounded by nothing but floor and at least one
+# lava square.
+# * The portal to Cocytus is surrounded by nothing but floor and at least one
+# water square.
+#
+# If you don't do this, the portals will not be unbarred correctly when
+# Geryon's horn is sounded.
+
MAP
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
@@ -468,11 +509,15 @@ MONS: skeleton_small, Shadow Fiend
###########################################################################
# mnoleg.
#
-# NOTE: The Pandemonium demonlord levels are requested by name; if you change
-# the name, also update dungeon.cc.
+# NOTE: The Pandemonium demonlord levels are requested by tag; if you change
+# the tag, also update dungeon.cc.
+#
+# You can define alternate levels for a Pandemonium lord by using the same
+# TAGS: and a different NAME:
#
NAME: mnoleg
+TAGS: mnoleg
ORIENT: northeast
MAP
@@ -522,6 +567,7 @@ MONS: random, random, random, random, random
#
NAME: lom_lobon
+TAGS: lom_lobon
ORIENT: north
MAP
@@ -570,6 +616,7 @@ MONS: random, random, random
# cerebov
NAME: cerebov
+TAGS: cerebov
ORIENT: northeast
# you might not want to teleport too much on this level - unless you can
@@ -622,6 +669,7 @@ MONS: random, random, random, random
# Gloorx Vloq
NAME: gloorx_vloq
+TAGS: gloorx_vloq
ORIENT: southwest
MAP
diff --git a/crawl-ref/source/dat/vaults.des b/crawl-ref/source/dat/vaults.des
index b0aaeaff3a..e4c96343fc 100644
--- a/crawl-ref/source/dat/vaults.des
+++ b/crawl-ref/source/dat/vaults.des
@@ -78,6 +78,10 @@
# ps - remember to add one to the monster array value when placing monsters
# on each map (it is 1-7, not 0-6) {dlb}
#
+# [dshaligram] All vaults MUST have an ORIENT: attribute; if there's no
+# ORIENT: attribute, the vault is considered to be a minivault, which is
+# usually not what you want.
+#
##############################################################################
default-depth: 1-27
@@ -828,16 +832,20 @@ ENDMAP
##############################################################################
# Minivaults
##############################################################################
-
+#
# NOTE: *Cannot* place 8,9 or 0 monsters in branch vaults which neither use the
# normal mons_level function or are around level 35, or generation will crash.
-
+#
# [dshaligram] Minivaults were traditionally drawn after rotating the vault by
# 90 degrees anticlockwise. Under the new dungeon vault handling, the map may
# be freely rotated and mirrored to any position (20061105).
#
-# Minivaults are traditionally 12x12 (hardcoded limitation in dungeon.cc. Under
-# the new rules they can be any size, but the smaller the better.
+# Minivaults are traditionally 12x12 (hardcoded limitation in dungeon.cc). Under
+# the new rules they can be any size, but the smaller the better. I'd recommend
+# no larger than 35x30 or so.
+#
+# NOTE: Minivaults must NOT have an ORIENT: attribute. Including an ORIENT:
+# attribute makes the map a normal vault, and mayhem can result.
NAME: minivault_1
@@ -879,6 +887,9 @@ ENDMAP
NAME: minitemple
+# More common than the others.
+CHANCE: 20
+
MAP
............
.cccccccccc.
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index f7fe994f19..f210d817e0 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -142,7 +142,6 @@ static void jelly_pit(int level_number, spec_room &sr);
// VAULT FUNCTIONS
static void build_vaults(int level_number, int vault_number);
-static void build_vaults(int level_number, const std::string &vname);
static void build_minivaults(int level_number, int force_vault);
static int vault_grid( int level_number, int vx, int vy, int altar_count,
FixedVector < char, 7 > &acq_item_class,
@@ -3728,7 +3727,19 @@ static int builder_by_type(int level_number, char level_type)
"mnoleg", "lom_lobon", "cerebov", "gloorx_vloq"
};
you.unique_creatures[40 + which_demon] = 1;
- build_vaults(level_number, pandemon_level_names[(int) which_demon]);
+
+ const int vault =
+ random_map_for_tag(pandemon_level_names[(int) which_demon]);
+
+ ASSERT(vault != -1);
+ if (vault == -1)
+ {
+ fprintf(stderr, "Failed to find Pandemonium level %s!\n",
+ pandemon_level_names[(int) which_demon]);
+ exit(1);
+ }
+
+ build_vaults(level_number, vault);
}
else
{
@@ -3761,9 +3772,9 @@ static int builder_by_branch(int level_number)
if (subdepth == branch_depth( branch_stair(you.where_are_you) ))
altname = level_name(0);
- int vault = find_map_for(name);
+ int vault = random_map_for_place(name);
if (vault == -1)
- vault = find_map_for(altname);
+ vault = random_map_for_place(altname);
if (vault != -1)
{
@@ -3812,7 +3823,7 @@ static int builder_normal(int level_number, char level_type, spec_room &sr)
bool skipped = false;
bool done_city = false;
- int vault = find_map_for(
+ int vault = random_map_for_place(
level_name(
subdungeon_depth(you.where_are_you, level_number)));
@@ -5273,20 +5284,6 @@ static void build_minivaults(int level_number, int force_vault)
}
} // end build_minivaults()
-static void build_vaults(int level_number, const std::string &name)
-{
- int vault = find_map_named(name);
- ASSERT(vault != -1);
-
- if (vault == -1)
- {
- fprintf(stderr, "Unable to find map named %s\n", name.c_str());
- exit(1);
- }
-
- build_vaults(level_number, vault);
-}
-
static void build_vaults(int level_number, int force_vault)
{
// for some weird reason can't put a vault on level 1, because monster equip
diff --git a/crawl-ref/source/it_use3.cc b/crawl-ref/source/it_use3.cc
index 8dc95960b0..6ffea41ef5 100644
--- a/crawl-ref/source/it_use3.cc
+++ b/crawl-ref/source/it_use3.cc
@@ -581,8 +581,28 @@ bool evoke_wielded( void )
{
opened_gates++;
+ // [dshaligram] New approach to placing Hell
+ // portals to handle the possibility of a mirrored
+ // Vestibule.
+ int surround_grid = DNGN_FLOOR;
+
+ for (int y = -1; y <= 1; ++y)
+ for (int x = -1; x <= 1; ++x)
+ {
+ if (!x && !y)
+ continue;
+ const int grid =
+ grd[count_x + x][count_y + y];
+
+ if (grid != DNGN_FLOOR
+ && grid != DNGN_SECRET_DOOR
+ && grid != DNGN_CLOSED_DOOR
+ && grid != DNGN_OPEN_DOOR)
+ surround_grid = grid;
+ }
+
// this may generate faulty [][] values {dlb}
- switch (grd[count_x + 2][count_y])
+ switch (surround_grid)
{
case DNGN_FLOOR:
grd[count_x][count_y] = DNGN_ENTER_DIS;
diff --git a/crawl-ref/source/makefile.dos b/crawl-ref/source/makefile.dos
index 3da25c2ecf..00900e1707 100644
--- a/crawl-ref/source/makefile.dos
+++ b/crawl-ref/source/makefile.dos
@@ -24,10 +24,100 @@ LDFLAGS =
LIB =
# LIB = -lcurso -lpano
+UTIL = util/
+
+# If you don't have flex or bison, set DOYACC to N or empty.
+DOYACC := y
+
+LEX := flex
+YACC := bison -y
+
+# DOS brain damage. What to do, what to do.
+YTABC := levcom~1.c
+YTABH := levcom~1.h
+
+ifeq ($(LEX),)
+DOYACC :=
+endif
+
+ifeq ($(YACC),)
+DOYACC :=
+endif
+
+GAME_DEPENDS := compile-levels $(OBJECTS)
+
+##########################################################################
+
all: $(APPNAME)
+##########################################################################
+# The level compiler
+#
+compile-levels: $(UTIL)levcomp.exe mapdefs.ixx
+
+mapdefs.ixx: dat\vaults.des dat\splev.des $(UTIL)levcomp.exe
+ $(subst /,\,$(UTIL)levcomp.exe $@ < dat\vaults.des)
+ $(subst /,\,$(UTIL)levcomp.exe -a $@ < dat\splev.des)
+
+$(UTIL)levcomp.exe: $(UTIL)levcomp.o $(UTIL)levtab.o \
+ $(UTIL)levlex.o mapdef.o
+ $(CXX) -o $@ $^
+
+# [dshaligram] A million plagues on djgpp make! It doesn't want to use a
+# generic rule for $(UTIL)%.cc; it always uses the .cc.o: rule instead.
+
+LINC := -I $(subst /,,$(UTIL)) -I.
+
+# [ds] If we're using the prebuilt include, we can't copy it around because
+# djgpp copy mangles the name irreparably.
+ifneq ($(DOYACC),y)
+LINC += -I prebuilt
+endif
+
+$(UTIL)levcomp.o: $(UTIL)levcomp.cc
+ $(subst /,\,$(CXX) $(LINC) -o $@ -c $<)
+
+$(UTIL)levlex.o: $(UTIL)levlex.cc
+ $(subst /,\,$(CXX) $(LINC) -o $@ -c $<)
+
+$(UTIL)levtab.o: $(UTIL)levtab.cc
+ $(subst /,\,$(CXX) $(LINC) -o $@ -c $<)
+
+ifeq ($(DOYACC),y)
+
+$(UTIL)levtab.cc: $(UTIL)levcomp.ypp
+ $(subst /,\,cd $(UTIL))
+ $(YACC) -d -b levcomp levcomp.ypp
+ copy $(YTABC) levtab.cc
+ cd ..
+
+# djgpp flex must not have a space between -o and its parameter, or no business
+# will result.
+$(UTIL)levlex.cc: $(UTIL)levcomp.lpp
+ $(subst /,\,cd $(UTIL))
+ $(LEX) -olevlex.cc levcomp.lpp
+ cd ..
+
+else
+
+$(UTIL)levtab.cc: prebuilt/levcom~2.cc
+ $(subst /,\,$(COPY) $< $@)
+
+$(UTIL)levlex.cc: prebuilt/levcom~1.cc
+ $(subst /,\,$(COPY) $< $@)
+
+endif
+
+##########################################################################
+
clean:
$(DELETE) *.o
+ $(subst /,\,$(DELETE) $(UTIL)*.o)
+ $(subst /,\,$(DELETE) $(UTIL)*.exe)
+ $(subst /,\,$(DELETE) $(UTIL)levcom~1.*)
+ $(subst /,\,$(DELETE) $(UTIL)levtab.*)
+ $(subst /,\,$(DELETE) $(UTIL)levlex.*)
+ $(DELETE) *.ixx
distclean:
$(DELETE) *.o
@@ -40,16 +130,18 @@ distclean:
$(DELETE) *.0*
$(DELETE) *.lab
-$(APPNAME): $(OBJECTS)
+$(APPNAME): $(GAME_DEPENDS)
${CXX} ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(APPNAME) $(LIB)
strip $(APPNAME)
-debug: $(OBJECTS)
+debug: $(GAME_DEPENDS)
${CXX} ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(APPNAME) $(LIB)
-profile: $(OBJECTS)
+profile: $(GAME_DEPENDS)
${CXX} -g -p ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(APPNAME) $(LIB)
+maps.o: mapdefs.ixx
+
.cc.o:
${CXX} ${CFLAGS} -c $< ${INCLUDE}
diff --git a/crawl-ref/source/makefile.mgw b/crawl-ref/source/makefile.mgw
index b4da9d91c9..ccd1c708f6 100644
--- a/crawl-ref/source/makefile.mgw
+++ b/crawl-ref/source/makefile.mgw
@@ -84,7 +84,7 @@ $(UTIL)levcomp.tab.cc: $(UTIL)levcomp.ypp
$(subst /,\, cd $(UTIL)) && $(YACC) -d -b levcomp levcomp.ypp
$(subst /,\, cd $(UTIL)) && move $(YTABC) levcomp.tab.cc
-$(UTIL)levcomp_lex.cc: $(UTIL)levcomp.lpp
+$(UTIL)levcomp.lex.cc: $(UTIL)levcomp.lpp
$(subst /,\, cd $(UTIL) && $(LEX) -olevcomp.lex.cc levcomp.lpp)
else
diff --git a/crawl-ref/source/makefile.unix b/crawl-ref/source/makefile.unix
index 75abff9d5b..0e2e3decb3 100644
--- a/crawl-ref/source/makefile.unix
+++ b/crawl-ref/source/makefile.unix
@@ -60,7 +60,8 @@ SRC_PKG_ZIP := $(PKG_SRC_DIR).zip
LEVCOMP := $(UTIL)levcomp
-PKG_TIDY_LIST := $(UTIL)*.o $(LEVCOMP) *.o $(LEVCOMP)*.cc $(LEVCOMP)*.h *.ixx
+PKG_TIDY_LIST := $(UTIL)*.o $(LEVCOMP) *.o \
+ $(UTIL)*.tab.cc $(UTIL)*.tab.h $(UTIL)*.lex.cc *.ixx
PKG_EXCLUDES := $(PWD)/misc/src-pkg-excludes.lst
##########################################################################
@@ -123,8 +124,7 @@ clean:
$(DELETE) $(UTIL)*.tab.cc $(UTIL)*.tab.c $(UTIL)*.tab.h $(UTIL)*.lex.cc
$(DELETE) *.ixx
-distclean:
- $(DELETE) *.o
+distclean: clean
$(DELETE) bones.*
$(DELETE) morgue.txt
$(DELETE) scores
@@ -145,7 +145,7 @@ profile: $(GAME_DEPENDS)
${CXX} -g -p ${LDFLAGS} $(INCLUDES) $(CFLAGS) $(OBJECTS) -o $(GAME) $(LIB)
# [ds] maps.cc now includes mapdefs.ixx, so add a dependency.
-$(OPATH)/maps.o: mapdefs.ixx
+maps.o: mapdefs.ixx
.cc.o:
${CXX} ${CFLAGS} -c $< ${INCLUDE}
diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc
index 3a185fad20..02843caaaf 100644
--- a/crawl-ref/source/mapdef.cc
+++ b/crawl-ref/source/mapdef.cc
@@ -30,17 +30,19 @@ std::string clean_string(std::string s, const std::string &tokill)
return (s);
}
+// [dshaligram] Use sprintf to compile on DOS without having to pull in
+// libutil.cc. The buffers used should be more than sufficient.
static std::string to_s(int num)
{
- char buf[20];
- snprintf(buf, sizeof buf, "%d", num);
+ char buf[100];
+ sprintf(buf, "%d", num);
return (buf);
}
static std::string to_sl(long num)
{
- char buf[20];
- snprintf(buf, sizeof buf, "%ld", num);
+ char buf[100];
+ sprintf(buf, "%ld", num);
return (buf);
}
diff --git a/crawl-ref/source/maps.cc b/crawl-ref/source/maps.cc
index 5c1d5ca354..7b8ff1f529 100644
--- a/crawl-ref/source/maps.cc
+++ b/crawl-ref/source/maps.cc
@@ -185,16 +185,34 @@ static int apply_vault_definition(
// Map lookups
// Returns a map for which PLACE: matches the given place.
-int find_map_for(const std::string &place)
+int random_map_for_place(const std::string &place, bool want_minivault)
{
if (place.empty())
return (-1);
+ int mapindex = -1;
+ int rollsize = 0;
+
for (unsigned i = 0; i < sizeof(vdefs) / sizeof(*vdefs); ++i)
- if (vdefs[i].place == place)
- return (i);
+ {
+ // We also accept tagged levels here.
+ if (vdefs[i].place == place
+ && ((vdefs[i].orient == MAP_NONE) == want_minivault))
+ {
+ rollsize += vdefs[i].chance;
- return (-1);
+ if (rollsize && random2(rollsize) < vdefs[i].chance)
+ mapindex = i;
+ }
+ }
+
+#ifdef DEBUG_DIAGNOSTICS
+ if (mapindex != -1)
+ mprf(MSGCH_DIAGNOSTICS, "Found map %s for %s",
+ vdefs[mapindex].name.c_str(), place.c_str());
+#endif
+
+ return (mapindex);
}
int find_map_named(const std::string &name)
@@ -240,6 +258,7 @@ int random_map_for_tag(std::string tag)
int rollsize = 0;
for (unsigned i = 0; i < sizeof(vdefs) / sizeof(*vdefs); ++i)
+ {
if (vdefs[i].tags.find(tag) != std::string::npos)
{
rollsize += vdefs[i].chance;
@@ -247,6 +266,15 @@ int random_map_for_tag(std::string tag)
if (rollsize && random2(rollsize) < vdefs[i].chance)
mapindex = i;
}
+ }
+
+#ifdef DEBUG_DIAGNOSTICS
+ if (mapindex != -1)
+ mprf(MSGCH_DIAGNOSTICS, "Found map %s tagged%s",
+ vdefs[mapindex].name.c_str(), tag.c_str());
+ else
+ mprf(MSGCH_DIAGNOSTICS, "No map for tag%s", tag.c_str());
+#endif
return (mapindex);
}
@@ -254,8 +282,8 @@ int random_map_for_tag(std::string tag)
/////////////////////////////////////////////////////////////////////////////
// map_def
// map_def functions that can't be implemented in mapdef.cc because that'll pull
-// in functions from lots of other places and make compiling levcomp unnecessarily
-// painful
+// in functions from lots of other places and make compiling levcomp
+// unnecessarily painful
void map_def::hmirror()
{
diff --git a/crawl-ref/source/maps.h b/crawl-ref/source/maps.h
index e9ec8fb48e..b30eb49d9a 100644
--- a/crawl-ref/source/maps.h
+++ b/crawl-ref/source/maps.h
@@ -32,7 +32,7 @@ int vault_main(map_type vgrid,
int vault_force,
int many_many);
-int find_map_for(const std::string &place);
+int random_map_for_place(const std::string &place, bool mini = false);
int find_map_named(const std::string &name);
int random_map_for_depth(int depth, bool want_minivault = false);
int random_map_for_tag(std::string tag);