################################################################################
# uniques.des: This is where unique placement should be defined.
################################################################################
# Most of this should be self-explanatory. A unique vault can be defined by
#
# NAME:   uniq_linley
# DEPTH:  D:2-, !Orc
# WEIGHT: 10
# TAGS:   place_unique
# MONS:   Linley
# MAP
# 1
# ENDMAP
#
# This assumes that the unique is defined as a monster in the files
#   enum.h, mon-gear.cc, mon-data.h,  mon-spell.h, tilemcache.cc, tilepick.cc
# Their speech is defined in
#   dat/database/monspeak.txt
#
# 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.
#
# For most purposes, a vault like the above sample is desired. You can use the
# inline function place_unique in this case, reducing to
#
# NAME:   uniq_linley
# DEPTH:  D:2-, !Orc
# : place_unique(_G, "Linley")
#
# The WEIGHT line was skipped as 10 is the default.
# You have to deviate from this simple 3 liner only if
# * You want a more complicated map, e.g. with items or other monsters.
#   (Not needed for unique in bands: place_unique(_G, "Linley band") works.)
# * You want additional tags, for example because you want to make a number
#   of Linley vaults. In this case, you can still use the inline function;
#   just add a TAG line.
# * You want different WEIGHTS. In this case, just add a WEIGHT line.
#
# If you want to weight uniques differently for some vaults, the weights for
# these vaults should all add up to 10 (the default weight for uniques),
# unless you want to make that unique appear more or less frequent on purpose.
# You can use multiple vaults that are tagged "uniq_<name>", with different
# weights for each of the vaults. See uniq_ribbit for examples of all this.
#
# Note also that uniques are never placed on D:1, so specifying placement there
# will only cause confusion.
#
# You can define DEBUG_UNIQUE_PLACEMENT and get a per-level unique generation
# report in "unique_placement.log" in debug mode.
#
# NOTE: Does not deal with fixed-place uniques such as the Royal Jelly, the Hell
# bosses, and the Pan bosses.
################################################################################

{{
crawl_require('dlua/vault.lua')

function place_unique(e, monster)
   e.mons(monster)
   e.tags("place_unique")
   e.tags("transparent overwrite_floor_cell no_exits")
   e.map("1")
end
}}

################################################################################
# Dummy vaults, used to weight the number of uniques per branch.
################################################################################

NAME:   uniq_dummy
TAGS:   place_unique dummy
DEPTH:  1-50, !Lair, !Slime
WEIGHT: 20 (D:1-8), 50
MAP
.
ENDMAP

NAME:   uniq_dummy_lair
TAGS:   place_unique dummy
DEPTH:  Lair
WEIGHT: 80
MAP
.
ENDMAP

NAME:   uniq_dummy_slime
TAGS:   place_unique dummy
DEPTH:  Slime
WEIGHT: 200
MAP
.
ENDMAP

################################################################################
# Uniques which can appear in the Dungeon (D):
################################################################################

NAME:   uniq_amaemon
DEPTH:  D:8-11, Lair:1-3
WEIGHT: 5, 15(Lair)
: place_unique(_G, "Amaemon band")

NAME:   uniq_azrael
DEPTH:  D:12-, Orc:$, Elf, !Elf:$, Snake, !Snake:$, Spider, !Spider:$
: place_unique(_G, "Azrael band")

NAME:   uniq_blorkula_the_orcula
DEPTH:  D:5-8
: place_unique(_G, "Blorkula the orcula")

NAME:   uniq_cassandra
DEPTH:  D:9-14, Lair:1
: place_unique(_G, "Cassandra")

# Crazy Yuif's hut is bottom of this file.

NAME:   uniq_duvessa
DEPTH:  D:4-7
: place_unique(_G, "Duvessa band")

NAME:   uniq_edmund
DEPTH:  D:4-6
: place_unique(_G, "Edmund")

NAME:   uniq_erica
DEPTH:  D:8-11, Orc, !Orc:$, Lair:1-2
: place_unique(_G, "Erica")

NAME:   uniq_erolcha
DEPTH:  D:9-13, Orc
: place_unique(_G, "Erolcha")

NAME:   uniq_eustachio
DEPTH:  D:4-6
: place_unique(_G, "Eustachio")

NAME:   uniq_frances
DEPTH:  D:12-14, Elf:1, Swamp:1-2, Snake:1-2, Shoals:1-2, Spider:1-2
: place_unique(_G, "Frances")

NAME:   uniq_fannar
DEPTH:  D:10-12, Orc, !Orc:$, Lair:1-3
: place_unique(_G, "Fannar")

NAME:   uniq_gastronok
DEPTH:  D:8-12, Orc, !Orc:$, Lair:1-3
WEIGHT: 5, 15(Lair)
: place_unique(_G, "Gastronok")

