diff options
-rw-r--r-- | crawl-ref/source/dat/splev.des | 54 | ||||
-rw-r--r-- | crawl-ref/source/dat/vaults.des | 19 | ||||
-rw-r--r-- | crawl-ref/source/dungeon.cc | 35 | ||||
-rw-r--r-- | crawl-ref/source/it_use3.cc | 22 | ||||
-rw-r--r-- | crawl-ref/source/makefile.dos | 98 | ||||
-rw-r--r-- | crawl-ref/source/makefile.mgw | 2 | ||||
-rw-r--r-- | crawl-ref/source/makefile.unix | 8 | ||||
-rw-r--r-- | crawl-ref/source/mapdef.cc | 10 | ||||
-rw-r--r-- | crawl-ref/source/maps.cc | 40 | ||||
-rw-r--r-- | crawl-ref/source/maps.h | 2 |
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); |