summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJude Brown <bookofjude@users.sourceforge.net>2009-11-09 17:49:56 +1000
committerJude Brown <bookofjude@users.sourceforge.net>2009-11-09 17:51:07 +1000
commit6f22c1aa223a666ae4d9d65f9f400b2fc0374dfd (patch)
tree669c223415f2b0877f9ee295017969a0dfc565d4
parentc3074999a910d76d6f5f2c644894a7baeb3a0d49 (diff)
downloadcrawl-ref-6f22c1aa223a666ae4d9d65f9f400b2fc0374dfd.tar.gz
crawl-ref-6f22c1aa223a666ae4d9d65f9f400b2fc0374dfd.zip
Finally move unique monster placement to Lua.
See dat/uniques.des for more information and a quick run down on how things work. Unique placement now should be roughly similar to unique placement before; weights may need to be adjusted, but initial statistics seem to be very, very similar.
-rw-r--r--crawl-ref/source/dat/uniques.des602
-rw-r--r--crawl-ref/source/dungeon.cc183
-rw-r--r--crawl-ref/source/maps.cc2
-rw-r--r--crawl-ref/source/monstuff.cc2
4 files changed, 635 insertions, 154 deletions
diff --git a/crawl-ref/source/dat/uniques.des b/crawl-ref/source/dat/uniques.des
new file mode 100644
index 0000000000..fe06de9d21
--- /dev/null
+++ b/crawl-ref/source/dat/uniques.des
@@ -0,0 +1,602 @@
+################################################################################
+# uniques.des: This is where unique placement should be defined. You should use
+# the format set in the example vault.
+################################################################################
+# Most of this should be self-explanatory. Vaults tagged as "place_unique" are
+# assumed to place only one unique. If the unique is in a band, specify "unique
+# band", (see uniq_duvessa, etc). Names of vault don't matter, except for the
+# Boris vault.
+#
+# If you want to weight uniques different for different, the different vaults
+# should all add up to 10 (the current default weight for uniques), you can use
+# multiple vaults that are tagged "uniq_<name>", with different weights for each
+# of the vaults.
+#
+# As a final caveat, you.branches[you.where_are_you].has_uniques is still checked
+# before vaults are even considered; unique vaults with depths that could take
+# in Lair should be specified !Lair (unless you want them in lair).
+#
+# You can define DEBUG_UNIQUE_PLACEMENT and get a per-level unique generation
+# report in "unique_placement.log" in debug mode.
+#
+################################################################################
+#
+# Dummy, weight will need eventual adjustment.
+NAME: uniq_dummy
+DEPTH: 1-50
+WEIGHT: 15
+TAGS: place_unique dummy
+MAP
+.
+ENDMAP
+
+################################################################################
+# General dungeon uniques:
+################################################################################
+NAME: uniq_terence
+DEPTH: 1-3
+TAGS: place_unique
+MONS: Terence
+MAP
+1
+ENDMAP
+
+NAME: uniq_jessica
+DEPTH: 1-3
+TAGS: place_unique
+MONS: Jessica
+MAP
+1
+ENDMAP
+
+NAME: uniq_iyjb
+DEPTH: 1-3, 4-7
+TAGS: place_unique
+MONS: Ijyb
+MAP
+1
+ENDMAP
+
+NAME: uniq_sigmund
+DEPTH: 1-3, 4-7
+TAGS: place_unique
+MONS: Sigmund
+MAP
+1
+ENDMAP
+
+NAME: uniq_blork_the_orc
+DEPTH: 4-7, 8-9, !Lair
+TAGS: place_unique
+MONS: Blork the orc
+MAP
+1
+ENDMAP
+
+NAME: uniq_edmund
+DEPTH: 4-7, 8-9, !Lair
+MONS: Edmund
+MAP
+1
+ENDMAP
+
+NAME: uniq_prince_ribbit
+DEPTH: 4-7, 8-9, Lair:1-3
+TAGS: place_unique
+MONS: Prince Ribbit
+MAP
+1
+ENDMAP
+
+NAME: uniq_purgy
+DEPTH: 4-7
+TAGS: place_unique
+MONS: Purgy
+MAP
+1
+ENDMAP
+
+NAME: uniq_menkaure
+DEPTH: 4-7
+TAGS: place_unique
+MONS: Menkaure
+MAP
+1
+ENDMAP
+
+NAME: uniq_duvessa
+DEPTH: 4-7, 8-9, !Lair
+TAGS: place_unique
+MONS: Duvessa band
+MAP
+1
+ENDMAP
+
+NAME: uniq_pikel
+DEPTH: 4-7, 8-9, !Lair, !Orc
+TAGS: place_unique
+MONS: Pikel band
+MAP
+1
+ENDMAP
+
+NAME: uniq_psyche
+DEPTH: 8-9, 10-13, !Lair
+TAGS: place_unique
+MONS: Psyche
+MAP
+1
+ENDMAP
+
+NAME: uniq_erolcha
+DEPTH: 8-9, 10-13, !Lair
+TAGS: place_unique
+MONS: Erolcha
+MAP
+1
+ENDMAP
+
+NAME: uniq_grum
+DEPTH: 8-9, 10-13, !Lair
+TAGS: place_unique
+MONS: Gastronok
+MAP
+1
+ENDMAP
+
+NAME: uniq_maurice
+DEPTH: 8-9, 10-13, !Lair
+TAGS: place_unique
+MONS: Maurice
+MAP
+1
+ENDMAP
+
+NAME: uniq_donald
+DEPTH: 10-13, !Lair
+TAGS: place_unique
+MONS: Donald
+MAP
+1
+ENDMAP
+
+NAME: uniq_urug
+DEPTH: 10-13, 14-16, !Lair, !Tomb
+TAGS: place_unique
+MONS: Urug
+MAP
+1
+ENDMAP
+
+NAME: uniq_michael
+DEPTH: 10-13, 14-16, !Lair, !Tomb
+TAGS: place_unique
+MONS: Michael
+MAP
+1
+ENDMAP
+
+NAME: uniq_eustachio
+DEPTH: 10-13, 14-16, !Lair, !Tomb
+TAGS: place_unique
+MONS: Eustachio
+MAP
+1
+ENDMAP
+
+NAME: uniq_sonja
+DEPTH: 10-13, 14-16, !Lair, !Tomb
+TAGS: place_unique
+MONS: Sonja
+MAP
+1
+ENDMAP
+
+NAME: uniq_joseph
+DEPTH: 10-13, !Lair
+TAGS: place_unique
+MONS: Joseph
+MAP
+1
+ENDMAP
+
+NAME: uniq_erica
+DEPTH: 10-13, 14-16, !Lair, !Tomb
+TAGS: place_unique
+MONS: Erica
+MAP
+1
+ENDMAP
+
+NAME: uniq_josephine
+DEPTH: 10-13, 14-16, !Lair, !Tomb
+TAGS: place_unique
+MONS: Josephine band
+MAP
+1
+ENDMAP
+
+NAME: uniq_jozef
+DEPTH: 10-13, 14-16, !Lair, !Tomb
+TAGS: place_unique
+MONS: Jozef
+MAP
+1
+ENDMAP
+
+NAME: uniq_harold
+DEPTH: 10-13, 14-16, !Lair, !Tomb
+TAGS: place_unique
+MONS: Harold
+MAP
+1
+ENDMAP
+
+NAME: uniq_norbert
+DEPTH: 10-13, 14-16, !Lair, !Tomb
+TAGS: place_unique
+MONS: Norbert
+MAP
+1
+ENDMAP
+
+NAME: uniq_snorg
+DEPTH: 14-16, 17-19, !Tomb
+TAGS: place_unique
+MONS: Snorg
+MAP
+1
+ENDMAP
+
+NAME: uniq_roxanne
+DEPTH: 14-16, 17-19, !Tomb
+TAGS: place_unique
+MONS: Roxanne
+MAP
+1
+ENDMAP
+
+NAME: uniq_rupert
+DEPTH: 14-16, 17-19, !Tomb
+TAGS: place_unique
+MONS: Rupert
+MAP
+1
+ENDMAP
+
+NAME: uniq_azrael
+DEPTH: 14-16, 17-19, !Tomb, !Swamp, !Shoal
+TAGS: place_unique
+MONS: Azrael band
+MAP
+1
+ENDMAP
+
+NAME: uniq_nessos
+DEPTH: 14-16, 17-19, !Tomb
+TAGS: place_unique
+MONS: Nessos
+MAP
+1
+ENDMAP
+
+NAME: uniq_agnes
+DEPTH: 14-16, !Tomb
+TAGS: place_unique
+MONS: Agnes
+MAP
+1
+ENDMAP
+
+NAME: uniq_nikola
+DEPTH: 14-16, 17-19, !Tomb
+TAGS: place_unique
+MONS: Nikola
+MAP
+1
+ENDMAP
+
+NAME: uniq_maud
+DEPTH: 14-16, !Tomb
+TAGS: place_unique
+MONS: Maud
+MAP
+1
+ENDMAP
+
+NAME: uniq_louise
+DEPTH: 14-16, 17-19, !Tomb
+TAGS: place_unique
+MONS: Louise
+MAP
+1
+ENDMAP
+
+NAME: uniq_nergalle
+DEPTH: 14-16, 17-19, !Tomb
+TAGS: place_unique
+MONS: Nergalle
+MAP
+1
+ENDMAP
+
+NAME: uniq_kirke
+DEPTH: 14-16, 17-19, !Tomb
+TAGS: place_unique
+MONS: Kirke band
+MAP
+1
+ENDMAP
+
+NAME: uniq_francis
+DEPTH: 17-19, 20-27, !Tomb
+TAGS: place_unique
+MONS: Francis
+MAP
+1
+ENDMAP
+
+NAME: uniq_frances
+DEPTH: 17-19, 20-27, !Tomb
+TAGS: place_unique
+MONS: Frances
+MAP
+1
+ENDMAP
+
+NAME: uniq_wayne
+DEPTH: 17-19, 20-27, !Tomb
+TAGS: place_unique
+MONS: Wayne
+MAP
+1
+ENDMAP
+
+NAME: uniq_duane
+DEPTH: 17-19, 20-27, !Tomb
+TAGS: place_unique
+MONS: Duane
+MAP
+1
+ENDMAP
+
+NAME: uniq_norris
+DEPTH: 17-19, !Tomb
+TAGS: place_unique
+MONS: Norris
+MAP
+1
+ENDMAP
+
+NAME: uniq_saint_roka
+DEPTH: 17-19, 20-27, !Tomb
+TAGS: place_unique
+MONS: Saint Roka band
+MAP
+1
+ENDMAP
+
+NAME: uniq_xtahua
+DEPTH: 20-27, !Tomb
+TAGS: place_unique
+MONS: Xtahua
+MAP
+1
+ENDMAP
+
+NAME: uniq_frederick
+DEPTH: 20-27, !Tomb
+TAGS: place_unique
+MONS: Frederick
+MAP
+1
+ENDMAP
+
+NAME: uniq_margery
+DEPTH: 20-27, !Tomb
+TAGS: place_unique
+MONS: Margery band
+MAP
+1
+ENDMAP
+
+###############################################################################
+# Do *not* change the name of this vault without changing the relevant section
+# in monstuff.cc:monster_die. If wishing to alter Boris's weights by using
+# multiple uniq_boris TAG'd maps, ensure that you add the relevant line to
+# remove the tag in monstuff.cc:monster_die.
+NAME: uniq_boris
+DEPTH: 20-27
+TAGS: place_unique
+MONS: Boris
+MAP
+1
+ENDMAP
+
+NAME: uniq_aizul
+DEPTH: 20-27, !Tomb
+TAGS: place_unique
+MONS: Aizul
+MAP
+1
+ENDMAP
+################################################################################
+# Non-dungeon Uniques
+################################################################################
+
+NAME: uniq_dissolution
+DEPTH: Slime:2-6
+TAGS: place_unique
+MONS: Dissolution
+MAP
+1
+ENDMAP
+
+NAME: uniq_murray
+DEPTH: Hell
+TAGS: place_unique
+MONS: Murray
+MAP
+1
+ENDMAP
+
+NAME: uniq_polyphemus
+DEPTH: Shoal:1-5
+TAGS: place_unique
+MONS: Polyphemus band
+MAP
+1
+ENDMAP
+
+NAME: uniq_ilsuiw
+DEPTH: Shoal:1-5
+TAGS: place_unique
+MONS: Ilsuiw band
+MAP
+1
+ENDMAP
+
+NAME: uniq_khufu
+DEPTH: Tomb, Crypt
+TAGS: place_unique
+MONS: Khufu band
+MAP
+1
+ENDMAP
+
+NAME: uniq_tiamat
+DEPTH: Zot
+TAGS: place_unique
+MONS: Tiamat band
+MAP
+1
+ENDMAP
+
+################################################################################
+# The original C++ code for unique placement was:
+# static monster_type _pick_unique(int lev)
+# {
+# if (player_in_branch(BRANCH_SLIME_PITS))
+# {
+# // Only allow Dissolution in the Slime Pits.
+# if (player_branch_depth() > 1 && one_chance_in(3))
+# return MONS_DISSOLUTION;
+#
+# return MONS_NO_MONSTER;
+# }
+# else if (player_in_branch(BRANCH_LAIR))
+# {
+# if (player_branch_depth() > 5 && one_chance_in(3))
+# return MONS_GASTRONOK;
+# else if (player_branch_depth() < 3 && one_chance_in(4))
+# return MONS_PRINCE_RIBBIT;
+# else
+# return MONS_NO_MONSTER;
+# }
+# else if (player_in_branch(BRANCH_SNAKE_PIT))
+# {
+# if (player_branch_depth() > 3 && coinflip())
+# return MONS_AIZUL;
+# }
+#
+# // First, pick generic unique depending on depth.
+# int which_unique =
+# ((lev <= 3) ? _choose_unique_by_depth(0) :
+# (lev <= 7) ? _choose_unique_by_depth(1) :
+# (lev <= 9) ? _choose_unique_by_depth(2) :
+# (lev <= 13) ? _choose_unique_by_depth(3) :
+# (lev <= 16) ? _choose_unique_by_depth(4) :
+# (lev <= 19) ? _choose_unique_by_depth(5) :
+# _choose_unique_by_depth(6));
+#
+# // Azrael may not be created in the Swamp or Shoals.
+# if (which_unique == MONS_AZRAEL
+# && (player_in_branch(BRANCH_SWAMP) || player_in_branch(BRANCH_SHOALS)))
+# {
+# return MONS_NO_MONSTER;
+# }
+#
+# // If applicable, replace it with one of the uniques appearing
+# // only in some branches.
+# if (player_in_branch(BRANCH_VESTIBULE_OF_HELL))
+# {
+# if (one_chance_in(7))
+# which_unique = MONS_MURRAY;
+# }
+# else if (player_in_branch(BRANCH_HALL_OF_ZOT))
+# {
+# if (one_chance_in(3))
+# which_unique = MONS_TIAMAT;
+# }
+# else if (player_in_branch(BRANCH_SHOALS))
+# {
+# if (player_branch_depth() > 1 && coinflip())
+# which_unique = MONS_POLYPHEMUS;
+# else if (player_branch_depth() > 2 && coinflip())
+# which_unique = MONS_ILSUIW;
+# }
+# else if (player_in_branch(BRANCH_TOMB) || player_in_branch(BRANCH_CRYPT))
+# {
+# if (one_chance_in(10))
+# which_unique = MONS_KHUFU;
+# }
+#
+# return static_cast<monster_type>(which_unique);
+# }
+#
+# // Doesn't include Polyphemus or Ilsuiw (only appear in the Shoals),
+# // Dissolution (Slime), Murray (Hell), Khufu(Tomb/Crypt) or Tiamat (Zot).
+# // NOTE: The Lernaean hydra should *never* be randomly generated.
+# // The Royal jelly likewise is only placed via Slime end vault.
+# // Dowan is automatically placed together with Duvessa.
+# static monster_type _choose_unique_by_depth(int step)
+# {
+# int ret;
+# switch (step)
+# {
+# case 0: // depth <= 3
+# ret = random_choose(MONS_TERENCE, MONS_JESSICA, MONS_IJYB,
+# MONS_SIGMUND, -1);
+# break;
+# case 1: // depth <= 7
+# ret = random_choose(MONS_IJYB, MONS_SIGMUND, MONS_BLORK_THE_ORC,
+# MONS_EDMUND, MONS_PRINCE_RIBBIT, MONS_PURGY,
+# MONS_MENKAURE, MONS_DUVESSA, MONS_PIKEL, -1);
+# break;
+# case 2: // depth <= 9
+# ret = random_choose(MONS_BLORK_THE_ORC, MONS_EDMUND, MONS_PSYCHE,
+# MONS_EROLCHA, MONS_PRINCE_RIBBIT, MONS_GRUM,
+# MONS_GASTRONOK, MONS_MAURICE, MONS_PIKEL, -1);
+# break;
+# case 3: // depth <= 13
+# ret = random_choose(MONS_PSYCHE, MONS_EROLCHA, MONS_DONALD, MONS_URUG,
+# MONS_MICHAEL, MONS_EUSTACHIO, MONS_SONJA, MONS_GRUM,
+# MONS_JOSEPH, MONS_ERICA, MONS_JOSEPHINE, MONS_JOZEF,
+# MONS_HAROLD, MONS_NORBERT, MONS_GASTRONOK,
+# MONS_MAURICE, -1);
+# break;
+# case 4: // depth <= 16
+# ret = random_choose(MONS_URUG, MONS_MICHAEL, MONS_EUSTACHIO, MONS_SONJA,
+# MONS_SNORG, MONS_ERICA, MONS_JOSEPHINE, MONS_HAROLD,
+# MONS_ROXANNE, MONS_RUPERT, MONS_NORBERT, MONS_JOZEF,
+# MONS_AZRAEL, MONS_NESSOS, MONS_AGNES, MONS_NIKOLA,
+# MONS_MAUD, MONS_LOUISE, MONS_NERGALLE, MONS_KIRKE, -1);
+# break;
+# case 5: // depth <= 19
+# ret = random_choose(MONS_SNORG, MONS_LOUISE, MONS_FRANCIS, MONS_FRANCES,
+# MONS_RUPERT, MONS_WAYNE, MONS_DUANE, MONS_NORRIS,
+# MONS_AZRAEL, MONS_NESSOS, MONS_NERGALLE, MONS_NIKOLA,
+# MONS_ROXANNE, MONS_SAINT_ROKA, MONS_KIRKE, -1);
+# break;
+# case 6: // depth > 19
+# default:
+# ret = random_choose(MONS_FRANCIS, MONS_FRANCES, MONS_WAYNE, MONS_DUANE,
+# MONS_XTAHUA, MONS_NORRIS, MONS_FREDERICK, MONS_NIKOLA,
+# MONS_MARGERY, MONS_BORIS, MONS_SAINT_ROKA, MONS_AIZUL,
+# -1);
+# }
+#
+# return static_cast<monster_type>(ret);
+# }
+#
+#
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index ce6e72487c..b3c6d1b962 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -3330,131 +3330,6 @@ static bool _make_room(int sx,int sy,int ex,int ey,int max_doors, int doorlevel)
return (true);
}
-// Doesn't include Polyphemus or Ilsuiw (only appear in the Shoals),
-// Dissolution (Slime), Murray (Hell), Khufu(Tomb/Crypt) or Tiamat (Zot).
-// NOTE: The Lernaean hydra should *never* be randomly generated.
-// The Royal jelly likewise is only placed via Slime end vault.
-// Dowan is automatically placed together with Duvessa.
-static monster_type _choose_unique_by_depth(int step)
-{
- int ret;
- switch (step)
- {
- case 0: // depth <= 3
- ret = random_choose(MONS_TERENCE, MONS_JESSICA, MONS_IJYB,
- MONS_SIGMUND, -1);
- break;
- case 1: // depth <= 7
- ret = random_choose(MONS_IJYB, MONS_SIGMUND, MONS_BLORK_THE_ORC,
- MONS_EDMUND, MONS_PRINCE_RIBBIT, MONS_PURGY,
- MONS_MENKAURE, MONS_DUVESSA, MONS_PIKEL, -1);
- break;
- case 2: // depth <= 9
- ret = random_choose(MONS_BLORK_THE_ORC, MONS_EDMUND, MONS_PSYCHE,
- MONS_EROLCHA, MONS_PRINCE_RIBBIT, MONS_GRUM,
- MONS_GASTRONOK, MONS_MAURICE, MONS_PIKEL, -1);
- break;
- case 3: // depth <= 13
- ret = random_choose(MONS_PSYCHE, MONS_EROLCHA, MONS_DONALD, MONS_URUG,
- MONS_MICHAEL, MONS_EUSTACHIO, MONS_SONJA, MONS_GRUM,
- MONS_JOSEPH, MONS_ERICA, MONS_JOSEPHINE, MONS_JOZEF,
- MONS_HAROLD, MONS_NORBERT, MONS_GASTRONOK,
- MONS_MAURICE, -1);
- break;
- case 4: // depth <= 16
- ret = random_choose(MONS_URUG, MONS_MICHAEL, MONS_EUSTACHIO, MONS_SONJA,
- MONS_SNORG, MONS_ERICA, MONS_JOSEPHINE, MONS_HAROLD,
- MONS_ROXANNE, MONS_RUPERT, MONS_NORBERT, MONS_JOZEF,
- MONS_AZRAEL, MONS_NESSOS, MONS_AGNES, MONS_NIKOLA,
- MONS_MAUD, MONS_LOUISE, MONS_NERGALLE, MONS_KIRKE, -1);
- break;
- case 5: // depth <= 19
- ret = random_choose(MONS_SNORG, MONS_LOUISE, MONS_FRANCIS, MONS_FRANCES,
- MONS_RUPERT, MONS_WAYNE, MONS_DUANE, MONS_NORRIS,
- MONS_AZRAEL, MONS_NESSOS, MONS_NERGALLE, MONS_NIKOLA,
- MONS_ROXANNE, MONS_SAINT_ROKA, MONS_KIRKE, -1);
- break;
- case 6: // depth > 19
- default:
- ret = random_choose(MONS_FRANCIS, MONS_FRANCES, MONS_WAYNE, MONS_DUANE,
- MONS_XTAHUA, MONS_NORRIS, MONS_FREDERICK, MONS_NIKOLA,
- MONS_MARGERY, MONS_BORIS, MONS_SAINT_ROKA, MONS_AIZUL,
- -1);
- }
-
- return static_cast<monster_type>(ret);
-}
-
-static monster_type _pick_unique(int lev)
-{
- if (player_in_branch(BRANCH_SLIME_PITS))
- {
- // Only allow Dissolution in the Slime Pits.
- if (player_branch_depth() > 1 && one_chance_in(3))
- return MONS_DISSOLUTION;
-
- return MONS_NO_MONSTER;
- }
- else if (player_in_branch(BRANCH_LAIR))
- {
- if (player_branch_depth() > 5 && one_chance_in(3))
- return MONS_GASTRONOK;
- else if (player_branch_depth() < 3 && one_chance_in(4))
- return MONS_PRINCE_RIBBIT;
- else
- return MONS_NO_MONSTER;
- }
- else if (player_in_branch(BRANCH_SNAKE_PIT))
- {
- if (player_branch_depth() > 3 && coinflip())
- return MONS_AIZUL;
- }
-
- // First, pick generic unique depending on depth.
- int which_unique =
- ((lev <= 3) ? _choose_unique_by_depth(0) :
- (lev <= 7) ? _choose_unique_by_depth(1) :
- (lev <= 9) ? _choose_unique_by_depth(2) :
- (lev <= 13) ? _choose_unique_by_depth(3) :
- (lev <= 16) ? _choose_unique_by_depth(4) :
- (lev <= 19) ? _choose_unique_by_depth(5) :
- _choose_unique_by_depth(6));
-
- // Azrael may not be created in the Swamp or Shoals.
- if (which_unique == MONS_AZRAEL
- && (player_in_branch(BRANCH_SWAMP) || player_in_branch(BRANCH_SHOALS)))
- {
- return MONS_NO_MONSTER;
- }
-
- // If applicable, replace it with one of the uniques appearing
- // only in some branches.
- if (player_in_branch(BRANCH_VESTIBULE_OF_HELL))
- {
- if (one_chance_in(7))
- which_unique = MONS_MURRAY;
- }
- else if (player_in_branch(BRANCH_HALL_OF_ZOT))
- {
- if (one_chance_in(3))
- which_unique = MONS_TIAMAT;
- }
- else if (player_in_branch(BRANCH_SHOALS))
- {
- if (player_branch_depth() > 1 && coinflip())
- which_unique = MONS_POLYPHEMUS;
- else if (player_branch_depth() > 2 && coinflip())
- which_unique = MONS_ILSUIW;
- }
- else if (player_in_branch(BRANCH_TOMB) || player_in_branch(BRANCH_CRYPT))
- {
- if (one_chance_in(10))
- which_unique = MONS_KHUFU;
- }
-
- return static_cast<monster_type>(which_unique);
-}
-
// Place uniques on the level.
// There is a hidden dependency on the player's actual
// location (through your_branch()).
@@ -3468,48 +3343,48 @@ static int _place_uniques(int level_number, char level_type)
return 0;
}
+#ifdef DEBUG_UNIQUE_PLACEMENT
+ FILE *ostat = fopen("unique_placement.log", "a");
+ fprintf(ostat, "--- Looking to place uniques on: Level %d of %s ---\n", level_number, your_branch().shortname);
+#endif
+
int num_placed = 0;
- while (one_chance_in(3))
+ while (coinflip())
{
- monster_type which_unique = MONS_NO_MONSTER;
+ const map_def *uniq_map = random_map_for_tag("place_unique", true);
- while (which_unique == MONS_NO_MONSTER
- || you.unique_creatures[which_unique])
+ if (!uniq_map)
{
- which_unique = _pick_unique(level_number);
-
- // Sometimes, we just quit if a unique is already placed.
- if (which_unique == MONS_NO_MONSTER
- || you.unique_creatures[which_unique] && !one_chance_in(3))
- {
- which_unique = MONS_NO_MONSTER;
- break;
- }
- }
-
- // Usually, we'll have quit after a few tries. Make sure we have
- // a valid unique.
- if (which_unique == MONS_NO_MONSTER)
+#ifdef DEBUG_UNIQUE_PLACEMENT
+ fprintf(ostat, "Dummy balance or no uniques left.\n");
+#endif
break;
+ }
- mgen_data mg(which_unique, BEH_SLEEP, 0, 0,
- coord_def(), MHITNOT, MG_PERMIT_BANDS,
- GOD_NO_GOD, MONS_NO_MONSTER, 0, BLACK,
- level_number, PROX_ANYWHERE);
- mg.map_mask = MMT_NO_MONS;
-
- const int mindex = place_monster(mg);
- if (mindex != -1)
+ if (dgn_place_map(uniq_map, true, false))
{
+ num_placed++;
+#ifdef DEBUG_UNIQUE_PLACEMENT
+ fprintf(ostat, "Placed valid unique map: %s.\n", uniq_map->name.c_str());
+#endif
#ifdef DEBUG_DIAGNOSTICS
- mprf(MSGCH_DIAGNOSTICS, "Placed %s",
- menv[mindex].name(DESC_NOCAP_A).c_str());
+ mprf(MSGCH_DIAGNOSTICS, "Placed %s.",
+ uniq_map->name.c_str());
+ }
#endif
- ++num_placed;
+#ifdef DEBUG_UNIQUE_PLACEMENT
+ else
+ {
+ fprintf(ostat, "Didn't place valid map: %s\n", uniq_map->name.c_str());
}
+#endif
}
+#ifdef DEBUG_UNIQUE_PLACEMENT
+ fprintf(ostat, "--- Finished this set, placed %d uniques.\n", num_placed);
+ fclose(ostat);
+#endif
return num_placed;
}
diff --git a/crawl-ref/source/maps.cc b/crawl-ref/source/maps.cc
index 01a8d90932..06a47f6100 100644
--- a/crawl-ref/source/maps.cc
+++ b/crawl-ref/source/maps.cc
@@ -506,6 +506,7 @@ bool map_selector::accept(const map_def &mapdef) const
return (mapdef.is_minivault() == mini
&& mapdef.place == place
&& !mapdef.has_tag("layout")
+ && !mapdef.has_tag("place_unique")
&& map_matches_layout_type(mapdef)
&& vault_unforbidden(mapdef));
case DEPTH:
@@ -520,6 +521,7 @@ bool map_selector::accept(const map_def &mapdef) const
&& !mapdef.has_tag("unrand")
&& !mapdef.has_tag("bazaar")
&& !mapdef.has_tag("layout")
+ && !mapdef.has_tag("place_unique")
&& (!check_layout || map_matches_layout_type(mapdef))
&& vault_unforbidden(mapdef));
case TAG:
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 8a8e48f753..563e6aec1b 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -2019,6 +2019,8 @@ int monster_die(monsters *monster, killer_type killer,
// Now that Boris is dead, he's a valid target for monster
// creation again. -- bwr
you.unique_creatures[monster->type] = false;
+ // And his vault can be placed again.
+ you.uniq_map_names.erase("uniq_boris");
}
else if (monster->type == MONS_KIRKE && !in_transit)
{