NAME:   uniq_grum
DEPTH:  D:8-11, Lair:1
: place_unique(_G, "Grum band")

NAME:   uniq_grinder
DEPTH:  D:3-6
: place_unique(_G, "Grinder")

NAME:   uniq_harold
DEPTH:  D:9-11, Orc, !Orc:$, Lair:1-2
: place_unique(_G, "Harold")

NAME:   uniq_ijyb
DEPTH:  D:3-5
: place_unique(_G, "Ijyb")

NAME:   uniq_jessica
DEPTH:  D:2-3
: place_unique(_G, "Jessica")

NAME:   uniq_jorgrun
DEPTH:  D:12-, Orc, Elf, !Elf:$, Snake, !Snake:$, Shoals, !Shoals:$
DEPTH:  Spider, !Spider:$, Swamp, !Swamp:$
: place_unique(_G, "Jorgrun")

NAME:   uniq_joseph
DEPTH:  D:7-10, Lair:1
: place_unique(_G, "Joseph")

NAME:   uniq_josephine
DEPTH:  D:10-14, Orc, !Orc:$, Lair:2-
: place_unique(_G, "Josephine band")

NAME:   uniq_kirke
DEPTH:  D:12-, Lair:3-, Elf:1, Swamp:1, Snake:1, Shoals:1, Spider:1
: place_unique(_G, "Kirke band")

NAME:   uniq_lodul
DEPTH:  D:10-14
: place_unique(_G, "Lodul band")

NAME:   uniq_louise
DEPTH:  D:14-, Elf, Swamp, Snake, Shoals, Spider
: place_unique(_G, "Louise")

NAME:   uniq_maggie
DEPTH:  D:6-10, Lair:1-2
: place_unique(_G, "Maggie")

NAME:   uniq_jeremiah
DEPTH:  D:6-9, Lair:1
: place_unique(_G, "Jeremiah")

NAME:   uniq_maurice
DEPTH:  D:7-12, Orc
: place_unique(_G, "Maurice")

NAME:   uniq_menkaure
DEPTH:  D:4-7
: place_unique(_G, "Menkaure")

NAME:   uniq_natasha
DEPTH:  D:2-4
: place_unique(_G, "Natasha")

NAME:   uniq_nergalle
DEPTH:  D:10-12, Orc, !Orc:$, Lair:1-3
: place_unique(_G, "Nergalle")

NAME:   uniq_nessos
DEPTH:  D:12-, Orc:$, Lair:3-
: place_unique(_G, "Nessos")

NAME:   uniq_pikel
DEPTH:  D:4-9
: place_unique(_G, "Pikel band")

NAME:   uniq_prince_ribbit1
TAGS:   uniq_ribbit
DEPTH:  D:5-9
WEIGHT: 7
: place_unique(_G, "Prince Ribbit")

NAME:   uniq_prince_ribbit2
TAGS:   uniq_ribbit
DEPTH:  Lair:1-3
WEIGHT: 3
: place_unique(_G, "Prince Ribbit band")

NAME:   uniq_pargi
DEPTH:  D:3-4
WEIGHT: 1
: place_unique(_G, "Pargi")

NAME:   uniq_robin
DEPTH:  D:2-4
: place_unique(_G, "Robin band")

NAME:   uniq_roxanne
TAGS:   place_unique transparent
DEPTH:  D:14-, Elf, Swamp, Snake, Shoals, Spider
MONS:   Roxanne
MAP
...
.1.
...
ENDMAP

NAME:   uniq_rupert
DEPTH:  D:12-, Lair:3-, Orc:$, Snake:1, Spider:1
: place_unique(_G, "Rupert")

NAME:   uniq_sigmund
DEPTH:  D:2-6
: place_unique(_G, "Sigmund")

NAME:   uniq_snorg
DEPTH:  D:10-14, Lair:3-, Orc
: place_unique(_G, "Snorg")

NAME:   uniq_sonja
DEPTH:  D:10-13, Orc, Lair
: place_unique(_G, "Sonja")

NAME:   uniq_sprozz
DEPTH:  D:7-11, Lair:1
: place_unique(_G, "Sprozz")

NAME:   uniq_terence
DEPTH:  D:2-3
: place_unique(_G, "Terence")

NAME:   uniq_urug
DEPTH:  D:10-13, Orc, Lair
: place_unique(_G, "Urug")

NAME:   uniq_agnes
DEPTH:  D:14-, Elf, !Elf:$, Snake, Spider
: place_unique(_G, "Agnes")

################################################################################
# Uniques which can appear in the Depths:
################################################################################

NAME:   uniq_arachne
DEPTH:  Vaults:1-4, Elf, Depths:1
veto {{
  if crawl.game_started() and dgn.br_exists("Spider") then
    return true
  end
  return false
}}
: place_unique(_G, "Arachne band")

