summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2008-11-19 18:02:31 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2008-11-19 18:02:31 +0000
commit6e304ee422e24338bde6ca84c420702d7d719993 (patch)
tree08bee3585e67a17a8b946df063185136cd95d148
parentdb54671af1f255d5f886ff79ffe8b2232585f1c3 (diff)
downloadcrawl-ref-6e304ee422e24338bde6ca84c420702d7d719993.tar.gz
crawl-ref-6e304ee422e24338bde6ca84c420702d7d719993.zip
Separate CHANCE and WEIGHT. CHANCE is a probability, WEIGHT is a raw number used as a generation weight (i.e. WEIGHT is what the old CHANCE used to be).
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7501 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r--crawl-ref/docs/level_design.txt64
-rw-r--r--crawl-ref/source/dat/altar.des10
-rw-r--r--crawl-ref/source/dat/bazaar.des40
-rw-r--r--crawl-ref/source/dat/clua/loadmaps.lua11
-rw-r--r--crawl-ref/source/dat/elf.des6
-rw-r--r--crawl-ref/source/dat/entry.des172
-rw-r--r--crawl-ref/source/dat/float.des8
-rw-r--r--crawl-ref/source/dat/hive.des12
-rw-r--r--crawl-ref/source/dat/lab.des12
-rw-r--r--crawl-ref/source/dat/lair.des24
-rw-r--r--crawl-ref/source/dat/large.des6
-rw-r--r--crawl-ref/source/dat/mini.des24
-rw-r--r--crawl-ref/source/dat/orc.des8
-rw-r--r--crawl-ref/source/dat/sewer.des2
-rw-r--r--crawl-ref/source/dat/temple.des18
-rw-r--r--crawl-ref/source/dat/vaults.des2
-rw-r--r--crawl-ref/source/dat/zot.des2
-rw-r--r--crawl-ref/source/debug.cc3
-rw-r--r--crawl-ref/source/dungeon.cc21
-rw-r--r--crawl-ref/source/luadgn.cc25
-rw-r--r--crawl-ref/source/mapdef.cc33
-rw-r--r--crawl-ref/source/mapdef.h6
-rw-r--r--crawl-ref/source/maps.cc321
-rw-r--r--crawl-ref/source/maps.h2
-rw-r--r--crawl-ref/source/util/levcomp.lpp8
-rw-r--r--crawl-ref/source/util/levcomp.ypp38
26 files changed, 581 insertions, 297 deletions
diff --git a/crawl-ref/docs/level_design.txt b/crawl-ref/docs/level_design.txt
index 95cce6b6c4..f8c9932d1d 100644
--- a/crawl-ref/docs/level_design.txt
+++ b/crawl-ref/docs/level_design.txt
@@ -298,12 +298,62 @@ DEPTH: For random vaults, branch entry vaults, and minivaults, this
have no DEPTH: constraint. Note that maps without a DEPTH: constraint
cannot be selected as random vaults or minivaults.
-CHANCE: (number with 10 being default)
+CHANCE: <priority>:<roll> or <roll>
+
+ CHANCE allows you to control the probability that your map
+ is used on any given level with an absolute roll.
+
+ There are two ways to specify the CHANCE roll:
+
+ CHANCE: 500
+ or
+ CHANCE: 5%
+
+ If specified as a raw number, the chance of selecting the
+ vault is <number> in 10000. If specified as a percentage,
+ the chance of selecting the vault is <perc> * 100 in 10000.
+ Note that CHANCE accepts only integers, no fractions or
+ decimals.
+
+ For any map with alternatives, a CHANCE influences how
+ likely the map is to be picked instead of the alternatives.
+ If a map has a CHANCE, Crawl will roll a random number in
+ the range 1-10000, and select the map if the CHANCE is >=
+ the rolled random number.
+
+ If there are multiple alternative maps with CHANCE, they
+ will be tested in an unspecified order; the first map that
+ makes the CHANCE roll will be used. If you'd like to specify
+ an order of testing CHANCEs, specify a CHANCE with a
+ priority:
+
+ CHANCE: 10 : 20%
+
+ This specifies a CHANCE of 20%, with a priority of 10, which
+ means this vault will be checked before any other vault with
+ a lower priority (the default priority is 0).
+
+ If no map with a CHANCE is picked, Crawl will select a map
+ based on WEIGHT, ignoring vaults with a CHANCE set.
+
+ Note that the Lua equivalent for CHANCE is a two-argument
+ function:
+
+ : chance(<priority>, <number>)
+
+ These lines are all equivalent:
+ CHANCE: 5%
+ CHANCE: 500
+ CHANCE: 0 : 5%
+ CHANCE: 0 : 500
+ : chance(0, 500)
+
+WEIGHT: (number with 10 being default)
For entry vaults and any other vaults randomly picked from among
a set, this type of line affects the likelihood of the given vault
- being picked in a given game. The default CHANCE: is 10. The
+ being picked in a given game. The default WEIGHT: is 10. The
likelihood of a vault getting picked is:
- [vault's CHANCE: / sum of all CHANCE:s of vaults of that type]
+ [vault's WEIGHT: / sum of all WEIGHT:s of vaults of that type]
PLACE: Used to specify certain special levels. Existing special levels
include most branch ends.
@@ -1042,7 +1092,7 @@ G. Hints for level makers
The same goes for traps. This is much less so if there are several places
for the chamber (or trap) and there's even a chance it doesn't exist.
- You can also use CHANCE to create modified versions of the same map. In
+ You can also use WEIGHT to create modified versions of the same map. In
order to do this, make several maps and endow each with a chance such
that the sum of chances add up to 10.
@@ -1068,13 +1118,13 @@ G. Hints for level makers
necromancy) is even better.
* Testing your maps.
- This is easy for entry vaults. Temporarily introducing a CHANCE: 50000
+ This is easy for entry vaults. Temporarily introducing a WEIGHT: 50000
will make your entry appear almost always. For other vaults, you can
- for the moment declare them as entry vaults with a huge CHANCE: as
+ for the moment declare them as entry vaults with a huge WEIGHT: as
above (and preferably in wizard mode). For more intricate things like
new branch ends, you have to resort to wizard mode and use the &~ command
to go directly to the place where the map is used, say Snake:5. You may want
- to use a high CHANCE: again, if the map has alternatives (like Snake:5, or
+ to use a high WEIGHT: again, if the map has alternatives (like Snake:5, or
Coc:7). Minivaults can also be tested by adding a PLACE: to the definition,
which makes it very likely that the minivault will appear in the chosen
level.
diff --git a/crawl-ref/source/dat/altar.des b/crawl-ref/source/dat/altar.des
index 76b7b8981e..d02c6001f6 100644
--- a/crawl-ref/source/dat/altar.des
+++ b/crawl-ref/source/dat/altar.des
@@ -17,7 +17,7 @@
NAME: minitemple
TAGS: allow_dup
# More common than the others.
-CHANCE: 20
+WEIGHT: 20
MAP
cccccccccc
cBcBcBcBcc
@@ -113,7 +113,7 @@ ENDMAP
NAME: lemuel_altar_in_water
DEPTH: D:2-18, Swamp, Shoal
-CHANCE: 9
+WEIGHT: 9
: local brnd = crawl.random2(13)
: if brnd > 10 then
TAGS: no_monster_gen no_rotate
@@ -138,7 +138,7 @@ ENDMAP
NAME: lemuel_altar_in_water2
TAGS: no_pool_fixup no_monster_gen
DEPTH: D:2-18, Lair, Snake, Swamp, Shoal
-CHANCE: 1
+WEIGHT: 1
MAP
www
wwwww
@@ -176,7 +176,7 @@ MAP
ENDMAP
NAME: lemuel_sealed_altar_a
-CHANCE: 3
+WEIGHT: 3
DEPTH: D:2-18, Vault, Elf, Crypt
MAP
xxxxxxxxxxxxx
@@ -194,7 +194,7 @@ xxxxxxxxxxxxx
ENDMAP
NAME: lemuel_sealed_altar_b
-CHANCE: 7
+WEIGHT: 7
DEPTH: D:2-18, Vault, Elf, Crypt
MAP
xxxxxxxxxxx
diff --git a/crawl-ref/source/dat/bazaar.des b/crawl-ref/source/dat/bazaar.des
index 6ea205b1bc..500160406e 100644
--- a/crawl-ref/source/dat/bazaar.des
+++ b/crawl-ref/source/dat/bazaar.des
@@ -209,7 +209,7 @@ ENDMAP
NAME: bazaar_general_marketplace
TAGS: bazaar allow_dup no_rotate
ORIENT: encompass
-CHANCE: 5
+WEIGHT: 5
KFEAT: A = any shop
: bazaar_message(_G)
MAP
@@ -236,7 +236,7 @@ ENDMAP
NAME: bazaar_outfitter
TAGS: bazaar allow_dup
ORIENT: encompass
-CHANCE: 5
+WEIGHT: 5
KFEAT: A = any shop
SHUFFLE: ABC, de
KFEAT: A = weapon shop / armour shop
@@ -262,7 +262,7 @@ ENDMAP
# 4 random shops
NAME: bazaar_oval
TAGS: bazaar allow_dup no_rotate
-CHANCE: 5
+WEIGHT: 5
ORIENT: encompass
SUBST: A = TVBG
KFEAT: B = any shop
@@ -282,7 +282,7 @@ ENDMAP
# 2 shops
NAME: bazaar_mystics
TAGS: bazaar allow_dup
-CHANCE: 5
+WEIGHT: 5
ORIENT: encompass
SUBST: w : wlx
SHUFFLE: AB, def
@@ -452,7 +452,7 @@ ENDMAP
# circle bazaar
# 5 shops
NAME: bazaar_circle_1
-CHANCE: 2
+WEIGHT: 2
TAGS: bazaar allow_dup no_rotate
ORIENT: encompass
SHUFFLE: ABCD, EFGH
@@ -492,7 +492,7 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ENDMAP
NAME: bazaar_circle_2
-CHANCE: 2
+WEIGHT: 2
TAGS: bazaar allow_dup no_rotate
ORIENT: encompass
SHUFFLE: EFGH
@@ -532,7 +532,7 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ENDMAP
NAME: bazaar_circle_3
-CHANCE: 2
+WEIGHT: 2
TAGS: bazaar allow_dup no_rotate
ORIENT: encompass
SHUFFLE: EFGH
@@ -572,7 +572,7 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ENDMAP
NAME: bazaar_circle_4
-CHANCE: 1
+WEIGHT: 1
TAGS: bazaar allow_dup no_rotate
ORIENT: encompass
SHUFFLE: ABCDEF
@@ -611,7 +611,7 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ENDMAP
NAME: bazaar_circle_5
-CHANCE: 2
+WEIGHT: 2
TAGS: bazaar allow_dup no_rotate
ORIENT: encompass
KFEAT: C = any shop
@@ -649,7 +649,7 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ENDMAP
NAME: bazaar_circle_6
-CHANCE: 1
+WEIGHT: 1
TAGS: bazaar allow_dup no_rotate
ORIENT: encompass
KFEAT: A = any shop / antique armour shop
@@ -796,7 +796,7 @@ ENDMAP
# ~3 shops
NAME: bazaar_cross1
TAGS: bazaar allow_dup no_rotate
-CHANCE: 2
+WEIGHT: 2
ORIENT: encompass
SHUFFLE: ABCD
SUBST: A = <, B = >
@@ -827,7 +827,7 @@ ENDMAP
NAME: bazaar_cross2
TAGS: bazaar allow_dup no_rotate
-CHANCE: 3
+WEIGHT: 3
ORIENT: encompass
SHUFFLE: ABCD
SUBST: A = T E, B = >
@@ -909,7 +909,7 @@ ENDMAP
# 5 shops
NAME: bazaar_ninerooms1
TAGS: bazaar allow_dup no_rotate
-CHANCE: 2
+WEIGHT: 2
ORIENT: encompass
SUBST: k : . x
NSUBST: A = 2=T:30 V / *:C
@@ -946,7 +946,7 @@ ENDMAP
NAME: bazaar_ninerooms2
TAGS: bazaar allow_dup no_rotate
-CHANCE: 2
+WEIGHT: 2
ORIENT: encompass
SUBST: k : . x
NSUBST: A = 2=T:30 V / *:C
@@ -983,7 +983,7 @@ ENDMAP
NAME: bazaar_ninerooms3
TAGS: bazaar allow_dup no_rotate
-CHANCE: 2
+WEIGHT: 2
ORIENT: encompass
SUBST: z = .:50 +
SUBST: k : . x
@@ -1021,7 +1021,7 @@ ENDMAP
NAME: bazaar_ninerooms4
TAGS: bazaar allow_dup no_rotate
-CHANCE: 2
+WEIGHT: 2
ORIENT: encompass
SUBST: z = .:50 +
SUBST: k : . x
@@ -1059,7 +1059,7 @@ ENDMAP
NAME: bazaar_ninerooms5
TAGS: bazaar allow_dup no_rotate
-CHANCE: 2
+WEIGHT: 2
ORIENT: encompass
SUBST: k : . x
NSUBST: A = 1:< / 1:> / 1:T C / 3=T:30 V / *:C
@@ -1100,7 +1100,7 @@ ENDMAP
NAME: bazaar_triangles
TAGS: bazaar allow_dup no_rotate
ORIENT: encompass
-CHANCE: 1
+WEIGHT: 1
SHUFFLE: ACD
SUBST: A = <
KFEAT: B = any shop / antique armour shop / jewellery shop
@@ -1122,7 +1122,7 @@ ENDMAP
NAME: bazaar_hexagon
TAGS: bazaar allow_dup no_rotate
ORIENT: encompass
-CHANCE: 4
+WEIGHT: 4
SHUFFLE: AC, BD
KFEAT: A = armour shop / weapon shop / wand shop
KFEAT: B = general shop / food shop
@@ -1152,7 +1152,7 @@ ENDMAP
NAME: bazaar_triangle_bulge
TAGS: bazaar allow_dup no_rotate
ORIENT: encompass
-CHANCE: 5
+WEIGHT: 5
SHUFFLE: ABC
SUBST: A = <, B = >
KFEAT: C = any shop
diff --git a/crawl-ref/source/dat/clua/loadmaps.lua b/crawl-ref/source/dat/clua/loadmaps.lua
index 0e12ed4313..2f6b617635 100644
--- a/crawl-ref/source/dat/clua/loadmaps.lua
+++ b/crawl-ref/source/dat/clua/loadmaps.lua
@@ -7,10 +7,13 @@
------------------------------------------------------------------------------
local des_files = {
- "altar.des", "bazaar.des", "entry.des", "elf.des", "float.des", "hells.des",
- "hive.des", "lab.des", "lair.des", "large.des", "layout.des", "mini.des",
- "orc.des", "pan.des", "sewer.des", "temple.des", "vaults.des", "crypt.des",
- "zot.des"
+ -- The dummy vaults that define global vault generation odds.
+ "dummy.des",
+
+ "altar.des", "bazaar.des", "entry.des", "elf.des", "float.des",
+ "hells.des", "hive.des", "lab.des", "lair.des", "large.des", "layout.des",
+ "mini.des", "orc.des", "pan.des", "sewer.des", "temple.des", "vaults.des",
+ "crypt.des", "zot.des"
}
for _, file in ipairs(des_files) do
diff --git a/crawl-ref/source/dat/elf.des b/crawl-ref/source/dat/elf.des
index 19b962335b..ee2b093303 100644
--- a/crawl-ref/source/dat/elf.des
+++ b/crawl-ref/source/dat/elf.des
@@ -37,7 +37,7 @@
NAME: elf_arrival_dummy
TAGS: dummy
PLACE: Elf:1
-CHANCE: 50
+WEIGHT: 50
ORIENT: float
MAP
{
@@ -378,7 +378,7 @@ PLACE: Elf:7
TAGS: no_pool_fixup no_rotate
LFLAGS: no_tele_control
ORIENT: float
-CHANCE: 5
+WEIGHT: 5
MONS: deep elf high priest, deep elf demonologist
MONS: deep elf annihilator, deep elf sorcerer
MONS: deep elf death mage, deep elf blademaster
@@ -432,7 +432,7 @@ NAME: elf_hall_gauntlet_narrow
PLACE: Elf:7
TAGS: no_pool_fixup no_rotate
ORIENT: float
-CHANCE: 5
+WEIGHT: 5
MONS: deep elf high priest, deep elf demonologist
MONS: deep elf annihilator, deep elf sorcerer
MONS: deep elf death mage, deep elf master archer
diff --git a/crawl-ref/source/dat/entry.des b/crawl-ref/source/dat/entry.des
index 932f09a06e..aac7791fcc 100644
--- a/crawl-ref/source/dat/entry.des
+++ b/crawl-ref/source/dat/entry.des
@@ -114,7 +114,7 @@ ENDMAP
# good luck! (Shiori)
NAME: shiawase
TAGS: entry no_monster_gen no_rotate no_vmirror
-CHANCE: 5
+WEIGHT: 5
ORIENT: float
ITEM: bread ration, meat ration, apple, orange, banana, choko, pear
SUBST: . = .:100 $ % d
@@ -142,7 +142,7 @@ ENDMAP
# Angband town! (Shiori)
NAME: angband_town
ORIENT: float
-CHANCE: 1
+WEIGHT: 1
TAGS: entry no_rotate
NSUBST: { = { / > / .
NSUBST: = = 3== / *=x
@@ -295,7 +295,7 @@ ENDMAP
NAME: zelgadis_glass_entry_002
TAGS: entry
ORIENT: float
-CHANCE: 1
+WEIGHT: 1
SHUFFLE: {[(<
SUBST: < = .
NSUBST: X = 4:+ / *:x
@@ -502,7 +502,7 @@ NAME: lemuel_entry_005_a
TAGS: entry no_monster_gen
ORIENT: float
SHUFFLE: {}
-CHANCE: 2
+WEIGHT: 2
MAP
xxxxxxxxxxxxxxxxxxx
xxxxx{.......}xxxxx
@@ -527,7 +527,7 @@ ENDMAP
NAME: lemuel_entry_005_b
TAGS: entry no_monster_gen
ORIENT: float
-CHANCE: 7
+WEIGHT: 7
SHUFFLE: {}, XYZ
SUBST: X=W, Y=w, Z=w
MAP
@@ -558,7 +558,7 @@ TAGS: entry no_monster_gen
ORIENT: float
SHUFFLE: {}, ABC
SUBST: A:=, B:x, C:x
-CHANCE: 1
+WEIGHT: 1
MAP
xxxxxxxxxxxxxxxxxxx
xxxWA{.......}xxxxx
@@ -674,7 +674,7 @@ TAGS: entry no_monster_gen
ORIENT: float
SHUFFLE: {[(
SUBST: ? : xxcvG.
-CHANCE: 4
+WEIGHT: 4
MAP
xxxxxxxxxxx
x{...(...[x
@@ -700,7 +700,7 @@ SUBST: ? : xxcvG.
ITEM: meat ration / bread ration / beef jerky / spear / potion of water / \
apple / club / hammer / knife
SHUFFLE: {[(
-CHANCE: 3
+WEIGHT: 3
MAP
xxxxxxxxxxxx
x{...(...[xx
@@ -726,7 +726,7 @@ SUBST: ? : xxcvG.
ITEM: meat ration / bread ration / beef jerky / spear / potion of water / \
apple / club / hammer / knife
SHUFFLE: {[(
-CHANCE: 3
+WEIGHT: 3
MAP
xxxxxxxxxxxx
x{...(...[xx
@@ -750,7 +750,7 @@ ENDMAP
NAME: lemuel_entry_010_a
TAGS: entry no_monster_gen
-CHANCE: 5
+WEIGHT: 5
ORIENT: float
SHUFFLE: {(
SUBST: b : bcvxxx
@@ -770,7 +770,7 @@ ENDMAP
NAME: lemuel_entry_010_b
TAGS: entry no_monster_gen
-CHANCE: 5
+WEIGHT: 5
ORIENT: float
SHUFFLE: {(
SUBST: b : bcvxxx
@@ -817,7 +817,7 @@ ENDMAP
NAME: david_entry_001_a
TAGS: entry no_rotate
ORIENT: float
-CHANCE: 5
+WEIGHT: 5
SHUFFLE: {[(
MAP
xxxxx x@x xxxxx
@@ -843,7 +843,7 @@ ENDMAP
NAME: david_entry_001_b
TAGS: entry no_rotate no_monster_gen
ORIENT: float
-CHANCE: 5
+WEIGHT: 5
SHUFFLE: {[, }>
MAP
xxxxx
@@ -1112,7 +1112,7 @@ ENDMAP
#
NAME: david_entry_011_a
TAGS: entry no_monster_gen no_rotate
-CHANCE: 3
+WEIGHT: 3
ORIENT: float
NSUBST: . = 1:d / *:.
ITEM: stone / dart
@@ -1144,7 +1144,7 @@ ENDMAP
NAME: david_entry_011_b
TAGS: entry no_monster_gen no_rotate
-CHANCE: 1
+WEIGHT: 1
ORIENT: float
NSUBST: . = 1:d / *:.
ITEM: stone / dart
@@ -1176,7 +1176,7 @@ ENDMAP
NAME: david_entry_011_c
TAGS: entry no_monster_gen no_rotate
-CHANCE: 6
+WEIGHT: 6
ORIENT: float
SHUFFLE: ab, cd, ef, gh, ij, kl, mn
SUBST: a=., c=., e=., g=., i=., k=., m=.
@@ -1303,7 +1303,7 @@ ENDMAP
# (but commented out). All water is deep.
# NAME: water_fire_template
# TAGS: entry no_monster_gen no_pool_fixup no_rotate
-# CHANCE: 1
+# WEIGHT: 1
# ORIENT: float
# MONS: plant
# MAP
@@ -1333,7 +1333,7 @@ ENDMAP
NAME: david_entry_015_a_water_fire
TAGS: entry no_monster_gen no_pool_fixup no_rotate
-CHANCE: 1
+WEIGHT: 1
MONS: plant
ORIENT: float
MAP
@@ -1363,7 +1363,7 @@ ENDMAP
NAME: david_entry_015_b_water_fire
TAGS: entry no_monster_gen no_pool_fixup no_rotate
-CHANCE: 1
+WEIGHT: 1
NSUBST: . = 1:d / *:.
ITEM: stone/dart
MONS: plant
@@ -1395,7 +1395,7 @@ ENDMAP
NAME: david_entry_015_c_water_fire
TAGS: entry no_monster_gen no_pool_fixup no_rotate
-CHANCE: 1
+WEIGHT: 1
NSUBST: . = 1:d / *:.
ITEM: stone/dart
MONS: plant
@@ -1427,7 +1427,7 @@ ENDMAP
NAME: david_entry_015_d_water_fire
TAGS: entry no_monster_gen no_pool_fixup no_rotate
-CHANCE: 1
+WEIGHT: 1
NSUBST: . = 1:d / *:.
ITEM: stone/dart
MONS: plant
@@ -1459,7 +1459,7 @@ ENDMAP
NAME: david_entry_015_e_water_fire
TAGS: entry no_monster_gen no_pool_fixup no_rotate
-CHANCE: 1
+WEIGHT: 1
NSUBST: . = 1:d / *:.
ITEM: stone/dart
MONS: plant
@@ -1491,7 +1491,7 @@ ENDMAP
NAME: david_entry_015_f_water_fire
TAGS: entry no_monster_gen no_pool_fixup no_rotate
-CHANCE: 1
+WEIGHT: 1
NSUBST: . = 1:d / *:.
ITEM: stone/dart
MONS: plant
@@ -1523,7 +1523,7 @@ ENDMAP
NAME: david_entry_015_g_water_fire
TAGS: entry no_monster_gen no_pool_fixup no_rotate
-CHANCE: 1
+WEIGHT: 1
NSUBST: . = 1:d / *:.
ITEM: stone/dart
MONS: plant
@@ -1555,7 +1555,7 @@ ENDMAP
NAME: david_entry_015_h_water_fire
TAGS: entry no_monster_gen no_pool_fixup no_rotate
-CHANCE: 1
+WEIGHT: 1
NSUBST: . = 1:d / *:.
ITEM: stone/dart
MONS: plant
@@ -1587,7 +1587,7 @@ ENDMAP
NAME: david_entry_015_i_water_fire
TAGS: entry no_monster_gen no_pool_fixup no_rotate
-CHANCE: 1
+WEIGHT: 1
NSUBST: . = 1:d / *:.
ITEM: stone/dart
MONS: plant
@@ -1619,7 +1619,7 @@ ENDMAP
NAME: david_entry_015_j_water_fire
TAGS: entry no_monster_gen no_pool_fixup no_rotate
-CHANCE: 1
+WEIGHT: 1
NSUBST: . = 1:d / *:.
ITEM: stone/dart
MONS: plant
@@ -1678,7 +1678,7 @@ ENDMAP
#
NAME: david_entry_017_a
TAGS: entry no_monster_gen no_rotate
-CHANCE: 2
+WEIGHT: 2
ORIENT: float
SHUFFLE: {[(
MAP
@@ -1700,7 +1700,7 @@ ENDMAP
NAME: david_entry_017_b
TAGS: entry no_monster_gen no_rotate
ORIENT: float
-CHANCE: 8
+WEIGHT: 8
SHUFFLE: cv
MAP
x@xxxxxxxxxxxxxxxxxxxx@x
@@ -2128,7 +2128,7 @@ NAME: david_entry_033_a
TAGS: entry
ORIENT: float
SHUFFLE: TV
-CHANCE: 5
+WEIGHT: 5
MAP
xx..@..xx
xx...x...xx
@@ -2148,7 +2148,7 @@ ENDMAP
NAME: david_entry_033_b
TAGS: entry
ORIENT: float
-CHANCE: 5
+WEIGHT: 5
MAP
xx..@..xx
xx...x...xx
@@ -2211,7 +2211,7 @@ ENDMAP
NAME: david_entry_036_a
TAGS: entry
ORIENT: float
-CHANCE: 2
+WEIGHT: 2
SHUFFLE: {[(
MAP
@.......xxxxx..@
@@ -2229,7 +2229,7 @@ ENDMAP
NAME: david_entry_036_b
TAGS: entry
ORIENT: float
-CHANCE: 2
+WEIGHT: 2
SHUFFLE: {[(
MAP
@.......xxxxx..@
@@ -2248,7 +2248,7 @@ NAME: david_entry_036_c
TAGS: entry
ORIENT: float
SHUFFLE: {[(
-CHANCE: 2
+WEIGHT: 2
MAP
@.......xxxxx..@
.[......xxxxx...
@@ -2266,7 +2266,7 @@ NAME: david_entry_036_d
TAGS: entry
ORIENT: float
SHUFFLE: {[(
-CHANCE: 2
+WEIGHT: 2
MAP
@.......xxxxx..@
.[......xxxxx...
@@ -2284,7 +2284,7 @@ NAME: david_entry_036_e
TAGS: entry
ORIENT: float
SHUFFLE: {[(
-CHANCE: 2
+WEIGHT: 2
MAP
@.......xxxxx..@
.[......xxxxx...
@@ -2321,7 +2321,7 @@ ENDMAP
NAME: david_entry_038_a
TAGS: entry
ORIENT: float
-CHANCE: 1
+WEIGHT: 1
MAP
xxxxxxxxxxxxx
x%.x%.=..=.[x
@@ -2337,7 +2337,7 @@ ENDMAP
NAME: david_entry_038_b
TAGS: entry
ORIENT: float
-CHANCE: 2
+WEIGHT: 2
MAP
xxxxxxxxxxxxx
x.%x%.x..=.[x
@@ -2353,7 +2353,7 @@ ENDMAP
NAME: david_entry_038_c
TAGS: entry
ORIENT: float
-CHANCE: 1
+WEIGHT: 1
MAP
xxxxxxxxxxxxx
x.%x%%x..=.[x
@@ -2369,7 +2369,7 @@ ENDMAP
NAME: david_entry_038_d
TAGS: entry
ORIENT: float
-CHANCE: 1
+WEIGHT: 1
MAP
xxxxxxxxxxxxx
x%.=..=.%x.[x
@@ -2385,7 +2385,7 @@ ENDMAP
NAME: david_entry_038_e
TAGS: entry
ORIENT: float
-CHANCE: 1
+WEIGHT: 1
MAP
xxxxxxxxxxxxx
x..=..=..x%[x
@@ -2401,7 +2401,7 @@ ENDMAP
NAME: david_entry_038_f
TAGS: entry
ORIENT: float
-CHANCE: 2
+WEIGHT: 2
MAP
xxxxxxxxxxxxx
x..=..x%.=%[x
@@ -2417,7 +2417,7 @@ ENDMAP
NAME: david_entry_038_g
TAGS: entry
ORIENT: float
-CHANCE: 2
+WEIGHT: 2
MAP
xxxxxxxxxxxxx
x%.x..x..x%[x
@@ -2564,7 +2564,7 @@ ENDMAP
NAME: david_entry_045_a
TAGS: entry
ORIENT: float
-CHANCE: 5
+WEIGHT: 5
SHUFFLE: {[(
MAP
xxxxxx@.xxx
@@ -2582,7 +2582,7 @@ ENDMAP
NAME: david_entry_045_b
TAGS: entry
ORIENT: float
-CHANCE: 5
+WEIGHT: 5
SHUFFLE: {[(
MAP
xxxxxx@.xxx
@@ -2644,7 +2644,7 @@ ENDMAP
NAME: david_entry_048_a
TAGS: entry no_monster_gen no_rotate
ORIENT: float
-CHANCE: 5
+WEIGHT: 5
SHUFFLE: cvba
NSUBST: . = 1:d / *:.
ITEM: stone / dart
@@ -2663,7 +2663,7 @@ ENDMAP
NAME: david_entry_048_b
TAGS: entry no_monster_gen no_rotate
ORIENT: float
-CHANCE: 5
+WEIGHT: 5
SHUFFLE: cvba
NSUBST: . = 1:d / *:.
ITEM: stone / dart
@@ -2830,7 +2830,7 @@ ENDMAP
NAME: david_entry_055_a
TAGS: entry no_monster_gen no_rotate
ORIENT: float
-CHANCE: 5
+WEIGHT: 5
SHUFFLE: lw
MAP
xxxxxxxxxxx
@@ -2855,7 +2855,7 @@ ENDMAP
NAME: david_entry_055_b
TAGS: entry no_monster_gen
ORIENT: float
-CHANCE: 5
+WEIGHT: 5
SHUFFLE: {(, lw
MAP
xxxxx@xxxxx
@@ -2883,7 +2883,7 @@ ENDMAP
NAME: david_entry_056_a
TAGS: entry no_rotate
ORIENT: float
-CHANCE: 3
+WEIGHT: 3
ITEM: nothing, nothing, nothing
SHUFFLE: cccbvxxx, def}
MAP
@@ -2911,7 +2911,7 @@ ENDMAP
NAME: david_entry_056_b
TAGS: entry no_rotate
ORIENT: float
-CHANCE: 7
+WEIGHT: 7
SHUFFLE: cccbvxxx
MAP
....................
@@ -2941,7 +2941,7 @@ ORIENT: float
SHUFFLE: {[AB
MONS: gnoll
SUBST: A=., B=.
-CHANCE: 3
+WEIGHT: 3
MAP
@....B........@
..............[
@@ -2964,7 +2964,7 @@ ORIENT: float
SHUFFLE: {[AB
SUBST: A=., B=.
MONS: gnoll
-CHANCE: 3
+WEIGHT: 3
MAP
@...B.........@
..............[
@@ -2987,7 +2987,7 @@ ORIENT: float
SHUFFLE: {[AB
SUBST: A=., B=.
MONS: gnoll
-CHANCE: 2
+WEIGHT: 2
MAP
@.....B.......@
..............[
@@ -3010,7 +3010,7 @@ ORIENT: float
SHUFFLE: {[AB
SUBST: A=., B=.
MONS: gnoll
-CHANCE: 2
+WEIGHT: 2
MAP
@......A......@
..............[
@@ -3100,7 +3100,7 @@ TAGS: entry no_monster_gen
ORIENT: northwest
SHUFFLE: Cc, {Y
SUBST: ?=l. , Y=.
-CHANCE: 6
+WEIGHT: 6
MAP
xxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxx
@@ -3125,7 +3125,7 @@ ENDMAP
NAME: david_entry_061_b_altar
TAGS: entry no_monster_gen
ORIENT: northwest
-CHANCE: 4
+WEIGHT: 4
SHUFFLE: Cc, {Y
SUBST: Y=.
MAP
@@ -3176,7 +3176,7 @@ ENDMAP
#
NAME: david_entry_063_tiny
TAGS: entry
-CHANCE: 10
+WEIGHT: 10
ORIENT: float
MAP
{
@@ -3187,7 +3187,7 @@ ENDMAP
#
NAME: david_entry_064_a_tiny
TAGS: entry
-CHANCE: 2
+WEIGHT: 2
ORIENT: float
MAP
xxx
@@ -3197,7 +3197,7 @@ ENDMAP
NAME: david_entry_064_b_tiny
TAGS: entry
-CHANCE: 4
+WEIGHT: 4
ORIENT: float
MAP
@....
@@ -3208,7 +3208,7 @@ ENDMAP
NAME: david_entry_064_c_tiny
TAGS: entry
-CHANCE: 4
+WEIGHT: 4
ORIENT: float
MAP
@....
@@ -3223,7 +3223,7 @@ ENDMAP
#
NAME: david_entry_065_a_tiny
TAGS: entry
-CHANCE: 1
+WEIGHT: 1
ORIENT: float
MAP
xxxxx
@@ -3235,7 +3235,7 @@ ENDMAP
NAME: david_entry_065_b_tiny
TAGS: entry
-CHANCE: 3
+WEIGHT: 3
ORIENT: float
MAP
@......
@@ -3248,7 +3248,7 @@ ENDMAP
NAME: david_entry_065_c_tiny
TAGS: entry
-CHANCE: 3
+WEIGHT: 3
ORIENT: float
MAP
@...xx
@@ -3261,7 +3261,7 @@ ENDMAP
NAME: david_entry_065_d_tiny
TAGS: entry
-CHANCE: 3
+WEIGHT: 3
ORIENT: float
MAP
@xxxxxx
@@ -3277,7 +3277,7 @@ ENDMAP
#
NAME: david_entry_066_a_tiny
TAGS: entry
-CHANCE: 4
+WEIGHT: 4
ORIENT: float
MAP
xxxxx
@@ -3287,7 +3287,7 @@ ENDMAP
NAME: david_entry_066_b_tiny
TAGS: entry
-CHANCE: 3
+WEIGHT: 3
ORIENT: float
SUBST: v : vcbxxx
MAP
@@ -3300,7 +3300,7 @@ ENDMAP
NAME: david_entry_066_d_tiny
TAGS: entry
-CHANCE: 3
+WEIGHT: 3
ORIENT: float
MAP
xxxx
@@ -3373,7 +3373,7 @@ ENDMAP
NAME: david_entry_069_a
TAGS: entry no_monster_gen no_rotate
ORIENT: float
-CHANCE: 3
+WEIGHT: 3
SHUFFLE: bxxxx
MAP
....... .......
@@ -3392,7 +3392,7 @@ ENDMAP
NAME: david_entry_069_b
TAGS: entry no_monster_gen no_rotate
ORIENT: float
-CHANCE: 3
+WEIGHT: 3
SHUFFLE: bxxxx
MAP
....... .......
@@ -3411,7 +3411,7 @@ ENDMAP
NAME: david_entry_069_c
TAGS: entry no_monster_gen no_rotate
ORIENT: float
-CHANCE: 3
+WEIGHT: 3
SHUFFLE: bxxxx
MAP
....... .......
@@ -3430,7 +3430,7 @@ ENDMAP
NAME: david_entry_069_d
TAGS: entry no_monster_gen no_rotate
ORIENT: float
-CHANCE: 1
+WEIGHT: 1
SHUFFLE: bxxxx
MAP
....... .......
@@ -3568,7 +3568,7 @@ ENDMAP
NAME: erik_entry_001_a
TAGS: entry
ORIENT: float
-CHANCE: 1
+WEIGHT: 1
SHUFFLE: {[(
SUBST: X : x:20 G:4 l:1
SUBST: c : cxxx
@@ -3596,7 +3596,7 @@ NAME: erik_entry_001_b
TAGS: entry
ORIENT: float
MONS: gnoll
-CHANCE: 3
+WEIGHT: 3
SHUFFLE: {[(
SUBST: c : cxxx
MAP
@@ -3623,7 +3623,7 @@ NAME: erik_entry_001_c
TAGS: entry
ORIENT: float
MONS: centaur, orc
-CHANCE: 3
+WEIGHT: 3
SHUFFLE: {[(
SUBST: c : cxxx
MAP
@@ -3648,7 +3648,7 @@ ENDMAP
NAME: erik_entry_001_d
TAGS: entry
-CHANCE: 3
+WEIGHT: 3
ORIENT: float
MONS: orc
SHUFFLE: {[(
@@ -3956,7 +3956,7 @@ ENDMAP
NAME: matt_entry_007_a
TAGS: entry no_monster_gen
ORIENT: float
-CHANCE: 1
+WEIGHT: 1
SHUFFLE: {[(<
MAP
xxx@xxx@xxx
@@ -3975,7 +3975,7 @@ ENDMAP
NAME: matt_entry_007_b
TAGS: entry no_monster_gen
ORIENT: float
-CHANCE: 3
+WEIGHT: 3
SHUFFLE: {[(<
MAP
xxx@xxx@xxx
@@ -3994,7 +3994,7 @@ ENDMAP
NAME: matt_entry_007_c
TAGS: entry no_monster_gen
ORIENT: float
-CHANCE: 6
+WEIGHT: 6
SHUFFLE: {[(<
MAP
xxx@xxx@xxx
@@ -4313,7 +4313,7 @@ ENDMAP
# Mini maze
NAME: onia_ninara_004_a_mini_maze
TAGS: entry
-CHANCE: 5
+WEIGHT: 5
ORIENT: float
ITEM: apple / sausage / nothing / stone / potion of water
SHUFFLE: ({[, Aa, Bb, Cc, Ee, Ff
@@ -4338,7 +4338,7 @@ ENDMAP
NAME: onia_ninara_004_b_mini_maze
TAGS: entry
-CHANCE: 5
+WEIGHT: 5
ORIENT: float
ITEM: apple / sausage / nothing / stone / potion of water / w:30 nothing
SHUFFLE: ({[ , AB
@@ -4447,7 +4447,7 @@ TAGS: entry no_monster_gen no_rotate
ORIENT: northwest
SUBST: V = V T:2
SUBST: ' : x.
-CHANCE: 5
+WEIGHT: 5
MAP
xxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxx
@@ -4479,7 +4479,7 @@ ENDMAP
NAME: entry_eino_001_b
TAGS: entry no_monster_gen no_rotate
ORIENT: northwest
-CHANCE: 5
+WEIGHT: 5
MAP
xxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxx
@@ -4512,7 +4512,7 @@ TAGS: entry no_monster_gen no_rotate
ORIENT: northwest
NSUBST: A = 1:= / x
SUBST: % = % .:5
-CHANCE: 2
+WEIGHT: 2
MAP
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
@@ -4538,7 +4538,7 @@ TAGS: entry no_rotate
ORIENT: northeast
SHUFFLE: bvc
SUBST: ' : x.
-CHANCE: 4
+WEIGHT: 4
MAP
xxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxx
@@ -4567,7 +4567,7 @@ NAME: entry_eino_002_c
TAGS: entry no_monster_gen no_rotate
ORIENT: northeast
SUBST: ' : x. , " : x. , ? = x.
-CHANCE: 4
+WEIGHT: 4
MAP
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
diff --git a/crawl-ref/source/dat/float.des b/crawl-ref/source/dat/float.des
index 11b9d752ef..ad49cbb487 100644
--- a/crawl-ref/source/dat/float.des
+++ b/crawl-ref/source/dat/float.des
@@ -27,7 +27,7 @@ DEPTH: D:1-11
# by depth.
TAGS: dummy
ORIENT: float
-CHANCE: 100
+WEIGHT: 100
MAP
x
ENDMAP
@@ -41,7 +41,7 @@ DEPTH: 1-, !D
# by depth.
TAGS: dummy
ORIENT: float
-CHANCE: 60
+WEIGHT: 60
MAP
x
ENDMAP
@@ -51,7 +51,7 @@ ENDMAP
#
NAME: erik_1
ORIENT: float
-CHANCE: 5
+WEIGHT: 5
TAGS: no_monster_gen
DEPTH: D:7-11, Lair
#
@@ -431,7 +431,7 @@ ENDMAP
#
NAME: oklob_3
DEPTH: D:18-27, Lair:2-10, Elf:2-7
-CHANCE: 2
+WEIGHT: 2
ORIENT: float
SHUFFLE: ab" / AB'
SUBST: a=[, b=(, A=., B=., '=., "=>
diff --git a/crawl-ref/source/dat/hive.des b/crawl-ref/source/dat/hive.des
index 745403bfe9..db65754621 100644
--- a/crawl-ref/source/dat/hive.des
+++ b/crawl-ref/source/dat/hive.des
@@ -11,7 +11,7 @@
NAME: hive_0
TAGS: hive_entry
ORIENT: float
-CHANCE: 60
+WEIGHT: 60
MAP
O
ENDMAP
@@ -260,7 +260,7 @@ ENDMAP
NAME: Hive_Balancer
DEPTH: Hive:*
TAGS: dummy
-CHANCE: 200
+WEIGHT: 200
MAP
x
ENDMAP
@@ -397,7 +397,7 @@ ENDMAP
NAME: lemuel_wasp_nest
DEPTH: Hive:2-3
MONS: yellow wasp / weight:2 red wasp
-CHANCE: 1
+WEIGHT: 1
SUBST: 1=1 .:15
SUBST: ?=a.
MAP
@@ -420,7 +420,7 @@ ENDMAP
NAME: lemuel_hive_grid_a
DEPTH: Hive:*
-CHANCE: 4
+WEIGHT: 4
MAP
a.a.a.a.a.a.a.a.a
aa.a.a.a.a.a.a.aa
@@ -437,7 +437,7 @@ ENDMAP
NAME: lemuel_hive_grid_b
DEPTH: Hive:*
-CHANCE: 6
+WEIGHT: 6
MAP
a.a.a.a.aa
aa.a.a.a.a
@@ -450,7 +450,7 @@ ENDMAP
NAME: lemuel_hive_grid_c
DEPTH: Hive:*
-CHANCE: 10
+WEIGHT: 10
MAP
aa.aa
aa.a.aa
diff --git a/crawl-ref/source/dat/lab.des b/crawl-ref/source/dat/lab.des
index 3aed292afa..9e40008913 100644
--- a/crawl-ref/source/dat/lab.des
+++ b/crawl-ref/source/dat/lab.des
@@ -42,7 +42,7 @@ ENDMAP
# Dummy balancer
NAME: labyrinth_0
TAGS: minotaur dummy
-CHANCE: 20
+WEIGHT: 20
MAP
x
ENDMAP
@@ -164,7 +164,7 @@ NSUBST: D = 1:. / *:D
KFEAT: d = axe trap / dart trap / needle trap / blade trap
KFEAT: D = teleport trap
SUBST: c : vvc
-CHANCE: 2
+WEIGHT: 2
MAP
..............
.cccccccccccc.
@@ -194,7 +194,7 @@ SUBST: Y=*, Z=*
KFEAT: X = <
KMONS: X = patrolling minotaur
KFEAT: S = granite_statue
-CHANCE: 2
+WEIGHT: 2
MAP
.............
.vvvvvvvvvvv.
@@ -226,7 +226,7 @@ ENDMAP
# Labyrinth dummy decorator
NAME: lab_dummy
TAGS: lab dummy
-CHANCE: 90
+WEIGHT: 90
MAP
x
ENDMAP
@@ -292,7 +292,7 @@ ENDMAP
NAME: labyrinth_glass_2
TAGS: lab allow_dup
-CHANCE: 1
+WEIGHT: 1
MAP
......
.nnnn.
@@ -324,7 +324,7 @@ TAGS: lab allow_dup
KFEAT: Y = teleport trap
KITEM: Y = any good_item
SHUFFLE: cxv
-CHANCE: 1
+WEIGHT: 1
MAP
.....
.x=x.
diff --git a/crawl-ref/source/dat/lair.des b/crawl-ref/source/dat/lair.des
index 5d103a529e..7588ea89f5 100644
--- a/crawl-ref/source/dat/lair.des
+++ b/crawl-ref/source/dat/lair.des
@@ -9,7 +9,7 @@
# Dummy Lair entry
NAME: lair_0_dummy
TAGS: lair_entry dummy
-CHANCE: 30
+WEIGHT: 30
ORIENT: float
MAP
O
@@ -220,7 +220,7 @@ NAME: RatsNest_Lair
ORIENT: northeast
TAGS: uniq_rats_nest
DEPTH: Lair
-CHANCE: 5
+WEIGHT: 5
SHUFFLE: 23, 34
MONS: rat / green rat / nothing, grey rat / orange rat / nothing
MONS: green rat / orange rat / nothing, orange rat / rat
@@ -295,7 +295,7 @@ ENDMAP
#
NAME: strawberry_fields_big
ORIENT: float
-CHANCE: 1
+WEIGHT: 1
DEPTH: Lair
SUBST: .= d .:150 1:8 2:4
MONS: plant, butterfly
@@ -323,7 +323,7 @@ ENDMAP
NAME: strawberry_fields_big_rounded
ORIENT: float
-CHANCE: 1
+WEIGHT: 1
DEPTH: Lair
SUBST: .= d .:140 1:8 2:4
MONS: plant, butterfly
@@ -351,7 +351,7 @@ ENDMAP
NAME: strawberry_fields_round
ORIENT: float
-CHANCE: 4
+WEIGHT: 4
TAGS: allow_dup
DEPTH: Lair
SUBST: .= d .:50 1:8 2:4
@@ -372,7 +372,7 @@ ENDMAP
NAME: strawberry_fields_patches_spacepadded
ORIENT: float
-CHANCE: 4
+WEIGHT: 4
DEPTH: Lair
SUBST: .= d .:50 1:8 2:4
MONS: plant, butterfly
@@ -408,7 +408,7 @@ SUBST: . = .:90 a:10 2:1
KITEM: a : apple / apricot / pear / orange / banana / strawberry q:1 w:5 /\
strawberry q:2 w:5 / lemon
KFEAT: a = .
-CHANCE: 8
+WEIGHT: 8
MAP
.....
.......
@@ -429,7 +429,7 @@ SUBST: _ = .:90 a:4
KITEM: a : apple / apricot / pear / orange / banana / strawberry q:1 w:5 /\
strawberry q:2 w:5 / lemon
KFEAT: a = .
-CHANCE: 2
+WEIGHT: 2
MAP
________
_........_
@@ -650,7 +650,7 @@ ENDMAP
#
NAME: Shoal_1
PLACE: Shoal:5
-CHANCE: 0
+WEIGHT: 0
MONS: cyclops, yaktaur, yaktaur captain
MAP
wwwwwwwwcccccccccccccwwwwwww
@@ -689,7 +689,7 @@ ENDMAP
#
NAME: Shoal_2
PLACE: Shoal:5
-CHANCE: 0
+WEIGHT: 0
MONS: cyclops,stone giant
SUBST: 1 = 1.
SUBST: W = W:2 w
@@ -727,7 +727,7 @@ ENDMAP
#
NAME: Shoal_3
PLACE: Shoal:5
-CHANCE: 0
+WEIGHT: 0
KMONS: x : ice statue / orange crystal statue / silver statue
KFEAT: x : O
MAP
@@ -741,7 +741,7 @@ ENDMAP
#
NAME: Shoal_4
PLACE: Shoal:5
-CHANCE: 0
+WEIGHT: 0
KFEAT: O = w
### KITEM: O = liquid rune of Zot
MAP
diff --git a/crawl-ref/source/dat/large.des b/crawl-ref/source/dat/large.des
index 0992a9c7f0..bea59e0766 100644
--- a/crawl-ref/source/dat/large.des
+++ b/crawl-ref/source/dat/large.des
@@ -16,7 +16,7 @@ default-depth: D:12-26
NAME: RatsNest_Dungeon
ORIENT: northeast
TAGS: uniq_rats_nest
-CHANCE: 5
+WEIGHT: 5
DEPTH: D:5-9
SHUFFLE: 23, 34
MONS: rat / nothing, grey rat / nothing
@@ -1255,7 +1255,7 @@ NAME: erik_rubicon_a
DEPTH: D:10-16
ORIENT: south
TAGS: no_pool_fixup no_rotate uniq_rubicon
-CHANCE: 6
+WEIGHT: 6
ITEM: ring of levitation / potion of levitation / nothing
ITEM: potion of levitation / nothing, nothing, nothing, nothing
SHUFFLE: {[(, )gh
@@ -1290,7 +1290,7 @@ NAME: erik_rubicon_b
DEPTH: D:10-16
ORIENT: south
TAGS: no_rotate uniq_rubicon
-CHANCE: 4
+WEIGHT: 4
ITEM: ring of levitation / potion of levitation / nothing
ITEM: potion of levitation, nothing, nothing, nothing, nothing
SHUFFLE: {[(, fgW, )hi
diff --git a/crawl-ref/source/dat/mini.des b/crawl-ref/source/dat/mini.des
index e03d932937..54a2d49c52 100644
--- a/crawl-ref/source/dat/mini.des
+++ b/crawl-ref/source/dat/mini.des
@@ -37,7 +37,7 @@ default-depth: D:8-27
NAME: mini_dummy
DEPTH: 1-50, !D:8-27
TAGS: dummy
-CHANCE: 90
+WEIGHT: 90
MAP
.
ENDMAP
@@ -48,7 +48,7 @@ ENDMAP
# still see you
NAME: glass_columns_a
DEPTH: D, Elf, Crypt
-CHANCE: 5
+WEIGHT: 5
MAP
.....
.m.m.
@@ -59,7 +59,7 @@ ENDMAP
NAME: glass_columns_b
DEPTH: D, Elf, Crypt
-CHANCE: 3
+WEIGHT: 3
MAP
.......
.m.m.m.
@@ -72,7 +72,7 @@ ENDMAP
NAME: glass_columns_c
DEPTH: D, Elf, Crypt
-CHANCE: 2
+WEIGHT: 2
MAP
.........
.m.m.m.m.
@@ -103,7 +103,7 @@ ENDMAP
# An item encased in glass. If the player wants it, it can be dug out.
NAME: item_on_display_a
DEPTH: D, Elf, Crypt, Vault
-CHANCE: 9
+WEIGHT: 9
SUBST: % = %%%*
TAGS: no_monster_gen no_item_gen
MAP
@@ -118,7 +118,7 @@ ENDMAP
# A good item encased in transparent stone.
NAME: item_on_display_b
DEPTH: D, Elf, Crypt, Vault
-CHANCE: 1
+WEIGHT: 1
SUBST: * = ***|
TAGS: no_monster_gen no_item_gen
MAP
@@ -406,7 +406,7 @@ TAGS: allow_dup
NSUBST: Z = 4=. / z
KFEAT: z = zot trap
SUBST: *: *$
-CHANCE: 3
+WEIGHT: 3
MAP
xxxxxxxxxx
xxxxxxx**x
@@ -639,7 +639,7 @@ ENDMAP
# Greed's colour
NAME: david_greed
-CHANCE: 4
+WEIGHT: 4
DEPTH: D:10-26, Vault, Elf
ITEM: nothing / any good_item
MONS: silver statue / orange crystal statue / ice statue
@@ -926,7 +926,7 @@ ENDMAP
NAME: minivault_16
TAGS: allow_dup
-CHANCE: 40
+WEIGHT: 40
# as this replaces the former statue only minivaults
SHUFFLE: G111
MONS: orange crystal statue / silver statue / ice statue
@@ -1522,7 +1522,7 @@ ENDMAP
NAME: small_statue_alley_a
TAGS: uniq_statue_alley
DEPTH: D:10-20
-CHANCE: 7
+WEIGHT: 7
MAP
xxxcccccx
...G...G@
@@ -1535,7 +1535,7 @@ ENDMAP
NAME: small_statue_alley_b
TAGS: uniq_statue_alley
DEPTH: D:3-10
-CHANCE: 2
+WEIGHT: 2
MAP
xxxcccccx
...G...G@
@@ -1548,7 +1548,7 @@ ENDMAP
NAME: small_statue_alley_c
TAGS: uniq_statue_alley
DEPTH: Orc
-CHANCE: 1
+WEIGHT: 1
MAP
xxxcccccx
...I...I@
diff --git a/crawl-ref/source/dat/orc.des b/crawl-ref/source/dat/orc.des
index 69a90229dd..14cacecff2 100644
--- a/crawl-ref/source/dat/orc.des
+++ b/crawl-ref/source/dat/orc.des
@@ -11,7 +11,7 @@
NAME: orc_0_dummy
TAGS: orc_entry
-CHANCE: 50
+WEIGHT: 50
ORIENT: float
MAP
O
@@ -438,7 +438,7 @@ default-depth: Orc:*
#
NAME: mines_dummy
TAGS: dummy
-CHANCE: 60
+WEIGHT: 60
MAP
x
ENDMAP
@@ -486,7 +486,7 @@ ENDMAP
NAME: mines1_david
TAGS: allow_dup
KFEAT: C = altar_beogh
-CHANCE: 20
+WEIGHT: 20
MAP
...........
.xxxx.xxxx.
@@ -508,7 +508,7 @@ TAGS: allow_dup
KFEAT: C = altar_beogh
MONS: orc / orc warrior w:1
SUBST: . = . 1:2
-CHANCE: 20
+WEIGHT: 20
MAP
.......
.......
diff --git a/crawl-ref/source/dat/sewer.des b/crawl-ref/source/dat/sewer.des
index 03f7f4913e..1cc3422ca1 100644
--- a/crawl-ref/source/dat/sewer.des
+++ b/crawl-ref/source/dat/sewer.des
@@ -95,7 +95,7 @@ ENDMAP
# The easiest one, so most probable (5 out of 9 sewers).
NAME: sewer_kobolds
TAGS: sewer no_item_gen no_monster_gen no_pool_fixup
-CHANCE: 40
+WEIGHT: 40
ORIENT: encompass
KFEAT: < = exit_portal_vault
COLOUR: < = darkgrey
diff --git a/crawl-ref/source/dat/temple.des b/crawl-ref/source/dat/temple.des
index b24ec5af41..e220f4c1e4 100644
--- a/crawl-ref/source/dat/temple.des
+++ b/crawl-ref/source/dat/temple.des
@@ -12,7 +12,7 @@
#
NAME: temple_hall_a
TAGS: temple_entry
-CHANCE: 9
+WEIGHT: 9
ORIENT: float
SUBST: ? : c:20 x v b G:5
MAP
@@ -35,7 +35,7 @@ ENDMAP
NAME: temple_hall_b
TAGS: temple_entry no_pool_fixup no_monster_gen
-CHANCE: 1
+WEIGHT: 1
ORIENT: float
SUBST: ? : v b G:5
MAP
@@ -104,7 +104,7 @@ ENDMAP
# Where's the entry to the temple?
#
NAME: temple_secret_doors_a
-CHANCE: 1
+WEIGHT: 1
TAGS: temple_entry
ORIENT: float
SUBST: c:cxxx
@@ -120,7 +120,7 @@ cccccccccc
ENDMAP
NAME: temple_secret_doors_b
-CHANCE: 1
+WEIGHT: 1
TAGS: temple_entry
ORIENT: float
SUBST: ? : ?:40 T:30 U, ? = T:30 U
@@ -137,7 +137,7 @@ ccccccccccc
ENDMAP
NAME: temple_secret_doors_c
-CHANCE: 1
+WEIGHT: 1
TAGS: temple_entry
ORIENT: float
SUBST: ? : ?:40 T:30 U, ? = T:30 U
@@ -156,7 +156,7 @@ ccccc@ccc
ENDMAP
NAME: temple_secret_doors_d
-CHANCE: 1
+WEIGHT: 1
TAGS: temple_entry
ORIENT: float
SUBST: ? : ?:40 T:30 U, ? = T:30 U
@@ -175,7 +175,7 @@ ccccc@ccccc
ENDMAP
NAME: temple_secret_doors_e
-CHANCE: 6
+WEIGHT: 6
TAGS: temple_entry no_rotate
ORIENT: float
SUBST: ? : ?:40 T:30 U, ? = T:30 U
@@ -200,7 +200,7 @@ ENDMAP
#
NAME: temple_pool_a
TAGS: temple_entry no_monster_gen no_pool_fixup no_rotate
-CHANCE: 3
+WEIGHT: 3
ORIENT: float
SHUFFLE: XY
SUBST: Y=w, X=.
@@ -220,7 +220,7 @@ ENDMAP
NAME: temple_pool_b
TAGS: temple_entry no_monster_gen no_rotate
-CHANCE: 7
+WEIGHT: 7
ORIENT: float
SHUFFLE: ABCDEFGHIJKL
SUBST: A=W, B=W, C=W, D=w, E=w, F=w, G=w, H=w, I=w, J=w, K=w, L=w
diff --git a/crawl-ref/source/dat/vaults.des b/crawl-ref/source/dat/vaults.des
index f50f8dd7b0..cdf365c456 100644
--- a/crawl-ref/source/dat/vaults.des
+++ b/crawl-ref/source/dat/vaults.des
@@ -14,7 +14,7 @@
NAME: vaults_0_dummy
TAGS: vault_entry
-CHANCE: 60
+WEIGHT: 60
ORIENT: float
MAP
O
diff --git a/crawl-ref/source/dat/zot.des b/crawl-ref/source/dat/zot.des
index f21af392e3..d8de119f9e 100644
--- a/crawl-ref/source/dat/zot.des
+++ b/crawl-ref/source/dat/zot.des
@@ -10,7 +10,7 @@
#
NAME: lemuel_baited_zot_trap
DEPTH: Zot:*
-CHANCE: 20
+WEIGHT: 20
TAGS: allow_dup
KFEAT: * = Zot trap
KITEM: * = any good_item
diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc
index 9f1ab4cf1f..f25a886c18 100644
--- a/crawl-ref/source/debug.cc
+++ b/crawl-ref/source/debug.cc
@@ -4698,6 +4698,7 @@ static bool mg_do_build_level(int niters)
static std::vector<level_id> mg_dungeon_places()
{
std::vector<level_id> places;
+
for (int br = BRANCH_MAIN_DUNGEON; br < NUM_BRANCHES; ++br)
{
if (branches[br].depth == -1)
@@ -4790,6 +4791,8 @@ static void _mapgen_report_available_random_vaults(FILE *outf)
i != places.end(); ++i)
{
fprintf(outf, "\n%s -------------\n", i->describe().c_str());
+ mesclr();
+ mprf("Examining random maps at %s", i->describe().c_str());
mg_report_random_maps(outf, *i);
fprintf(outf, "---------------------------------\n");
}
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index a004341c0c..9f4160da0b 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -241,8 +241,7 @@ std::vector<vault_placement> Level_Vaults;
std::string dgn_Build_Method;
std::string dgn_Layout_Type;
-static int vault_chance = 9;
-static int minivault_chance = 3;
+static int can_create_vault = true;
static bool dgn_level_vetoed = false;
static bool use_random_maps = true;
static bool dgn_check_connectivity = false;
@@ -795,7 +794,7 @@ static bool _ensure_vault_placed(bool vault_success)
if (!vault_success)
dgn_level_vetoed = true;
else
- vault_chance = 0;
+ can_create_vault = false;
return (vault_success);
}
@@ -862,8 +861,7 @@ static void _reset_level()
level_clear_vault_memory();
dgn_colour_grid.reset(NULL);
- vault_chance = 9;
- minivault_chance = 3;
+ can_create_vault = true;
use_random_maps = true;
dgn_check_connectivity = false;
dgn_zones = 0;
@@ -2418,7 +2416,7 @@ static void _place_minivaults(const std::string &tag, int lo, int hi, bool force
}
std::set<int> used;
- if (use_random_maps && minivault_chance && one_chance_in(minivault_chance))
+ if (use_random_maps)
{
const int vault = random_map_in_depth(level_id::current(), true);
if (vault != -1)
@@ -2461,9 +2459,7 @@ static builder_rc_type _builder_normal(int level_number, char level_type,
int vault = _dgn_random_map_for_place(false);
// Can't have vaults on you.where_are_you != BRANCH_MAIN_DUNGEON levels.
- if (vault == -1
- && use_random_maps
- && one_chance_in(vault_chance))
+ if (vault == -1 && use_random_maps && can_create_vault)
{
vault = random_map_in_depth(level_id::current());
@@ -2518,7 +2514,6 @@ static builder_rc_type _builder_normal(int level_number, char level_type,
if (level_number > 2 && level_number < 23 && one_chance_in(3))
{
_plan_main(level_number, 0);
- minivault_chance = 3;
return BUILD_SKIP;
}
@@ -2534,7 +2529,6 @@ static builder_rc_type _builder_normal(int level_number, char level_type,
// Sometimes _roguey_level() generates a special room.
_roguey_level(level_number, sr, just_roguey);
- minivault_chance = 4;
if (just_roguey)
return BUILD_SKIP;
@@ -2841,8 +2835,7 @@ static void _place_extra_vaults()
{
if (!player_in_branch(BRANCH_MAIN_DUNGEON)
&& use_random_maps
- && vault_chance
- && one_chance_in(vault_chance))
+ && can_create_vault)
{
int vault = random_map_in_depth(level_id::current());
@@ -2851,7 +2844,7 @@ static void _place_extra_vaults()
vault = -1;
if (vault != -1 && _build_secondary_vault(you.your_level, vault, -1))
- vault_chance = 0;
+ can_create_vault = false;
}
}
diff --git a/crawl-ref/source/luadgn.cc b/crawl-ref/source/luadgn.cc
index ca773b84d8..2d688d887c 100644
--- a/crawl-ref/source/luadgn.cc
+++ b/crawl-ref/source/luadgn.cc
@@ -534,12 +534,30 @@ static int dgn_change_branch_flags(lua_State *ls)
return (1);
}
+static int dgn_chance(lua_State *ls)
+{
+ MAP(ls, 1, map);
+ if (!lua_isnil(ls, 2) && !lua_isnil(ls, 3))
+ {
+ const int chance_priority = luaL_checkint(ls, 2);
+ const int chance = luaL_checkint(ls, 3);
+ if (chance < 0 || chance > CHANCE_ROLL)
+ luaL_argerror(ls, 2,
+ make_stringf("Chance must be in the range [0,%d]",
+ CHANCE_ROLL).c_str());
+
+ map->chance_priority = chance_priority;
+ map->chance = chance;
+ }
+ PLUARET(number, map->chance);
+}
+
static int dgn_weight(lua_State *ls)
{
MAP(ls, 1, map);
if (!lua_isnil(ls, 2))
- map->chance = luaL_checkint(ls, 2);
- PLUARET(number, map->chance);
+ map->weight = luaL_checkint(ls, 2);
+ PLUARET(number, map->weight);
}
static int dgn_orient(lua_State *ls)
@@ -2107,7 +2125,8 @@ static const struct luaL_reg dgn_lib[] =
{ "tags_remove", dgn_tags_remove },
{ "lflags", dgn_lflags },
{ "bflags", dgn_bflags },
- { "chance", dgn_weight },
+ { "chance", dgn_chance },
+ { "weight", dgn_weight },
{ "welcome", dgn_welcome },
{ "weight", dgn_weight },
{ "orient", dgn_orient },
diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc
index 3eaea9b11f..fb0b1b6a3a 100644
--- a/crawl-ref/source/mapdef.cc
+++ b/crawl-ref/source/mapdef.cc
@@ -1164,7 +1164,7 @@ dlua_set_map::~dlua_set_map()
//
map_def::map_def()
- : name(), tags(), place(), depths(), orient(), chance(),
+ : name(), tags(), place(), depths(), orient(), chance(), weight(),
welcome_messages(), map(), mons(), items(), keyspecs(),
prelude("dlprelude"), main("dlmain"), validate("dlvalidate"),
veto("dlveto"), rock_colour(BLACK), floor_colour(BLACK),
@@ -1199,8 +1199,26 @@ void map_def::reinit()
rock_colour = floor_colour = BLACK;
- // Base chance; this is not a percentage.
- chance = 10;
+ // Chance of using this level. Nonzero chance should be used
+ // sparingly. When selecting vaults for a place, first those
+ // vaults with chance > 0 are considered, in the order they were
+ // loaded (which is arbitrary). If random2(100) < chance, the
+ // vault is picked, and all other vaults are ignored for that
+ // random selection. weight is ignored if the vault is chosen
+ // based on its chance.
+ chance = 0;
+
+ // If multiple alternative vaults have a chance, the order in which
+ // they're tested is based on chance_priority: higher priority vaults
+ // are checked first. Vaults with the same priority are tested in
+ // unspecified order.
+ chance_priority = 0;
+
+ // Weight for this map. When selecting a map, if no map with a
+ // nonzero chance is picked, one of the other eligible vaults is
+ // picked with a probability of weight / (sum of weights of all
+ // eligible vaults).
+ weight = 10;
// Clearing the map also zaps map transforms.
map.clear();
@@ -1296,7 +1314,9 @@ void map_def::write_index(writer& outf) const
marshallString4(outf, place_loaded_from.filename);
marshallLong(outf, place_loaded_from.lineno);
marshallShort(outf, orient);
+ marshallLong(outf, chance_priority);
marshallLong(outf, chance);
+ marshallLong(outf, weight);
marshallLong(outf, cache_offset);
marshallString4(outf, tags);
place.save(outf);
@@ -1310,7 +1330,9 @@ void map_def::read_index(reader& inf)
unmarshallString4(inf, place_loaded_from.filename);
place_loaded_from.lineno = unmarshallLong(inf);
orient = static_cast<map_section_type>( unmarshallShort(inf) );
+ chance_priority = unmarshallLong(inf);
chance = unmarshallLong(inf);
+ weight = unmarshallLong(inf);
cache_offset = unmarshallLong(inf);
unmarshallString4(inf, tags);
place.load(inf);
@@ -1757,6 +1779,11 @@ bool map_def::has_tag_suffix(const std::string &suffix) const
&& tags.find(suffix + " ") != std::string::npos;
}
+std::vector<std::string> map_def::get_tags() const
+{
+ return split_string(" ", tags);
+}
+
const keyed_mapspec *map_def::mapspec_for_key(int key) const
{
keyed_specs::const_iterator i = keyspecs.find(key);
diff --git a/crawl-ref/source/mapdef.h b/crawl-ref/source/mapdef.h
index 83098d2b5a..ca9da9c113 100644
--- a/crawl-ref/source/mapdef.h
+++ b/crawl-ref/source/mapdef.h
@@ -618,7 +618,10 @@ public:
depth_ranges depths;
map_section_type orient;
+
+ int chance_priority;
int chance;
+ int weight;
std::vector<std::string> welcome_messages;
@@ -711,6 +714,7 @@ public:
bool has_tag(const std::string &tag) const;
bool has_tag_prefix(const std::string &tag) const;
bool has_tag_suffix(const std::string &suffix) const;
+ std::vector<std::string> get_tags() const;
std::vector<std::string> get_shuffle_strings() const;
std::vector<std::string> get_subst_strings() const;
@@ -753,6 +757,8 @@ private:
const std::string &s, bool fixed));
};
+const int CHANCE_ROLL = 10000;
+
std::string escape_string(std::string in, const std::string &toesc,
const std::string &escapewith);
diff --git a/crawl-ref/source/maps.cc b/crawl-ref/source/maps.cc
index cc896d2f22..f2c5827afb 100644
--- a/crawl-ref/source/maps.cc
+++ b/crawl-ref/source/maps.cc
@@ -22,6 +22,7 @@
#include "dungeon.h"
#include "enum.h"
#include "files.h"
+#include "message.h"
#include "monplace.h"
#include "mapdef.h"
#include "misc.h"
@@ -44,7 +45,8 @@ static bool resolve_map(map_def &def, const map_def &original);
//////////////////////////////////////////////////////////////////////////
// New style vault definitions
-static std::vector<map_def> vdefs;
+typedef std::vector<map_def> map_vector;
+static map_vector vdefs;
/* ******************** BEGIN PUBLIC FUNCTIONS ******************* */
@@ -356,111 +358,249 @@ std::vector<std::string> find_map_matches(const std::string &name)
return (matches);
}
-// Returns a map for which PLACE: matches the given place.
-int random_map_for_place(const level_id &place, bool want_minivault)
-{
- if (!place.is_valid())
- return (-1);
+struct map_selector {
+private:
+ enum select_type
+ {
+ PLACE,
+ DEPTH,
+ TAG
+ };
- int mapindex = -1;
- int rollsize = 0;
+public:
+ bool accept(const map_def &md) const;
+ void announce(int vault) const;
- for (unsigned i = 0, size = vdefs.size(); i < size; ++i)
+ bool valid() const
{
- // We also accept tagged levels here.
- if (vdefs[i].place == place
- && vdefs[i].is_minivault() == want_minivault
- && !vdefs[i].has_tag("layout")
- && map_matches_layout_type(vdefs[i])
- && vault_unforbidden(vdefs[i]))
- {
- rollsize += vdefs[i].chance;
+ return (sel == TAG || place.is_valid());
+ }
- if (rollsize && x_chance_in_y(vdefs[i].chance, rollsize))
- mapindex = i;
- }
+ static map_selector by_place(const level_id &place, bool mini)
+ {
+ return map_selector(map_selector::PLACE, place, "", mini, false);
}
- if (mapindex != -1 && vdefs[mapindex].has_tag("dummy"))
- mapindex = -1;
+ static map_selector by_depth(const level_id &place, bool mini)
+ {
+ return map_selector(map_selector::DEPTH, place, "", mini, true);
+ }
+ static map_selector by_tag(const std::string &tag, bool mini,
+ bool check_depth)
+ {
+ return map_selector(map_selector::TAG, level_id::current(), tag,
+ mini, check_depth);
+ }
+
+private:
+ map_selector(select_type _typ, const level_id &_pl,
+ const std::string &_tag,
+ bool _mini, bool _check_depth)
+ : ignore_chance(false), preserve_dummy(false),
+ sel(_typ), place(_pl), tag(_tag),
+ mini(_mini), check_depth(_check_depth),
+ check_layout(sel == DEPTH && place == level_id::current())
+ {
+ }
+
+public:
+ bool ignore_chance;
+ bool preserve_dummy;
+ const select_type sel;
+ const level_id place;
+ const std::string tag;
+ const bool mini;
+ const bool check_depth;
+ const bool check_layout;
+};
+
+bool map_selector::accept(const map_def &mapdef) const
+{
+ switch (sel)
+ {
+ case PLACE:
+ return (mapdef.place == place
+ && mapdef.is_minivault() == mini
+ && !mapdef.has_tag("layout")
+ && map_matches_layout_type(mapdef)
+ && vault_unforbidden(mapdef));
+ case DEPTH:
+ return (mapdef.is_minivault() == mini
+ && !mapdef.place.is_valid()
+ && mapdef.is_usable_in(place)
+ // Some tagged levels cannot be selected by depth. This is
+ // the only thing preventing Pandemonium demon vaults from
+ // showing up in the main dungeon.
+ && !mapdef.has_tag_suffix("entry")
+ && !mapdef.has_tag("pan")
+ && !mapdef.has_tag("unrand")
+ && !mapdef.has_tag("bazaar")
+ && !mapdef.has_tag("layout")
+ && (!check_layout || map_matches_layout_type(mapdef))
+ && vault_unforbidden(mapdef));
+ case TAG:
+ return (mapdef.has_tag(tag) && mapdef.is_minivault() == mini
+ && (!check_depth || !mapdef.has_depth()
+ || mapdef.is_usable_in(place))
+ && map_matches_layout_type(mapdef)
+ && vault_unforbidden(mapdef));
+ default:
+ return (false);
+ }
+}
+
+void map_selector::announce(int vault) const
+{
#ifdef DEBUG_DIAGNOSTICS
- if (mapindex != -1)
- mprf(MSGCH_DIAGNOSTICS, "Found map %s for %s",
- vdefs[mapindex].name.c_str(), place.describe().c_str());
+ if (vault != -1)
+ {
+ const char *format =
+ sel == PLACE? "[PLACE] Found map %s for %s" :
+ sel == DEPTH? "[DEPTH] Found random map %s for %s" :
+ "[TAG] Found map %s tagged '%s'";
+
+ mprf(MSGCH_DIAGNOSTICS, format,
+ vdefs[vault].name.c_str(),
+ sel == TAG? tag.c_str() : place.describe().c_str());
+ }
#endif
+}
- return (mapindex);
+static bool _compare_vault_chance_priority(int a, int b)
+{
+ return (vdefs[b].chance_priority < vdefs[a].chance_priority);
}
-int random_map_in_depth(const level_id &place, bool want_minivault)
+static std::string _vault_chance_tag(const map_def &map)
{
+ if (map.has_tag_prefix("chance_"))
+ {
+ const std::vector<std::string> tags = map.get_tags();
+ for (int i = 0, size = tags.size(); i < size; ++i)
+ {
+ if (tags[i].find("chance_") == 0)
+ return (tags[i]);
+ }
+ }
+ return ("");
+}
+
+static int _random_map_by_selector(const map_selector &sel)
+{
+ if (!sel.valid())
+ return (-1);
+
int mapindex = -1;
int rollsize = 0;
- const bool check_layout = (place == level_id::current());
+ typedef std::vector<unsigned> vault_indices;
+
+ // First build a list of vaults that could be used:
+ vault_indices eligible;
+
+ // Vaults that are eligible and have >0 chance.
+ vault_indices chance;
+
+ typedef std::set<std::string> tag_set;
+ tag_set chance_tags;
for (unsigned i = 0, size = vdefs.size(); i < size; ++i)
- if (vdefs[i].is_minivault() == want_minivault
- && !vdefs[i].place.is_valid()
- && vdefs[i].is_usable_in(place)
- // Some tagged levels cannot be selected by depth. This is
- // the only thing preventing Pandemonium demon vaults from
- // showing up in the main dungeon.
- && !vdefs[i].has_tag_suffix("entry")
- && !vdefs[i].has_tag("pan")
- && !vdefs[i].has_tag("unrand")
- && !vdefs[i].has_tag("bazaar")
- && !vdefs[i].has_tag("layout")
- && (!check_layout || map_matches_layout_type(vdefs[i]))
- && vault_unforbidden(vdefs[i]))
+ if (sel.accept(vdefs[i]))
{
- rollsize += vdefs[i].chance;
-
- if (rollsize && x_chance_in_y(vdefs[i].chance, rollsize))
- mapindex = i;
+ if (!sel.ignore_chance && vdefs[i].chance > 0)
+ {
+ // There may be several alternatives for a portal
+ // vault that want to be governed by one common
+ // CHANCE. In this case each vault will use a
+ // CHANCE, and a common chance_xxx tag. Pick the
+ // first such vault for the chance roll. Note that
+ // at this point we ignore chance_priority.
+ const std::string tag = _vault_chance_tag(vdefs[i]);
+ if (chance_tags.find(tag) == chance_tags.end())
+ {
+ if (!tag.empty())
+ chance_tags.insert(tag);
+ chance.push_back(i);
+ }
+ }
+ else
+ {
+ eligible.push_back(i);
+ }
}
- if (mapindex != -1 && vdefs[mapindex].has_tag("dummy"))
- mapindex = -1;
+ // Sort chances by priority, high priority first.
+ std::sort(chance.begin(), chance.end(), _compare_vault_chance_priority);
- return (mapindex);
-}
+ // Check CHANCEs.
+ for (vault_indices::const_iterator i = chance.begin();
+ i != chance.end(); ++i)
+ {
+ const map_def &map(vdefs[*i]);
+ if (random2(CHANCE_ROLL) < map.chance)
+ {
+ const std::string chance_tag = _vault_chance_tag(map);
+ // If this map has a chance_ tag, convert the search into
+ // a lookup for that tag.
+ if (!chance_tag.empty())
+ {
+ map_selector msel = map_selector::by_tag(sel.tag, sel.mini,
+ sel.check_depth);
+ msel.ignore_chance = true;
+ return _random_map_by_selector(msel);
+ }
-int random_map_for_tag(const std::string &tag,
- bool want_minivault,
- bool check_depth)
-{
- int mapindex = -1;
- int rollsize = 0;
+ mapindex = *i;
+ break;
+ }
+ }
- for (unsigned i = 0, size = vdefs.size(); i < size; ++i)
+ if (mapindex == -1)
{
- if (vdefs[i].has_tag(tag) && vdefs[i].is_minivault() == want_minivault
- && (!check_depth || !vdefs[i].has_depth()
- || vdefs[i].is_usable_in(level_id::current()))
- && map_matches_layout_type(vdefs[i])
- && vault_unforbidden(vdefs[i]))
+ for (vault_indices::const_iterator i = eligible.begin();
+ i != eligible.end(); ++i)
{
- rollsize += vdefs[i].chance;
+ const map_def &map(vdefs[*i]);
+ rollsize += map.weight;
- if (rollsize && x_chance_in_y(vdefs[i].chance, rollsize))
- mapindex = i;
+ if (rollsize && x_chance_in_y(map.weight, rollsize))
+ mapindex = *i;
}
}
- if (mapindex != -1 && vdefs[mapindex].has_tag("dummy"))
+ if (!sel.preserve_dummy && mapindex != -1
+ && vdefs[mapindex].has_tag("dummy"))
+ {
mapindex = -1;
+ }
-#ifdef DEBUG_DIAGNOSTICS
- if (mapindex != -1)
- mprf(MSGCH_DIAGNOSTICS, "Found map %s tagged '%s'",
- vdefs[mapindex].name.c_str(), tag.c_str());
-#endif
+ sel.announce(mapindex);
return (mapindex);
}
+// Returns a map for which PLACE: matches the given place.
+int random_map_for_place(const level_id &place, bool want_minivault)
+{
+ return _random_map_by_selector(
+ map_selector::by_place(place, want_minivault));
+}
+
+int random_map_in_depth(const level_id &place, bool want_minivault)
+{
+ return _random_map_by_selector(
+ map_selector::by_depth(place, want_minivault));
+}
+
+int random_map_for_tag(const std::string &tag,
+ bool want_minivault,
+ bool check_depth)
+{
+ return _random_map_by_selector(
+ map_selector::by_tag(tag, want_minivault, check_depth));
+}
+
const map_def *map_by_index(int index)
{
if (index < 0 || index >= (int) vdefs.size())
@@ -745,6 +885,14 @@ void run_map_preludes()
typedef std::pair<std::string, int> weighted_map_name;
typedef std::vector<weighted_map_name> weighted_map_names;
+static int _mg_random_vault_here(const level_id &place, bool mini)
+{
+ no_messages mx;
+ map_selector sel = map_selector::by_depth(place, mini);
+ sel.preserve_dummy = true;
+ return _random_map_by_selector(sel);
+}
+
static weighted_map_names mg_find_random_vaults(
const level_id &place, bool wantmini)
{
@@ -753,22 +901,23 @@ static weighted_map_names mg_find_random_vaults(
if (!place.is_valid())
return (wms);
- for (unsigned i = 0, size = vdefs.size(); i < size; ++i)
+ typedef std::map<std::string, int> map_count_t;
+
+ map_count_t map_counts;
+
+ for (int i = 0; i < 10000; ++i)
{
- if (vdefs[i].is_minivault() == wantmini
- && !vdefs[i].place.is_valid()
- && vdefs[i].is_usable_in(place)
- // Some tagged levels cannot be selected by depth. This is
- // the only thing preventing Pandemonium demon vaults from
- // showing up in the main dungeon.
- && !vdefs[i].has_tag_suffix("entry")
- && !vdefs[i].has_tag("pan")
- && !vdefs[i].has_tag("unrand")
- && !vdefs[i].has_tag("bazaar"))
- {
- wms.push_back(
- weighted_map_name( vdefs[i].name, vdefs[i].chance ) );
- }
+ const int v = _mg_random_vault_here(place, wantmini);
+ if (v == -1)
+ map_counts["(none)"]++;
+ else
+ map_counts[vdefs[v].name]++;
+ }
+
+ for (map_count_t::const_iterator i = map_counts.begin();
+ i != map_counts.end(); ++i)
+ {
+ wms.push_back(*i);
}
return (wms);
@@ -794,7 +943,7 @@ static void mg_report_random_vaults(
for (int i = 0, size = wms.size(); i < size; ++i)
{
std::string curr =
- make_stringf("%s (%.2f%%)",
+ make_stringf("%s (%.4f%%)",
wms[i].first.c_str(),
100.0 * wms[i].second / weightsum);
if (i < size - 1)
diff --git a/crawl-ref/source/maps.h b/crawl-ref/source/maps.h
index f2f35a275e..20dc1709c1 100644
--- a/crawl-ref/source/maps.h
+++ b/crawl-ref/source/maps.h
@@ -71,7 +71,7 @@ extern depth_ranges lc_default_depths;
extern dlua_chunk lc_global_prelude;
extern bool lc_run_global_prelude;
-const int MAP_CACHE_VERSION = 1007;
+const int MAP_CACHE_VERSION = 1008;
#ifdef DEBUG_DIAGNOSTICS
diff --git a/crawl-ref/source/util/levcomp.lpp b/crawl-ref/source/util/levcomp.lpp
index 590cd59122..41d3b60b0f 100644
--- a/crawl-ref/source/util/levcomp.lpp
+++ b/crawl-ref/source/util/levcomp.lpp
@@ -236,7 +236,7 @@ ORIENT: { CBEGIN(ARGUMENT); return ORIENT; }
PLACE: { CBEGIN(ARGUMENT); return PLACE; }
WELCOME: { CBEGIN(ARGUMENT); return WELCOME; }
CHANCE: return CHANCE;
-WEIGHT: return CHANCE;
+WEIGHT: return WEIGHT;
FLAGS: { CBEGIN(KEYWORDS); return TAGS; }
TAGS: { CBEGIN(KEYWORDS); return TAGS; }
LFLAGS: { CBEGIN(ARGUMENT); return LFLAGS; }
@@ -258,7 +258,11 @@ KMASK: { CBEGIN(ARGUMENT); return KMASK; }
, return COMMA;
-[0-9]+ {
+: return COLON;
+
+% return PERC;
+
+[+-]?[0-9]+ {
clean();
yylval.i = atoi(yytext);
return INTEGER;
diff --git a/crawl-ref/source/util/levcomp.ypp b/crawl-ref/source/util/levcomp.ypp
index f2bb2b17b6..a678937ea9 100644
--- a/crawl-ref/source/util/levcomp.ypp
+++ b/crawl-ref/source/util/levcomp.ypp
@@ -53,11 +53,11 @@ level_range set_range(const char *s, int start, int end)
%expect 2
%token <i> DEFAULT_DEPTH SHUFFLE SUBST TAGS KFEAT KITEM KMONS KMASK
-%token <i> NAME DEPTH ORIENT PLACE CHANCE MONS ITEM MARKER COLOUR
+%token <i> NAME DEPTH ORIENT PLACE CHANCE WEIGHT MONS ITEM MARKER COLOUR
%token <i> PRELUDE MAIN VALIDATE VETO NSUBST WELCOME LFLAGS BFLAGS
%token <i> FLOORCOL ROCKCOL
-%token <i> COMMA INTEGER CHARACTER
+%token <i> COMMA COLON PERC INTEGER CHARACTER
%token <text> STRING MAP_LINE MONSTER_NAME ITEM_INFO
%token <text> LUA_LINE
@@ -152,6 +152,7 @@ name : NAME STRING
metaline : place
| depth
| chance
+ | weight
| orientation
| welcome
| mons
@@ -468,11 +469,40 @@ depth : DEPTH {}
}
;
-chance : CHANCE INTEGER
+chance : CHANCE INTEGER COLON INTEGER PERC
{
lc_map.main.add(
yylineno,
- make_stringf("chance(\"%d\")", $2));
+ make_stringf("chance(%d, %d)", $2, $4 * 100));
+ }
+ |
+ CHANCE INTEGER COLON INTEGER
+ {
+ lc_map.main.add(
+ yylineno,
+ make_stringf("chance(%d, %d)", $2, $4));
+ }
+ |
+ CHANCE INTEGER PERC
+ {
+ lc_map.main.add(
+ yylineno,
+ make_stringf("chance(0, %d)", $2 * 100));
+ }
+ |
+ CHANCE INTEGER
+ {
+ lc_map.main.add(
+ yylineno,
+ make_stringf("chance(0, %d)", $2));
+ }
+ ;
+
+weight : WEIGHT INTEGER
+ {
+ lc_map.main.add(
+ yylineno,
+ make_stringf("weight(%d)", $2));
}
;