NAME:   uniq_asterion
DEPTH:  Depths:1-2, Elf, Snake, Spider, Vaults:1-3
: place_unique(_G, "Asterion")

NAME:   uniq_bai_suzhen
DEPTH:  Depths:1-2, Elf:$, Swamp:3-, Snake:3-, Shoals:3-, Spider:3-, Vaults:2-
: place_unique(_G, "Bai Suzhen")

# Initial placement of Boris: he may regenerate on later levels after
# being killed.
NAME:   uniq_boris
DEPTH:  Depths, Elf:$, Vaults, Crypt, Tomb
: place_unique(_G, "Boris")

NAME:   uniq_enchantress
DEPTH:  Depths
MONS:   Enchantress band
: place_unique(_G, "Enchantress band")

NAME:   uniq_frederick
DEPTH:  Depths:3-, Vaults:2-, Crypt
: place_unique(_G, "Frederick")

NAME:   uniq_jory
DEPTH:  Depths:3-, Vaults:2-, Crypt
: place_unique(_G, "Jory")

NAME:   uniq_josephina
# Higher weight to compensate for Josephine.
WEIGHT: 15
DEPTH:  Depths:2-, Zot:1-4, Crypt
: place_unique(_G, "Josephina band")

NAME:   uniq_margery
# Higher WEIGHT to compensate for Maggie. Used objstat to calculate doubling
# the WEIGHT would lead to numbers closest to Margery's pre-Maggie spawn rates
WEIGHT: 20
DEPTH:  Depths:3-, Vaults:2-, Crypt
: place_unique(_G, "Margery band")

NAME:   uniq_mara
DEPTH:  Depths, !Depths:$, Elf:$, Swamp:3-, Snake:3-, Shoals:3-, Spider:3-
DEPTH:  Vaults:2-
: place_unique(_G, "Mara")

NAME:   uniq_mennas
DEPTH:  Depths:3-, Vaults:2-, Crypt, Tomb
: place_unique(_G, "Mennas")

NAME:   uniq_mennas_pan
TAGS:   transparent extra allow_dup luniq_mennas
DEPTH:  Pan
CHANCE: 5%
veto {{
  return you.uniques("Mennas")
}}
MONS: generate_awake Mennas
MAP
1
ENDMAP

NAME:   uniq_nikola
DEPTH:  Depths:1-2, Elf, Swamp, Snake, Shoals, Spider, Vaults:1-3
: place_unique(_G, "Nikola")

NAME:   uniq_parghit
DEPTH:  Depths:3-, Zot:1-4
: place_unique(_G, "Parghit")

NAME:   uniq_norris
DEPTH:  Depths, !Depths:$, Elf, Vaults, !Vaults:$
: place_unique(_G, "Norris band")

NAME:   uniq_saint_roka
DEPTH:  Orc:$, Depths:1, Elf:2-, Snake:2-, Vaults
: place_unique(_G, "Saint Roka band")

NAME:   uniq_sojobo
DEPTH:  Depths, Vaults:2-, Crypt
: place_unique(_G, "Sojobo band")

NAME:   uniq_vv
DEPTH:  Depths:2-, Zot:1-4, Crypt
: place_unique(_G, "Vv")

NAME:   uniq_xtahua
DEPTH:  Depths:3-, Vaults:2-, Crypt, !Crypt:$
: place_unique(_G, "Xtahua")

NAME:   uniq_grunn
DEPTH:  Depths:2-, Zot:1-4, Crypt
: place_unique(_G, "Grunn band")

NAME:   uniq_nameless_revenant
DEPTH:  Depths, Vaults:2-, Crypt
: place_unique(_G, "Nobody")

################################################################################
# Uniques which appear in neither the Dungeon nor the Depths:
################################################################################

NAME:   uniq_aizul
DEPTH:  Elf, Swamp, Snake, Shoals, Spider, Vaults:1-2
WEIGHT: 50 (Snake), 10
: place_unique(_G, "Aizul")

NAME:   uniq_donald
DEPTH:  Swamp, Snake, Shoals, Spider, Slime, Vaults, !Vaults:$
DEPTH:  Crypt, !Crypt:$, Elf, Orc:$
: place_unique(_G, "Donald")

NAME:   uniq_mlioglotl
DEPTH:  Swamp, Snake, Shoals, Spider
: place_unique(_G, "Mlioglotl")

NAME:   uniq_wiglaf
DEPTH:  Elf, Snake, Spider, Vaults:1-3
: place_unique(_G, "Wiglaf")

NAME:   uniq_vashnia
DEPTH:  Snake:2-
WEIGHT: 50
: place_unique(_G, "Vashnia band")

NAME:   uniq_polyphemus
DEPTH:  Shoals:2-
WEIGHT: 50
: place_unique(_G, "Polyphemus band")

NAME:   uniq_ilsuiw
# Her placement on Shoals:$ is handled through the shoal_guardian tagged
# vaults.
DEPTH:  Shoals:2-, !Shoals:$
WEIGHT: 50
: place_unique(_G, "Ilsuiw band")

NAME:   uniq_xakkrixis
DEPTH:  Spider:2-
WEIGHT: 40
: place_unique(_G, "Xak'krixis")

NAME:   uniq_dissolution
DEPTH:  Slime:2-
WEIGHT: 100
: place_unique(_G, "Dissolution")

NAME:   uniq_khufu
DEPTH:  Tomb, Crypt
: place_unique(_G, "Khufu band")

NAME:   uniq_tiamat
DEPTH:  Zot
: place_unique(_G, "Tiamat band")

NAME:   uniq_zenata
DEPTH:  Vaults:1-4, Elf, Crypt
: place_unique(_G, "Zenata")

NAME:   uniq_cerebov
TAGS:   transparent extra allow_dup luniq_cerebov
DEPTH:  Pan
CHANCE: 25%
veto {{
  if you.uniques("Cerebov") or not you.have_rune("fiery") then
    return true
  end
  return false
}}
MONS: generate_awake Cerebov band
MAP
1
ENDMAP

NAME:   uniq_gloorx_vloq
TAGS:   transparent extra allow_dup luniq_gloorx_vloq
DEPTH:  Pan
CHANCE: 25%
veto {{
  if you.uniques("Gloorx Vloq") or not you.have_rune("dark") then
    return true
  end
  return false
}}
MONS: generate_awake Gloorx Vloq band
MAP
1
ENDMAP

NAME:   uniq_mnoleg
TAGS:   transparent extra allow_dup luniq_mnoleg
DEPTH:  Pan
CHANCE: 25%
veto {{
  if you.uniques("Mnoleg") or not you.have_rune("glowing") then
    return true
  end
  return false
}}
MONS: generate_awake Mnoleg band
MAP
1
ENDMAP

NAME:   uniq_lom_lobon
TAGS:   transparent extra allow_dup luniq_lom_lobon
DEPTH:  Pan
CHANCE: 25%
veto {{
  if you.uniques("Lom Lobon") or not you.have_rune("magical") then
    return true
  end
  return false
}}
MONS: generate_awake Lom Lobon band
MAP
1
ENDMAP

NAME:   uniq_ignacio
TAGS:   transparent extra allow_dup luniq_ignacio
DEPTH:  Pan
CHANCE: 10%
# TODO: use regular unique code instead?
veto {{
  if you.uniques("Ignacio") then
    return true -- don't spam the list of vaults
  end
  if not dgn.persist.ignacio_spawned then
    dgn.persist.ignacio_spawned = true
    dgn.persist.ignacio_forbid = crawl.coinflip()
  end
  if dgn.persist.ignacio_forbid then
    return true
  end
  return false
}}
MONS: Ignacio
MAP
1
ENDMAP

###############################################################################
# Crazy Yiuf! Only in his cottage.
NAME:    uniq_crazy_yiuf_cottage
TAGS:    place_unique no_monster_gen no_item_gen
DEPTH:   D:2-7
MONS:    Crazy Yiuf
MONS:    fungus / bush w:1
ITEM:    mace tile:wpn_hammer wtile:hammer itemname:hammer
KFEAT:   e = cache_of_fruit
# Randomisation 1: Some chance for a gate.
SHUFFLE: Bb / Aa
SUBST:   Bb = ;
: if crawl.one_chance_in(3) then
SUBST:   A : AAA+, A:x
: else
SUBST:   A : ;;;x, a:;
: end
# Randomisation 2: Plants might be in the way -- Yiuf seems to be a bad
#                  gardener. Sometimes.
SUBST:   P : PQQ;;;; , Q = 2;
NSUBST:  P = 1:t / * : 2;
# Randomisation 3: Hammers. Hammers. Hammers.
SUBST:   ; : .:100 ;:10 d:2
SUBST:   ; = .:10 d:2
: if crawl.one_chance_in(300) then
SUBST:   t = "
: end
SUBST:   e = ef'', ':.......' , "=' , ':d' , '=..d
# Randomisation 4: trees or rock
SUBST:   t : ttx
: decorative_floor(_G, 'f', "garden patch")
MAP
 xxxxxxxxxxxxxxxx
 xxtttttttxxtttxx
 xxtttttttttttttx
 BAP't'tttccccctx
;baPP't''tc''ectx
@baPPtttt'=''1ctx
;BAPttttttc''dctx
 xxtttttttccccctx
 xxtttttttttttttx
 xxxxxttttttttxxx
 xxxxxxxxxxxxxxxx
ENDMAP
