###############################################################################
# shops.des: The file for minivaults centered around a single shops. The
#            generic vaults, with the 'shop' tag, can be placed by themselves
#            or in sets of multiple shops throughout valid levels. The themed
#            vaults are excluded from the latter, but are collected here for
#            ease of reference.
#
# <<1>>      Generic
# <<2>>      Themed
# <<3>>      Multi
#
###############################################################################

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

MAX_RANDOM_SHOPS = 5

-- If a level gets shops, how many there are.
-- Just one most of the time; expected value is 1.42.
function num_shops()
    if crawl.x_chance_in_y(5, 6) then
        return 1
    else
        return crawl.random_range(2, MAX_RANDOM_SHOPS)
    end
end

function ks_shop_vault(e, glyphs)
  if e.is_validating() then
    e.subst('O = B')
    return
  end

  local is_shop = false
  local is_altar = false

  local params = dgn.map_parameters()
  if params ~= nil then
    local tag = unpack(params)
    if tag ~= nil then
      if tag == "shop" then
        is_shop = true
      elseif string.find(tag, "temple_overflow_generic_") ~= nil then
        is_altar = true
      end
    end
  end

  if is_shop then
    e.kfeat('O = any shop')
  elseif is_altar then
    e.subst('O = B')
  else
    e.tags('extra decor')
    e.subst('O = ' .. glyphs)
  end
end
}}

# XXX: Don't change the name of this vault!
# Gozag code uses it to find out where shops can normally place.
NAME: serial_shops
TAGS: allow_dup extra luniq
DEPTH: D, Depths, Orc, Elf, Shoals, Snake, Vaults
CHANCE: 15% (D)
CHANCE: 20% (Depths)
CHANCE: 30% (Orc)
CHANCE: 40% (Elf, Vaults)
CHANCE: 20% (Shoals, Snake)
{{
hook("post_place", function()
    local num = num_shops()

    if you.absdepth() > 10 and you.absdepth() <= 27
      and crawl.one_chance_in(30 - (you.absdepth() - 1))
    then
        dgn.place_maps { tag = "bzr_entry", count = 1 }
        num = num - 1
    end

    dgn.place_maps { tag = "shop", count = num }
end)
}}
MAP
ENDMAP

###############################################################################
# <<1>> Generic.
#       Tagged shop, may only contain a single shop. No threats.
#

NAME:   shop
TAGS:   allow_dup extra shop transparent
WEIGHT: 270
KFEAT:  O = any shop
MAP
O
ENDMAP

NAME:   shop_fountains
TAGS:   allow_dup extra shop transparent
KFEAT:  O = any shop
MAP
T.T
.O.
T.T
ENDMAP

NAME:   shop_statue
TAGS:   allow_dup extra shop no_descent
KFEAT:  O = any shop
MAP
@G.O.<.G@
ENDMAP

NAME:   shop_coins
TAGS:   allow_dup extra shop transparent
WEIGHT: 3
KFEAT:  O = any shop
MAP
$$$
$O$
$$$
ENDMAP

NAME:   shop_scrolls
TAGS:   allow_dup extra shop transparent
WEIGHT: 1
KFEAT:  O = scroll shop
ITEM:   nothing w:30 / scroll of noise w:10
MAP
ddd
dOd
ddd
ENDMAP

NAME: nicolae_shop_behind_doors
TAGS: allow_dup extra shop transparent
KFEAT: O = any shop
MAP
x+x
+O+
x+x
ENDMAP

NAME: nicolae_shop_crystal
TAGS: allow_dup extra shop transparent
KFEAT: O = any shop
MAP
b.b
.O.
b.b
ENDMAP

NAME: nicolae_shop_statue_plus
TAGS: allow_dup extra shop no_descent
KFEAT: O = any shop
MAP
   @
   G
   <
@G.O.G@
   .
   G
   @
ENDMAP

NAME: nicolae_shop_stone
TAGS: allow_dup extra shop transparent
KFEAT: O = any shop
MAP
  c
 ...
c.O.c
 ...
  c
ENDMAP

NAME: nicolae_shop_trees
TAGS: allow_dup extra shop transparent
KFEAT: O = any shop
MAP
  t
t.O.t
  t
ENDMAP

NAME: nicolae_shop_waterfront
TAGS: allow_dup extra shop no_pool_fixup
KFEAT: O = any shop
SUBST: v = wW
MAP
 www
wwvvW
wwO.@
wwvvW
 www
ENDMAP

NAME: nicolae_shop_overgrown_old_shop
TAGS: allow_dup extra shop transparent
WEIGHT: 5
KFEAT: O = antiques shop / antique weapon shop w:5 / antique armour shop w:5
NSUBST: 1 = . / 1
MONS: plant / nothing w:3
MAP
.....
.111.
.1O1.
.111.
.....
ENDMAP

# A shop owner has copied a temple entry for their shop. Is nothing sacred?
# (minmay_temple_entry_statues_fountains)
NAME: nicolae_shop_temple_entry_statues_fountains
TAGS: allow_dup extra shop transparent
WEIGHT: 5
SUBST: T = TV
KFEAT: O = any shop
MAP
G.G.G
.T.T.
G.O.G
.T.T.
G.G.G
ENDMAP

NAME: nicolae_shop_window_shopping
TAGS: allow_dup extra shop transparent
KFEAT: O = any shop
MAP
xxm.
+Om@
xxm.
ENDMAP

NAME: nicolae_shop_competitors_out_of_business
TAGS: allow_dup extra shop transparent
WEIGHT: 3
KFEAT: O = any shop
KFEAT: A = abandoned_shop
MAP
O.A
...
A.A
ENDMAP

####
# These three vaults were originally plain minivaults.
# They can still place as plain minivaults, in which case they have no
# shops.
NAME:  kennysheep_mini
TAGS:  shop temple_overflow_generic_1
DEPTH: D:4-, Depths, !D:$, !Depths:$
: ks_random_setup(_G)
: ks_shop_vault(_G, '{}CC')
MAP
cDc
FOF
c+c
ENDMAP

NAME:  kennysheep_mini_moat
TAGS:  shop temple_overflow_generic_1
DEPTH: D:4-, Depths, !D:$, !Depths:$
: ks_random_setup(_G)
SUBST: . : @
: ks_shop_vault(_G, '{}CC')
MAP
wwEww
wcDcw
HFOFH
wc+cw
ww@ww
ENDMAP

NAME:  kennysheep_little_box
TAGS:  shop temple_overflow_generic_1
DEPTH: D:4-, Depths, !D:$, !Depths:$
: ks_random_setup(_G)
: ks_shop_vault(_G, '{}C....')
MAP
cccDccc
cwwEwwc
cwt.twc
FH.O.HF
cwt.twc
cww.wwc
ccc+ccc
ENDMAP

NAME:  nicolae_diamond_shop
TAGS:  allow_dup extra shop transparent no_pool_fixup
KFEAT: O = any shop
SUBST: x : xcvbtGwl
MAP
...x...
..x.x..
.x...x.
x..O..x
.x...x.
..x.x..
...x...
ENDMAP

NAME:  nicolae_lakefront_shop
TAGS:  allow_dup extra shop transparent no_pool_fixup
KFEAT: O = any shop
SUBST: G : GTUtwx, w : wl
MAP
xxxxxxxx
x.....Gx
..www..x
.wwwww.x
@wwwwwOx
.wwwww.x
..www..x
x.....Gx
xxxxxxxx
ENDMAP

NAME:  nicolae_square_shop
TAGS:  allow_dup extra shop transparent
KFEAT: O = any shop
SUBST: c : cvbn
MAP
   ..cc
 cc..cc
 cc....
...O...
....cc
cc..cc
cc..
ENDMAP

NAME:    nicolae_inconvenience_store
TAGS:    extra shop transparent no_pool_fixup
DEPTH:   D:4-, Depths
WEIGHT:  5
KFEAT:   a = iron_grate
KFEAT:   O = any shop
SHUFFLE: xm/cn/va/ll/ww
MAP
.............
.xxxxxmxxxxx.
.x...........
.x.xxxmxxxxx.
.x.x.......x.
.x.x.xmxxx.x.
.x.x.x...x.x.
.m.m.mOm.m.m.
.x.x.xmx.x.x.
.x.x.....x.x.
.x.xxxmxxx.x.
.x.........x.
.xxxxxmxxxxx.
.............
ENDMAP

NAME:    nicolae_stop_n_shop_1
TAGS:    allow_dup extra shop transparent
DEPTH:   D:4-, !D:$, Depths:2-, !Depths:$, Shoals:2-, !Shoals:$, Snake:2-, \
         !Snake:$, Elf:2-, !Elf:$
KFEAT:   O = any shop
SHUFFLE: {}/[]/()
SUBST:   D : G., E : G., F : G.
MAP
D...E
.....
..}...F
.......
E...O...E
  .......
  F...{..
    .....
    E...D
ENDMAP

NAME:    nicolae_stop_n_shop_2
TAGS:    allow_dup extra shop transparent
DEPTH:   D:4-, !D:$, Depths:2-, !Depths:$, Shoals:2-, !Shoals:$, Snake:2-, \
         !Snake:$, Elf:2-, !Elf:$
KFEAT:   O = any shop
SHUFFLE: {}/[]/()
SUBST:   D : G_, E : G_, F : G_
CLEAR:   _
MAP
  E F E
 .......
D.}.O.{.D
 .......
  E F E
ENDMAP

NAME:  nicolae_take_the_stairs
TAGS:  shop extra no_descent
DEPTH: D:4-, !D:$, Depths, !Depths:$, Shoals, !Shoals:$, Snake, !Snake:$, \
       Elf, !Elf:$
KFEAT: O = any shop
SUBST: } = }])
MAP
 .......
.ccccccc.
.n.....n.
@n.O.}.n@
.n.....n.
.ccccccc.
 .......
ENDMAP

NAME:     nicolae_shop_advertising_works
TAGS:     extra shop transparent
# Exploiting subvault placement behavior to get the shop a varying distance
# from the arrow.
SUBVAULT: - : nico_adshop
CLEAR:    -
MAP
.........             -------------------------------
.....b...             -------------------------------
......b..             -------------------------------
.bbbbbbb.             -------------------------------
......b..             -------------------------------
.....b...             -------------------------------
.........             -------------------------------
ENDMAP

NAME:  nicolae_subvault_shop_adworks
TAGS:  unrand transparent allow_dup nico_adshop
KFEAT: O = any shop
MAP
.......
.b...b.
..b.b..
...O...
..b.b..
.b...b.
.......
ENDMAP

NAME:    nicolae_shop_hallway_plus
TAGS:    allow_dup extra shop transparent no_pool_fixup
KFEAT:   O = any shop
SHUFFLE: Pp/Pp/Rr, Qq/Qq/Ss
SUBST:   P : xxxw, p : _, R : mmmw, r : ...xmwGT, \
         Q : xxxw, q : _, S : mmmw, s : ...xmwGT
KPROP:   Gw = no_tele_into
CLEAR:   _
MAP
  x+x
 pP.Qq
xPP.QQx
+..O..+
xQQ.PPx
 qQ.Pp
  x+x
ENDMAP

NAME:    nicolae_shop_hallway_stairs
TAGS:    allow_dup extra shop transparent no_pool_fixup
KFEAT:   O = any shop
: if you.depth() == 1 then
SUBST:   S = )}]
: elseif you.depth_fraction() < 1 then
SUBST:   S = (){}[]
: else
SUBST:   S = ({[
: end
SHUFFLE: Pp/Qq, Rr/Ss
SUBST:   P : xw_, p = _, Q : mw+, q = ., R : xw_, r = _, S : mw+, s = .
CLEAR:   _
MAP
    pp
xxxxPPxxxx
+..O..S..+
xxxxRRxxxx
    rr
ENDMAP

# Q: Why is there a dead body outside your shop with blood everywhere?
# A: Don't worry about it. Are you going to buy something or not?
NAME:   nicolae_shop_bloodbath_and_beyond
TAGS:   extra shop transparent
KITEM:  D = mundane dagger / mundane club / mundane hand axe / mundane spear
KFEAT:  O = weapon shop
KFEAT:  E = x
NSUBST: - = D / Z / -
SUBST:  . = `.., - = `., ! = ``., x = Exx
KPROP:  `DOEZ = bloody
: dgn.delayed_decay(_G, "Z", "human corpse" )
MAP
xx...xx
x-----x
.-!!!-.
.-!O!-.
.-!!!-.
x-----x
xx...xx
ENDMAP

NAME:    nicolae_book_shop_shelving
TAGS:    transparent shop extra allow_dup
WEIGHT:  5
KFEAT:   S = book shop
SHUFFLE: DE
SUBST:   D = c, E = .
TILE:    c = wall_studio
# Console players won't get to enjoy the bookshelf tiles. As consolation,
# I'm reusing the color scheme from nicolae_shop_i_like_big_books.
COLOUR: c : blue / red / magenta / lightgreen / lightred / lightmagenta / yellow
MAP
EDcDE
D.E.D
cESEc
D.E.D
EDcDE
ENDMAP

NAME:  nicolae_shop_back_alley_shop
TAGS:  transparent extra shop allow_dup
KFEAT: S = any shop
KFEAT: - = iron_grate
MAP
xxxxxxx
@.....@
xx.xxxx
xx.xS.x
xx.x-.x
xx....x
xxxxxxx
ENDMAP

NAME:   nicolae_shop_dealshenge
TAGS:   transparent extra shop allow_dup
WEIGHT: 3
KFEAT:  S = antiques shop / antique weapon shop / antique armour shop
MAP
.A.
ASA
.A.
ENDMAP

NAME:   nicolae_shop_drivethru
TAGS:   extra shop
WEIGHT: 5
KFEAT:  S = any shop
MARKER: D = lua:transp_loc("nico_drivethru_in")
MARKER: E = lua:transp_dest_loc("nico_drivethru_in")
MARKER: F = lua:transp_loc("nico_drivethru_out")
MARKER: H = lua:transp_dest_loc("nico_drivethru_out")
MAP
xxxxxxxxxxxxx
xxxcccccccxxx
...n.....n...
@.DnE.S.FnH.@
...n.....n...
xxxcccccccxxx
xxxxxxxxxxxxx
ENDMAP

NAME:    nicolae_shop_gaudy_bauble
TAGS:    transparent extra shop allow_dup
WEIGHT:  5
KFEAT:   S = jewellery shop
: if crawl.coinflip() then
SHUFFLE: DF
SUBST:   FH = .
SHUFFLE: DEJ
SUBST:   D : v, E : b, J : bv
: else
SHUFFLE: EF
SUBST:   FJ = .
SHUFFLE: DEH
SUBST:   D : v, E : b, H : bv
: end
SHUFFLE: bv
MAP
.......
.DEFED.
.EHJHE.
.FJSJF.
.EHJHE.
.DEFED.
.......
ENDMAP

NAME:    nicolae_shop_getting_attention
TAGS:    transparent extra shop allow_dup
WEIGHT:  3
KFEAT:   S = any shop
SHUFFLE: pqrs
MARKER:  p = lua:fog_machine { cloud_type = "black smoke", \
                pow_min = 5, pow_max = 5, delay_min = 50, delay_max = 80, \
                size = 1, walk_dist = 1, spread_rate = 10 }
MARKER:  q = lua:fog_machine { cloud_type = "grey smoke", \
                pow_min = 5, pow_max = 5, delay_min = 50, delay_max = 80, \
                size = 1, walk_dist = 1, spread_rate = 10 }
MARKER:  r = lua:fog_machine { cloud_type = "blue smoke", \
                pow_min = 5, pow_max = 5, delay_min = 50, delay_max = 80, \
                size = 1, walk_dist = 1, spread_rate = 10 }
MARKER:  s = lua:fog_machine { cloud_type = "purple smoke", \
                pow_min = 5, pow_max = 5, delay_min = 50, delay_max = 80, \
                size = 1, walk_dist = 1, spread_rate = 10 }
MAP
.....
.p.q.
..S..
.s.r.
.....
ENDMAP

# Q: Why are there strange fluids leaking from your potions shop?
# A: Don't worry about it. Are you going to buy something or not?
NAME:   nicolae_shop_industrial_runoff
TAGS:   transparent shop extra allow_dup no_pool_fixup
WEIGHT: 5
KFEAT:  S = distillery shop
NSUBST: W = W / w / Ww
COLOUR: W = lightgreen / cyan w:5
COLOUR: w = green / blue w:5
MAP
.....
.WWW.
.WSW.
.WWW.
.....
ENDMAP

NAME:  nicolae_shop_just_a_little_nook
TAGS:  transparent extra shop allow_dup
KFEAT: S = any shop
MAP
xxxxx
xcccx
xcScx
@...@
ENDMAP

NAME:    nicolae_shop_mannequins
TAGS:    extra shop transparent
WEIGHT:  5
KMONS:   p = dancing weapon ; rapier | triple sword | executioner's axe | \
               great mace | bardiche | lajatang | triple crossbow | \
               demon blade | demon trident | demon whip | quick blade | \
               giant club | giant spiked club
KMONS:   q = animated armour ; plate armour | crystal plate armour | \
               pearl dragon scales | shadow dragon scales | \
               storm dragon scales | gold dragon scales
KMONS:   r = walking crystal tome / walking divine tome / \
             walking earthen tome / walking frostbound tome
KFEAT:   P = weapon shop
KFEAT:   Q = armour shop
KFEAT:   R = book shop
KMASK:   pqr` = opaque
KMASK:   pqr` = no_trap_gen
KMASK:   pqr` = no_item_gen
KMASK:   pqr` = no_monster_gen
KPROP:   pqr` = no_tele_into
SHUFFLE: Pp/Qq/Rr
MAP
.........
.nnn.nnn.
.n`n.n`n.
.npnPnpn.
.n`n.n`n.
.nnn.nnn.
.........
ENDMAP

# Trying out new ways to generate a variable-size vault. This particular
# approach is deeply cursed and I can't encourage anyone else to try it.
# ...but it does work.
NAME:  nicolae_shop_peninsula
TAGS:  no_pool_fixup shop extra allow_dup
KFEAT: S = any shop
{{
local i = crawl.random2(6) + 2
for j = 1, i, 1 do
   map("w@w")
end
map("wSw")
map("www")
subst("w : wwwwttl")
if you.in_branch("Orc") or you.in_branch("Snake") then
    subst("t = l")
end
}}

NAME:  nicolae_shop_pleasant_corner_grove
TAGS:  transparent shop extra allow_dup
KFEAT: S = any shop
KFEAT: D = demonic_tree
SUBST: t : t:35 D:1
MAP
xxxx
xS.t
x...
xt.@
ENDMAP

NAME:   nicolae_shop_real_fake_doors
TAGS:   transparent extra shop
KFEAT:  S = any shop
SUBST:  G : GTt m:5 U:5
:lua_marker('+', props_marker { connected_exclude="true" })
MAP
 .......
...x+x...
..Gx+xG..
.xxx+xxx.
.+++S+++.
.xxx+xxx.
..Gx+xG..
...x+x...
 .......
ENDMAP

NAME:   nicolae_shop_rolled_up
TAGS:   transparent extra shop allow_dup
WEIGHT: 5
KFEAT:  S = scroll shop
MAP
.........
.c.ccccc.
.c.c...c.
.c.c.c.c.
.c.cSc.c.
.c.ccc.c.
.c.....c.
.ccccccc.
.........
ENDMAP

NAME:    nicolae_shop_rolling_square
TAGS:    transparent extra shop allow_dup
KFEAT:   S = any shop
SHUFFLE: DEF, HJ
SUBST:   D = +, EF = c, c : cbv, H = ., J : T., T = TTTTV
MAP
    cDc
  cEc.F
cFc...cc
D..HJH.E
cc.JSJ.cc
 E.HJH..D
 cc...cFc
  F.cEc
  cDc
ENDMAP

NAME:   nicolae_shop_scrapyard
TAGS:   transparent extra shop allow_dup
WEIGHT: 2
: if crawl.coinflip() then
KITEM:  s = dagger damaged ego:none / falchion damaged ego:none / \
            hand axe damaged ego:none / club damaged ego:none / \
            spear damaged ego:none / sling damaged ego:none
KFEAT:  S = weapon shop / antique weapon shop w:5
: else
KITEM:  s = robe damaged ego:none / leather armour damaged ego:none / \
            ring mail damaged ego:none / buckler damaged ego:none / \
            helmet damaged ego:none w:2 / hat damaged ego:none w:2 / \
            pair of boots damaged ego:none w:2 / cloak damaged ego:none w:2 / \
            pair of gloves damaged ego:none w:2
KFEAT:  S = armour shop / antique armour shop w:5
: end
MAP
.....
.s.s.
..S..
.s.s.
.....
ENDMAP

NAME:   nicolae_shop_tiny_glass
TAGS:   transparent extra shop allow_dup
KFEAT:  S = any shop
KFEAT:  + = closed_clear_door
NSUBST: m = + / m
MAP
mmm
mSm
mmm
ENDMAP

NAME:  nicolae_shop_tiny_real_fake_doors
TAGS:  transparent extra shop allow_dup
KFEAT: S = any shop
: lua_marker('+', props_marker { connected_exclude="true" })
MAP
+++
+S+
+++
ENDMAP

NAME:  nicolae_shop_tiny_statue_garden
TAGS:  transparent allow_dup extra shop
KFEAT: S = any shop
# 5% chance of an enterprising orc leaving the mines to start a business out
# in the rest of the Dungeon.
SUBST: G : G:19 I:1
MAP
G.G
.S.
G.G
ENDMAP

NAME:   nicolae_shop_tiny_waterfront
TAGS:   allow_dup no_pool_fixup transparent extra shop
KFEAT:  S = any shop
NSUBST: w = @ / w
MAP
www
wSw
www
ENDMAP

NAME:   nicolae_shop_wares_on_display
TAGS:   transparent shop extra allow_dup
DEPTH:  !D:1-3
WEIGHT: 2
KFEAT:  S = general shop
MAP
xxxxxxxxx
x%%+S+%%x
mmmm.mmmm
.........
@.......@
ENDMAP

# This merchant does not tolerate thieves. Fortunately, since players can't
# steal from shops, you probably have nothing to worry about.
NAME:   nicolae_shop_gibbet_a_chance
TAGS:   shop extra transparent
WEIGHT: 5
KFEAT:  S = any shop
KFEAT:  - = iron_grate
KPROP:  DEFH = no_tele_into
KMASK:  DEFH = no_monster_gen
KMASK:  DEFH = no_item_gen
KMASK:  DEFH = no_trap_gen
KMASK:  DEFH = opaque
{{
-- The skellingtons are purely decorative, but also the only decorations, and
-- unlike other kinds of vaults, it's likely that the player will come back to a
-- shop after a long time on other levels. So, set them to be fully never_decay
-- rather than using a delayed_decay trigger. That way, players don't come back
-- to empty gibbets once they've gone and rounded up some cash.
local skeletons = {"human", "elf", "orc", "ogre", "merfolk", "naga", "kobold",
                   "gnoll", "minotaur", "spriggan", "troll", "felid",
                   "draconian", "tengu", "demonspawn", "demigod"}
kitem("D = never_decay " .. util.random_from(skeletons) .. " skeleton" )
kitem("E = never_decay " .. util.random_from(skeletons) .. " skeleton" )
kitem("F = never_decay " .. util.random_from(skeletons) .. " skeleton" )
kitem("H = never_decay " .. util.random_from(skeletons) .. " skeleton" )
}}
MAP
   .---
   .-E-
---.---
-D-......
---.S.---
......-F-
  ---.---
  -H-.
  ---.
ENDMAP

###############################################################################
# <<2>> Themed.
#       Not tagged shop, but still contains one. Can have threats, and can have
#       have a specific custom item list. Even if the below examples don't show
#       it, try to have some restraint with additions here.
#

#####################################################
# Custom venom shop
NAME:    guppyfry_shop_venom
TAGS:    no_monster_gen transparent
DEPTH:   D:4-, Depths
MONS:    ball python w:5 / adder / water moccasin, place:Snake:1
KFEAT:   v = general shop type:Serpentskin suffix:Sales count:7 ; \
         w:8 dart ego:poisoned | w:4 dart ego:curare | w:5 scroll of poison | \
         w:3 ring of poison resistance | w:6 randbook disc:alchemy | \
         w:2 staff of alchemy | w:4 any weapon ego:venom | w:1 serpent talisman | \
         w:4 any armour ego:poison_resistance | w:1 swamp dragon scales
SUBST:   ? = 2..
: if you.absdepth() < 13 then
SUBST:   2 = 1
: end
MAP
xxxxx
x???x
+?v?+
x???x
xxxxx
ENDMAP

#####################################################
# Custom earth shop
NAME:    guppyfry_shop_earth
TAGS:    no_monster_gen transparent
DEPTH:   D:11-, Depths
KMONS:   1 = gargoyle / basilisk / boulder beetle / cyclops w:3
KMONS:   2 = stone giant / catoblepas / deep troll earth mage / \
             iron dragon w:4
ITEM:    stone
KFEAT:   S = general shop type:Pet suffix:Rocks count:7 ; \
             stone w:15 | large rock w:15 | sling w:8  | \
             tin of tremorstones w:7 | wand of digging w:8 | \
             staff of earth w:4 | granite talisman w:4 | \
             randbook disc:earth w:5 | book of the earth w:2 | \
             book of geomancy w:2 | book of iron w:2 | book of the moon w:2 | \
             book of blasting w:2 | crystal plate armour w:1
SUBST:   ? = 2d.
: if you.absdepth() < 16 then
SUBST:   2 = 1
: end
MAP
.......
.xx+xx.
.x???x.
.m?S?m.
.x???x.
.xx+xx.
.......
ENDMAP

#####################################################
# Custom blood shop
NAME:    guppyfry_shop_blood
TAGS:    no_monster_gen transparent
DEPTH:   D:12-, Depths
KMONS:   1 = vampire / bat
KMONS:   2 = vampire / vampire mage / vampire knight
KFEAT:   v = general shop type:Blood suffix:Bar count:7 ; \
             nothing w:70 | any weapon ego:vampirism w:10 | \
             randbook disc:necromancy w:9 | w:1 book of annihilations
SUBST:   ? = 2.Y
: if you.in_branch("D") then
SUBST:   2 = 1
: end
MAP
xxxxx
x???x
+?v?+
x???x
xxxxx
ENDMAP

#####################################################
# Sells only evil items.
NAME:   nicolae_evil_shop
TAGS:   transparent
WEIGHT: 2
DEPTH:  D:6-, Depths
SUBST:  G : YlG
# I couldn't decide on just one alliterative name.
: local shopname = util.random_from({"type:Blasphemy suffix:Boutique",
:   "type:Evil suffix:Emporium", "type:Profane suffix:Products",
:   "type:Sacrilege suffix:Store", "type:Wicked suffix:Wares"})
: kfeat("s = general shop " .. shopname .. " ; \
:   any weapon ego:draining w:15 | any weapon ego:pain | \
:   any weapon ego:vampirism | any weapon ego:chaos w:1 | demon blade w:5 | \
:   demon trident w:5 | demon whip w:5 | scroll of torment | staff of death | \
:   book of necromancy | book of death | book of unlife | \
:   book of decay | \
:   randbook disc:necromancy w:5 | necronomicon w:1 | grand grimoire w:1 | \
:   sceptre_of_torment w:1 | scythe_of_curses w:1 | majin-bo w:1 | \
:   black_knights_barding w:1 | obsidian_axe w:1 | damnation w:1 | \
:   sword_of_zonguldrok w:1")
: if not you.in_branch("D") then
KFEAT: a = altar_kikubaaqudgha / altar_yredelemnul / altar_makhleb / \
           altar_beogh w:1 / altar_lugonu w:1
: end
MAP
...   ...
.G.a.s.G.
...   ...
ENDMAP

#####################################################
# Items related to the good gods thematically; healing, silver, holy wrath,
# etc.
NAME: nicolae_good_shop
WEIGHT: 2
DEPTH: D:6-, Depths
TAGS: no_monster_gen no_trap_gen transparent
SHUFFLE: _s
KFEAT: s = general shop type:Hallowed suffix:Reliquary ; \
   potion of heal wounds | potion of curing | \
   javelin ego:silver w:2 | \
   any weapon ego:holy_wrath | any armour ego:positive_energy w:5 |\
   amulet of faith w:2 | ring of positive energy w:5
: if not you.in_branch("D") then
KFEAT: _ = altar_the_shining_one / altar_zin / altar_elyvilon
: end
KPROP: 1 = no_tele_into
KMASK: 1 = opaque
MONS: angel
MAP
nnn
n1n
nnn
._.
...
.s.
ENDMAP

#####################################################
# All bardings, all the time.
NAME: nicolae_barding_shop
DEPTH: D:8-, Depths, Snake, !Snake:$
WEIGHT: 1
TAGS: transparent
: if you.in_branch("Snake") then
KMONS: s = naga w:50 / naga warrior
: else
KMONS: s = centaur w:50 / centaur warrior
: end
KFEAT: s = armour shop type:Specialty suffix:Armours count:3 use_all ; \
   barding | barding | barding good_item
MAP
.......
..xxx..
.x...x.
.x.s.x.
.x...x.
..xxx..
.......
ENDMAP

#####################################################
# Sells conjurations-heavy books, destructive wands, etc.
NAME: nicolae_blasting_shop
DEPTH: D:8-, Depths
TAGS: no_monster_gen no_item_gen transparent extra
MARKER: s = lua:fog_machine { cloud_type = "flame", \
             pow_min = 3, pow_max = 5, delay_min = 50, delay_max = 90, \
             start_clouds = 1, size = 3, walk_dist = 0, spread_rate= 0 }
KFEAT: s = general shop type:Demolitions suffix:Depot ; \
   book of conjurations | book of power | book of annihilations | \
   book of blasting |\
   randbook disc:conjuration | book of storms | book of lightning | \
   any blast wand | wand of flame | wand of mindburst | \
   condenser vane | staff of conjuration | any beam wand | \
   lightning rod | phial of floods | scroll of immolation | \
   book of flames | book of fire | book of air | manual of conjurations | \
   manual of evocations
FTILE: ' = floor_rough_red
COLOUR: ' = red
MAP
  ...
 ..x..
..'''..
.x's'x.
..'''..
 ..x..
  ...
ENDMAP

#####################################################
# Contains only four items: two evocable items/wands, a staff, and a randbook,
# associated with one of each of the four elemental schools. Falls back to
# generating additional books if the evocable in question is excluded due to
# item sets.
NAME: nicolae_elemental_shop
TAGS: no_monster_gen no_item_gen no_pool_fixup transparent extra
DEPTH: D:4-, Depths
SHUFFLE: AB
NSUBST: A = a / l / w / x
SUBST: B = .
KPROP: l = no_cloud_gen
MARKER: a = lua:fog_machine { cloud_type = "thin mist", \
            pow_min = 100, pow_max = 100, delay = 1, \
            size = 1, walk_dist = 0, start_clouds = 1 }
{{
  local evocables = {"wand of flame","wand of iceblast",
                     "lightning rod","tin of tremorstones"}
  if items.excluded_from_set("wand of iceblast") then
    evocables[2] = "randbook disc:ice"
  end
  if items.excluded_from_set("tin of tremorstones") then
    evocables[4] = "randbook disc:earth"
  end
  local staffs    = {"staff of fire","staff of cold",
                     "staff of air","staff of earth"}
  local randbooks = {"randbook disc:fire","randbook disc:ice",
                     "randbook disc:air","randbook disc:earth"}
  local choices   = {1, 2, 3, 4}
  local i, j, temp
  for i = 4, 2, -1 do
     j = crawl.random_range(1,i)
     temp = choices[j] ; choices[j] = choices[i] ; choices[i] = temp
  end
  local inventory = evocables[choices[1]] .. " | " .. evocables[choices[2]] ..
           " | " .. staffs[choices[3]] .. " | " .. randbooks[choices[4]]
  kfeat("s = general shop type:Elemental suffix:Accessories count:4 use_all ; "
         .. inventory )
}}
MAP
.......
.B.A.B.
.......
.A.s.A.
.......
.B.A.B.
.......
ENDMAP

# Sells only randbooks. All unique first editions with goofy names.
NAME: nicolae_rare_books
TAGS: transparent extra
DEPTH: Elf, Depths
KFEAT: S = book shop type:One-of-a-Kind suffix:Books count:5 ; \
       any fixed theme book | any fixed level book
MAP
 c.c
.....
c.S.c
.....
 c.c
ENDMAP

# Why not take a chance on an unidentified artefact?
NAME: nicolae_antique_artefacts
TAGS: transparent extra
DEPTH: D:10-, Depths
WEIGHT: 1
SHUFFLE: -m
SUBST: - = .
KFEAT: m = iron_grate
KFEAT: S = antiques shop type:Antique suffix:Artefacts count:8 ; \
   any weapon randart | any armour randart | any jewellery randart w:4 | \
   any magical staff randart w:4
MAP
.......
.-vmv-.
.v...v.
.m.S.m.
.v...v.
.-vmv-.
.......
ENDMAP

# Get away from it all.
NAME: nicolae_island_escapes
DEPTH: D:7-, !D:$, Depths, !Depths:$, Shoals, !Shoals:$, Swamp, !Swamp:$
TAGS: no_item_gen no_monster_gen water_ok no_tide no_pool_fixup no_descent
WEIGHT: 5
SHUFFLE: Aa/Bb
SUBST: Aa = t, B = ..t, b = .
KFEAT: S = general shop type:Island suffix:Escapes count:7 ; \
 scroll of blinking | scroll of teleportation w:15 | scroll of fog w:8 | \
 potion of enlightenment | potion of invisibility w:8 | potion of haste w:3 | \
 ring of flight w:5 | wand of digging w:4
MAP
  wwwwwwwww
 wwwwwwwwwww
 wwwwwwwwwww
 wwwwBABwwww
@wwwa...Awww
@wwwb.S>Bwww
@wwwa...Awww
 wwwwBABwwww
 wwwwwwwwwww
 wwwwwwwwwww
  wwwwwwwww
ENDMAP

# Eat the purple.
NAME:   nicolae_transmutations_shop
TAGS:   transparent no_item_gen no_monster_gen extra
DEPTH:  D:8-, Depths, Zot
COLOUR: m = magenta
TILE:   m = dngn_transparent_wall_magenta
KFEAT:  S = general shop type:Changing suffix:Room count:7 ; \
            potion of mutation | potion of lignification | wand of polymorph | \
            book of transmutation w:5 | any talisman w:30 | \
            randbook disc:alchemy w:5 | plutonium_sword w:1
MARKER: F = lua:fog_machine { cloud_type = "mutagenic fog", pow_min = 50, \
   pow_max = 50, delay = 1, size = 1, walk_dist = 0, start_clouds = 1, \
   spread_rate = 0, excl_rad = 0 }
MAP
.........
.mmmmmmm.
.mFFFFFm.
.m....Fm.
....S.Fm.
.m....Fm.
.mFFFFFm.
.mmmmmmm.
.........
ENDMAP

NAME:   doesnt_shop_hydraphobe
DEPTH:  D:5-11
WEIGHT: 5
TAGS:   transparent no_pool_fixup
KPROP:  -1wP = no_tele_into
KMASK:  -w = no_monster_gen
KMASK:  -1wP = no_item_gen
KMASK:  -1wP = opaque
MONS:   hydra
KMONS:  P = plant
KFEAT:  P = shallow_water
KFEAT:  S = weapon shop type:Hydra suffix:Hut count:7 ; falchion ego:flaming | \
    long sword ego:flaming | scimitar ego:flaming | great sword ego:flaming | \
    hand axe ego:flaming | broad axe ego:flaming | war axe ego:flaming | \
    battleaxe ego:flaming | lajatang ego:flaming | halberd ego:flaming | \
    glaive ego:flaming | hand cannon ego:freezing | orcbow ego:freezing | \
    arbalest ego:freezing | shortbow ego:freezing | longbow ego:freezing
FTILE:  -1wP = floor_lair
COLOUR: -1 = brown
MAP
.......
.ccccc.
.cwP1c.
.c---c.
.cnnnc.
.......
...S...
.......
ENDMAP

# Get your favourite rare base type early in the game! As long as you don't mind
# enchanting and branding it yourself...
NAME:    minmay_shop_damaged
TAGS:    transparent extra
# not interesting after Lair
DEPTH:   D:4-10
KFEAT:   S = general shop type:Lightly-Used suffix:Armoury ; \
             damaged ego:none demon whip | \
             damaged ego:none eveningstar | \
             damaged ego:none quick blade | \
             damaged ego:none demon blade | \
             damaged ego:none double sword | \
             damaged ego:none triple sword | \
             damaged ego:none executioner's axe | \
             damaged ego:none demon trident | \
             damaged ego:none bardiche | \
             damaged ego:none lajatang | \
             damaged ego:none hand cannon | \
             damaged ego:none triple crossbow | \
             damaged ego:none longbow | \
             damaged ego:none crystal plate armour | \
             damaged ego:none barding | \
             damaged ego:none pearl dragon scales | \
             damaged ego:none gold dragon scales
MAP
S
ENDMAP

NAME:    minmay_shop_chei
TAGS:    transparent extra
DEPTH:   D:7-
WEIGHT:  5
KFEAT:   _ = altar_cheibriados
# Determine items and their enchantment for the shop.
{{
-- The enchantment bonus for ponderousness only gets applied to naturally
-- generated items, so I have to duplicate it here in order to get the same
-- distribution of enchantments as naturally generated plate of ponderousness.
local plateEnchant = 3 + crawl.random2(3) + crawl.random2(8) +
    (crawl.x_chance_in_y(21 + you.absdepth(), 300) and crawl.random2(3) or 0)
if plateEnchant > 10 then plateEnchant = 10 end

-- And that enchantment bonus is too good for CPA, so use a super complicated
-- custom formula for the CPA's enchantment.
local cpaEnchant = crawl.random2(6)

-- Don't want to have the same items every time, but also don't want to pick
-- the same unrandart twice. So build a custom list...
local items = {"black knight's barding",
               "hat of pondering",
               "crystal plate armour ego:ponderousness plus:" .. cpaEnchant,
               "plate armour ego:ponderousness plus:" .. plateEnchant}
local itemCount = crawl.random2(2) + 1
local chosen = {}
local kstr =
    "S = armour shop name:Cheibriados type:Comfort suffix:Zone use_all ; "
local i = 0
while i < itemCount do
    local itm = items[crawl.random2(#items) + 1]
    if not (chosen[itm]) then
        i = i + 1
        chosen[itm] = true
        kstr = kstr .. itm
        if i < itemCount then kstr = kstr .. " | " end
    end
end
kfeat(kstr)
}}
MAP
 ...
.._..
.G.G.
..S..
 ...
ENDMAP

NAME:   minmay_shop_enchanted_jewellery
DEPTH:  D:4-, Depths, Orc, Elf, Shoals, Snake, Vaults
TAGS:   transparent extra
WEIGHT: 5
KFEAT:  S = jewellery shop ; \
            ring of strength | \
            ring of dexterity | \
            ring of intelligence | \
            amulet of reflection | \
            ring of evasion | \
            ring of protection | \
            ring of slaying w:3
MAP
S
ENDMAP

NAME:   minmay_shop_mayhem
DEPTH:  D:4-, Depths, Orc, Elf, Shoals, Snake, Vaults
TAGS:   transparent extra
WEIGHT: 3
# Only deals in items that damage multiple targets, only has spellbooks in which
# ALL of the spells damage multiple targets.
{{
local kstr = "S = general shop type:Mayhem suffix:Merchandise ; " ..
             "hand axe w:5 | " ..
             "war axe | " ..
             "broad axe w:5 | " ..
             "battleaxe | " ..
             "executioner's axe w:2 | " ..
             "book of fire w:5 | " ..
             "the unrestrained analects w:5 | " ..
             "wand of iceblast"

-- Unfortunately this can still result in the unrandart being picked twice or
-- more in the shop (resulting in the shop having regular clubs/great maces).
-- unrandart axes aren't included here since one of the above axes can already
-- get turned into them.
if not you.unrands("devastator") then
      kstr = kstr .. "|devastator w:1"
end
if not you.unrands("firestarter") then
      kstr = kstr .. "|firestarter w:1"
end

kfeat(kstr)
}}
MAP
S
ENDMAP

NAME:   minmay_shop_mass
DEPTH:  D:4-, Depths, Orc, Elf, Shoals, Snake, Vaults
TAGS:   transparent extra
WEIGHT: 3
# Only deals in items that are probably really heavy.
KFEAT:  S = general shop type:Mass suffix:Market ; \
        large rock w:30 | \
        giant club w:20 | \
        giant spiked club | \
        great mace | \
        executioner's axe w:2 | \
        triple sword w:2 | \
        bardiche w:5 | \
        plate armour w:20 | \
        tower shield | \
        crystal plate armour w:1
MAP
S
ENDMAP

# top tier equipment for a single gold... if you're on zot:5
NAME:   hellmonk_bargain_basement
DEPTH:  Zot:5
WEIGHT: 3
KFEAT:  S = general shop type:Last-Chance suffix:Deals greed:0 count:7 ; \
 any ring randart w:15 | any amulet randart w:15 | quick blade randart | \
 pearl dragon scales randart | executioner's axe randart | \
 triple sword randart | triple crossbow randart | longbow randart | \
 hand cannon randart | bardiche randart | eveningstar randart | \
 crystal plate armour randart | any armour good_item randart w:50
MAP
  t
 ...
T.S.T
 ...
  T
ENDMAP

# The last holdout in a failed strip mall. A chance to pick up items at a
# potentially very steep discount... if there's anything good left, that is.
# The greed can range from 0 to 9 with an average of 4.5.
# The item count can range from 1 to 7 with an average of 4.
# There is a 0.2% chance of rolling greed = 0, which makes everything in the
# store cost one gold. Hopefully it's not just +0 robes and scrolls of noise.
NAME:   nicolae_shop_clearance
TAGS:   transparent
DEPTH:  D:4-, Depths, Orc, Elf, Snake, Shoals, Vaults, Zot
{{
local greed = crawl.roll_dice(9, 2) - 9
local count = crawl.roll_dice(6, 2) - 5
kfeat("S = general shop type:CLEARANCE_SALE! \
           greed:" .. greed .. " count:" .. count)
}}
KFEAT:  D = abandoned_shop
NSUBST: D = S / D
MAP
xxxxxxx
xD.D.Dx
.......
...V...
.......
xD.D.Dx
xxxxxxx
ENDMAP

NAME:   nicolae_shop_firing_range
TAGS:   transparent no_monster_gen no_item_gen no_tide
DEPTH:  D:4-, Depths, Orc, Elf, Shoals, Snake, Vaults
KMONS:  DE = training dummy
KITEM:  D = stone q:1 / nothing, stone q:1 / nothing, stone q:1 / nothing
KITEM:  H = stone q:1 w:30 / boomerang q:1 / javelin q:1 / dart q:1
KITEM:  E = throwing net q:1
# Launchers are weighted so they have the same total weight as the projectiles.
# The slightly-higher weights go to the better weapons, because I'm nice.
KFEAT:  S = weapon shop type:Firing suffix:Range ; dart w:14 | \
        throwing net w:14 | boomerang  w:14 | javelin w:14 | large rock w:14 \
        | sling | shortbow | orcbow | longbow | hand cannon | arbalest | \
        triple crossbow | manual of throwing w:1 | manual of ranged weapons w:1
NSUBST: D = E / D
SUBST:  ' = H .:25
MAP
.....
.xxxxxxxx
.x'''''Dx
.S'''''Dx
.x'''''Dx
.xxxxxxxx
.....
ENDMAP

# Gadget shops are back! Well, one gadget shop is back.
NAME:    nicolae_shop_gadgets
TAGS:    transparent
DEPTH:   D:4-, Depths, Orc, Elf, Shoals, Snake, Vaults
KFEAT:   S = general shop type:Gadget suffix:Gallery count:4 ; \
         any wand | any misc
SHUFFLE: cvmb
MAP
cc.vv
c...v
..S..
m...b
mm.bb
ENDMAP

# Sells wands with 25% more charges than the usual item-generation maximum,
# with a 50% markup.
NAME:    nicolae_shop_overcharged_wands
TAGS:    transparent
DEPTH:   D:4-, Depths, Orc, Elf, Shoals, Snake, Vaults
KFEAT:   S = general shop type:Overcharged suffix:Wands greed:15 count:6 ; \
         wand of digging charges:11 | any blast wand charges:18 | \
         any beam wand charges:18 | wand of charming charges:18 | \
         wand of paralysis charges:18 | wand of polymorph charges:18 | \
         wand of mindburst charges:30 | wand of flame charges:40
SHUFFLE: bv/bc/cv/bm/vm/cm
MAP
.......
..b.v..
.b...v.
...S...
.v...b.
..v.b..
.......
ENDMAP

NAME:  nicolae_shop_self_help
TAGS:  transparent no_pool_fixup
DEPTH: D:4-, Depths, Orc, Elf, Shoals, Snake, Vaults
KFEAT: S = book shop type:Self-Improvement suffix:Boutique count:4 ; \
           any manual
SUBST: T : TUw
MAP
 ww.ww
www.www
wwT.Tww
...S...
wwT.Tww
www.www
 ww.ww
ENDMAP

NAME:   nicolae_shop_sticking_my_neck_out
TAGS:   transparent
DEPTH:  D:4-, Depths, Elf, Snake
KFEAT:  S = general shop type:Neck suffix:Hole count:7 use_all ; \
        cloak | cloak | scarf | scarf | any amulet | any amulet | any amulet
MAP
cc     cc
..c   c..
...ccc...
....S....
...ccc...
..c   c..
cc     cc
ENDMAP

NAME:   hellmonk_scale_shop
TAGS:   transparent
WEIGHT: 3
DEPTH:  D:8-, Snake, Depths
KFEAT:  D = armour shop type:Superior suffix:Scales count:3 ; \
        scale mail randart
: if you.in_branch("Depths") then
KMONS:  D = golden dragon / iron dragon / quicksilver dragon / storm dragon /\
        shadow dragon / pearl dragon w:1
: elseif you.in_branch("D") and you.absdepth() < 13 then
KMONS:  D = steam dragon / acid dragon
:else
KMONS:  D = fire dragon / ice dragon / swamp dragon
:end
MAP
 xxx
xxll@
xl..lx
xlD.lx
xxllxx
 xxxx
ENDMAP

NAME:   monkooky_shop_mail_order
TAGS:   transparent
WEIGHT: 3
DEPTH:  D:6-, Vaults, Depths
{{
local count = crawl.roll_dice(2, 2) + 3
local kstr = "S = general shop type:Mail-Order suffix:Catalogue " ..
             "count:" .. count .. " ; " ..
             "w:5 ring mail | " ..
             "ring mail good_item| " ..
             "w:5 scale mail | " ..
             "scale mail good_item| " ..
             "w:5 chain mail | " ..
             "chain mail good_item"

-- Stealing nicolae's methodology from Mayhem Merchandise
-- Again, could but probably won't result in an inappropriate lajatang appearing
if not you.unrands("lajatang of order") then
      kstr = kstr .. "|lajatang of order w:6"
end

kfeat(kstr)
}}
MAP
S
ENDMAP

NAME:   monkooky_shop_alliterative
TAGS:   transparent
WEIGHT: 3
DEPTH:  D:8-, Orc, Elf, Depths
{{
local count = crawl.roll_dice(2, 3) + 5
local name = "A" ..
  string.sub(string.lower(string.gsub(crawl.make_name(), " ", "")), 2)
--Weights of equally rare weapons are divided by two for types with
--two alliterative egos
local weaponnames = {"dagger", "short sword", "falchion", "scimitar",
                    "w:3 demon blade", "double sword w:3",
                    "hand axe", "executioner's axe w:6",
                    "club w:20", "flail", "demon whip w:3",
                    "dire flail", "eveningstar w:6",
                    "spear", "halberd", "demon trident w:3"}
local egos = {"chaos", "draining", "distortion", "electrocution", "flaming",
              "freezing", "heavy", "speed", "spectral"}
local kstr = "S = general shop name:" .. name .. " type:Alliterative " ..
             "suffix:Armaments count:" .. count .. " ; " ..
             "halberd itemname:scythe tile:wpn_scythe wtile:scythe ego:speed | " ..
             "halberd itemname:scythe tile:wpn_scythe wtile:scythe ego:spectral"
--add any weapon-ego pair with matching first letter
for _, weapon in ipairs(weaponnames) do
  for _, ego in ipairs(egos) do
    if weapon:sub(1, 1) == ego:sub(1, 1) then
      kstr = kstr .. " | " .. weapon .. " ego:" .. ego
    end
  end
end
kfeat(kstr)
}}
MAP
S
ENDMAP


# Q: Why is the shop across from your fire supplies store burned down?
# A: Don't worry about it. Are you going to buy something or not?
NAME:     nicolae_shop_fire_sale
TAGS:     extra transparent no_item_gen
DEPTH:    D:4-, Depths
KITEM:    O = ring of ice w:5 / ring of protection from cold / \
          damaged dagger ego:freezing / wand of iceblast charges:1 w:5
KFEAT:    O = abandoned_shop
KFEAT:    P = general shop type:Fire suffix:Supplies ; ring of fire | \
          ring of protection from fire | staff of fire | wand of flame | \
          any weapon ego:flaming w:30 | scroll of immolation | \
          randbook disc:fire w:20 | manual of fire magic w:1 | \
          any armour ego:fire_resistance w:30 | fire dragon scales w:5
SUBVAULT: ' : nico_deadtrees
MARKER:   O = lua:fog_machine { cloud_type = "black smoke", pow_min = 10, \
              pow_max = 20, delay = 40, size = 1, walk_dist = 0 }
MAP
xxxxx@@xxxxx
xx''....ttxx
x''......ttx
x'O.V..T.Ptx
x''......ttx
xx''....ttxx
xxxxx@@xxxxx
ENDMAP

# Using a subvault so only these trees become dead trees.
NAME:   nicolae_sub_dead_trees
TAGS:   unrand nico_deadtrees
SUBST:  t = tt.
COLOUR: t = lightgrey / darkgrey
TILE:   t = dngn_tree_dead
: set_feature_name("tree", "dead tree")
MAP
t   t
tt tt
 ttt
ENDMAP

# This shop sells only unique rings. At least one randart, and also ordinary
# rings whose pluses have been set via vault syntax to something besides the
# default pluses for that type of ring.
# For each of the six rings that can have pluses, there is the possibility of
# a ring of that type whose pluses are worse than default (which makes it a bit
# less useful, but cheaper, and so possibly more enticing to poor players),
# and a ring of that type whose pluses are better than default (which will be
# accordingly more expensive).
# Default for dex/int/str: +6, default for EV: +5, default for slay/prot: +4
# EV/prot rings are capped to not step on existing unrands, rest capped at +10
NAME:   nicolae_shop_unique_rings
TAGS:   transparent extra
DEPTH:  D, Depths, Elf, Snake, Shoals
WEIGHT: 5
{{
  local itemcount = crawl.roll_dice( 2, 3 ) + 1
  local rings = {
     -- Worse than usual:
     -- +1 to +5
     "ring of dexterity    plus:" .. (crawl.roll_dice( 4, 2 ) - 3),
     "ring of intelligence plus:" .. (crawl.roll_dice( 4, 2 ) - 3),
     "ring of strength     plus:" .. (crawl.roll_dice( 4, 2 ) - 3),
     -- +1 to +4
     "ring of evasion      plus:" .. (crawl.roll_dice( 3, 2 ) - 2),
     -- +1 to +3
     "ring of slaying      plus:" .. (crawl.roll_dice( 2, 2 ) - 1),
     "ring of protection   plus:" .. (crawl.roll_dice( 2, 2 ) - 1),
     -- Better than usual:
     -- +7 to +10
     "ring of dexterity    plus:" .. (crawl.roll_dice( 3, 2 ) + 4),
     "ring of intelligence plus:" .. (crawl.roll_dice( 3, 2 ) + 4),
     "ring of strength     plus:" .. (crawl.roll_dice( 3, 2 ) + 4),
     -- +6 to +9
     "ring of evasion      plus:" .. (crawl.roll_dice( 3, 2 ) + 3),
     -- +5 to +10
     "ring of slaying      plus:" .. (crawl.roll_dice( 5, 2 )),
     -- +5 to +7
     "ring of protection   plus:" .. (crawl.roll_dice( 2, 2 ) + 3),
     "any ring randart", "any ring randart", "any ring randart" }
  local inventory = table.concat( util.random_subset( rings, itemcount ), " | ")
  kfeat("P = jewellery shop type:One-of-a-Kind suffix:Rings count:" ..
             (itemcount + 1) .. " use_all ; " ..
             inventory .. " | any ring randart" )
}}
MAP
  vvv..
 v...v..
v.....v.
v..P..b@
v.....v.
 v...v..
  vvv..
ENDMAP

NAME:   nicolae_shop_dragon_depot
TAGS:   transparent extra no_item_gen no_tide
DEPTH:  D:4-, Depths, Elf, Snake, Shoals
WEIGHT: 5
{{
  -- This shop is guaranteed to generate one of each type of dragon scales.
  -- About a half will get the good_item modifier. This keeps the shop
  -- inventory from just being a boring list of gray +0 scales 90% of the time.
  -- This also makes things slightly less of a guarantee, since if the scales
  -- you want get turned into a randart, they might become too expensive for
  -- you, or end up with some kind of negative artefact property like -Tele.
  local scales = { "steam dragon scales", "acid dragon scales",
    "swamp dragon scales", "fire dragon scales", "ice dragon scales",
    "pearl dragon scales", "shadow dragon scales", "storm dragon scales",
    "gold dragon scales", "quicksilver dragon scales" }

  for i, sc in ipairs(scales) do
     if crawl.coinflip() then
       scales[ i ] = sc .. " good_item"
     end
  end

  -- Mostly from the Wikipedia list of fictional/mythological dragonslayers,
  -- although some are from poking around elsewhere in dragon-related articles.
  -- Some dragonslayers have multiple spellings/alternates/variations of their
  -- names included, or have their first and last names listed separately.
  -- No videogame references, but there is some Tolkien in here. Some of these
  -- dragonslayers are better known for other works.
  local dragonslayers = { "Apollo", "Argus", "Assipattle", "Baal", "Bahram_Gur",
    "Bayajidda", "Benzaiten", "Beowulf", "Bulat", "Cadmus", "Daniel",
    "Dobrynya", "Earendil", "Egara", "El", "Enki", "Erlang", "Erlang_Shen",
    "Eurybarus", "Fat-Frumos", "Fereydun", "Fraech", "Garshasp", "Gawain",
    "George", "Gilgamesh", "Hadad", "Hadad-Baal", "Haida", "Haymon",
    "Heinrich", "Heracles", "Indra", "Ishkur", "John_Lambton", "Keresaspa",
    "Kirsasp", "Krakus", "Lancelot", "Li_Erlang", "Li_Ji", "Lodbrok", "Marduk",
    "Margaret", "Michael", "Moore", "Mwindo", "Nabu", "Nezha", "Ninurta",
    "Perseus", "Piers_Shonks", "Ra", "Ragnar", "Rammanu", "Rostam", "Sarasvati",
    "Schrutan", "Siegfried", "Sigurd", "Sikandar", "Susanowo", "Tanenaga",
    "Tarhunz", "Teodosio", "Teshub", "Thor", "Tishpak", "Tokoyo", "Tristan",
    "Turambar", "Vahagn", "Venera", "Vishabakagh", "Wada", "Winkelried",
    "Yahweh", "Yegara", "Zeus", "Zhao_Yu" }
  local shopname = dragonslayers[ crawl.random2( #dragonslayers ) + 1 ]
  kfeat( "P = armour shop name:" .. shopname ..
         " type:Dragon-Slaying suffix:Spoils count:10 use_all ; " ..
         util.join( " | ", scales ) )
}}
KFEAT: N = b
KPROP: PNWY' = bloody
MAP
   xxxxxxxx
  xx......xx
 xx...bb...xx
xx'''NbWbb..xx
xP''Nbbbbbb..@
xY''Nbbbbbb..@
xx'''NbWbb..xx
 xx...bb...xx
  xx......xx
   xxxxxxxx
ENDMAP

# A reference to the special Oracle level from NetHack.
# Like in NetHack, players can purchase readings from the Oracle. In a sense.
NAME:   nicolae_nh_oracle_at_delphi
TAGS:   transparent no_rotate
DEPTH:  D, Depths, Elf
WEIGHT: 5
# In Nethack, sometimes statues can contain spellbooks if you break them open.
# Here, for each statue, there's a 1/12 chance that it's broken, leaving
# behind a pile of rocks and a book. With 8 statues, the odds are about 50/50
# that at least one free spellbook will be generated. And some rocks.
KITEM:  ` = stone, any book
KFEAT:  O = scroll shop name:The_Oracle type:Delphic suffix:Readings ; \
            any scroll | any book
NSUBST: . = 2=0 / ., D = . / c, E = + / x, F = + / x
SUBST:  G = G:11 `:1
TILE:   G : dngn_statue_centaur
MAP
xxxxxxxxxxxxx
xG.........Gx
E.....G.....F
E...cDcDc...F
E...D-T-D...F
E..GcTOTcG..F
E...D-T-D...F
E...cDcDc...F
E.....G.....F
xG.........Gx
xxxxxxxxxxxxx
ENDMAP

# Now that most predefined books have been cut back to 3 spells,
# there is a growing market for spellbooks with a little more thickness.
NAME:   nicolae_shop_i_like_big_books
TAGS:   transparent extra
DEPTH:  D:4-, Depths, Elf, Snake
KFEAT:  S = book shop type:Tremendous suffix:Tomes count:8 ; \
            any randbook numspells:8
KFEAT:  p = c
COLOUR: p : blue / red / magenta / lightgreen / lightred / lightmagenta / yellow
MAP
...........
.pppppppp..
.cccccccpp.
.......ccp.
.......Scp.
.......ccp.
.cccccccpp.
.pppppppp..
...........
ENDMAP

NAME:   nicolae_shop_i_like_small_books_too
TAGS:   transparent extra
DEPTH:  D:4-, Depths, Elf, Snake
KFEAT:  S = book shop type:Tiny suffix:Tomes count:8 ; \
            any randbook numspells:1
KFEAT:  p = c
COLOUR: p : blue / red / magenta / lightgreen / lightred / lightmagenta / yellow
MAP
.......
.ppppp.
..cccp.
...Scp.
..cccp.
.ppppp.
.......
ENDMAP

NAME:  nicolae_shop_vocational
TAGS:  transparent
DEPTH: D, Depths, Orc, Elf, Shoals, Snake, Vaults
KFEAT: S = book shop type:Vocational suffix:Training count:2 use_all ; \
           manual of invocations | manual of evocations
MAP
.......
.T...T.
...S...
.T...T.
.......
ENDMAP

# Featuring everybody's favorite sketchy Mesopotamian copper merchant.
# Sells metal goods, which may or may not actually be fine. Only half the items
# will have the damaged tag, so it's still possible to get something good, and
# even the damaged goods can still have egos. But it's an antique store, so you
# can't tell which items are good and which aren't.
# Layout inspired by the map here:
# https://en.wikipedia.org/wiki/Complaint_tablet_to_Ea-nasir
NAME:   nicolae_ea-nasir_strikes_again
TAGS:   transparent extra
DEPTH:  D:4-10
WEIGHT: 2
{{
-- Rather than writing the whole list out myself, I'll make lua do it.
local metal_goods = {"ring mail", "scale mail", "chain mail", "plate armour",
   "buckler", "kite shield", "tower shield", "helmet", "rapier", "war axe",
   "short sword", "scimitar", "great sword", "broad axe", "battleaxe", "glaive",
   "morningstar", "dire flail", "great mace", "trident", "arbalest", "bardiche",
   "executioner's axe", "eveningstar", "lajatang", "hand cannon",
   "triple crossbow"}
local inventory = {}
for _, good in ipairs(metal_goods) do
   table.insert(inventory, good .. " damaged w:13")
   table.insert(inventory, good)
   table.insert(inventory, good .. " good_item w:3")
end
kfeat("E = antiques shop name:Ea-nāṣir type:Fine_Metal suffix:Goods ; " ..
   util.join(" | ", inventory))
}}
# The scrolls represent the complaint tablets, many of which were found in
# the bottom-left room, with the rest throughout the house. Scroll count odds:
# 2 ~ 19.75%, 3 ~ 39.51%, 4 ~ 29.63%, 5 ~ 9.88%, 6 ~ 1.23%
KITEM:  S = any scroll
NSUBST: ` = 2=S / 2=S.. / ., . = 2=S.. / .
SUBST:  - = ., { = {[(
MAP
         xxxxxxx
         x-------@
         x----xxx-
  x    xxxxxx+x.+-
 -xxxxxx...x..x.x-
 @-----+...x..xxx-
xxxxxxxx...x..x.--
 x``x..xx+xxx+xxx-
 x``+..x.......x.-
 x``x..+...E...xx-
 x``x..x.......x.--
 x``x..xx+xxx+xxxxx
 x``x..x...x.....{x
 xxxxxxxxxxxxxxxxxx
xx
ENDMAP

# a well guarded shop which sells orb and orb-related things
NAME:   tekkud_shop_of_orbs
TAGS:   no_monster_gen no_item_gen no_trap_gen patrolling
TAGS:   vaults_hard vaults_orient_s
DEPTH:  D:13-, Snake:2-, Elf:2-, Vaults, Crypt, Depths, Zot, !Zot:$
WEIGHT: 1 (Zot), 3
{{
local shopname = util.random_from({"type:Orb suffix:Outfitters",
   "type:Spherical suffix:Supermarket", "type:Round suffix:Resellers",
   "type:Globular suffix:Garage"})
local kstr = "S = general shop " .. shopname .. " count:6 ; " ..
             "orb randart w:20 | orb w:5 | book of the spheres w:1 "

if not you.unrands("sphere of Battle") then
      kstr = kstr .. " | sphere of Battle w:2"
end
if not you.unrands("crystal ball of Wucad Mu") then
      kstr = kstr .. " | crystal ball of Wucad Mu w:2"
end

kfeat(kstr)
}}
: if you.in_branch("D") then
MONS:  orb spider, great orb of eyes / occultist w:5
MONS:  tengu conjurer / boulder beetle w:5
SUBST: + = =
: elseif you.in_branch("Snake") then
MONS:  nagaraja / naga sharpshooter, naga ritualist / salamander mystic
MONS:  naga / salamander / mana viper w:5
: elseif you.in_branch("Elf") then
MONS:  deep elf high priest / deep elf sorcerer / \
       deep elf elementalist / crystal guardian
MONS:  deep elf knight / deep elf archer w:5
MONS:  deep elf zephyrmancer / deep elf pyromancer
: elseif you.in_branch("Vaults") then
MONS:  lich / fire giant, crystal guardian
MONS:  great orb of eyes / occultist w:5 / glowing shapeshifter w:1
SUBST: + = .
: elseif you.in_branch("Crypt") then
MONS:  revenant / curse skull w:5 / lich
MONS:  vampire knight / deep elf death mage
MONS:  orb spider zombie / weeping skull / laughing skull
: elseif you.in_branch("Depths") then
MONS:  glass eye / tengu reaver, lich / fire giant w:5
MONS:  occultist w:5 / tengu conjurer / rakshasa w:5
: else -- Zot
MONS:  orb of fire, draconian scorcher, lich
: end
MAP
   ccccc
  ccccccc
 ccc212ccc
ccc.....ccc
cc3.....3cc
cc...S...cc
cc3.....3cc
ccc.....ccc
 ccc...ccc
  ccb+bcc
ENDMAP

###############################################################################
# <<3>> Multi
#       Not tagged shop, and has no threats. Contain possibly multiple shops in
#       a somewhat generic theme. Kept here for a certain ease of reference.
#

# 3 shops
NAME:    minmay_shop_grove
TAGS:    extra luniq_floating_shops transparent
DEPTH:   D:4-, Depths, Elf, Snake
ORIENT:  float
MONS:    plant / bush w:2
KFEAT:   B = book shop
KFEAT:   C = jewellery shop
SUBST:   1 : 1.
SUBST:   1 = 1:9 .:1
SUBST:   x : xc v:2 b:2
SHUFFLE: BC
# The empty arch is intentional!
MAP
  xxxxxxx
 xxtttttxx
xxtt1.1ttxx
xtt..B..ttx
xt.C...C.tx
xt1..T..1tx
xt11...11tx
xttttAttttx
xxxxx@xxxxx
ENDMAP

# 1 (33%) or 4 (66%) shops
NAME:    minmay_shop_grid_forest
TAGS:    extra luniq_floating_shops transparent
DEPTH:   D:4-, Depths, Elf, Snake
KFEAT:   A = any shop
SHUFFLE: ABC
SUBST:   t : t:11 x:1 c:1 b:1 v:1
SUBST:   B : .:12 C:6 x:1 c:1 b:1 v:1 G:1 T:1
SUBST:   C : T:12 x:1 c:1 b:1 v:1 G:1 t:1
MAP
.........
.t.t.t.t.
..B.C.B..
.t.t.t.t.
..C.A.C..
.t.t.t.t.
..B.C.B..
.t.t.t.t.
.........
ENDMAP

# 1 (25%), 2 (25%), or 3 (50%) shops
NAME:    minmay_shop_star
TAGS:    extra luniq_floating_shops transparent
DEPTH:   D:4-, Depths, Elf, Snake
ORIENT:  float
KFEAT:   A = any shop
SHUFFLE: AB
SUBST:   b : x:20 cv b:5 .:5 m:5 G:5 t:5
SUBST:   A : A:90 .xcvbmGtT
SUBST:   B = A
MAP
       x@x
       x.x
      xx.xx
      x...x
xxxxxxxb.bxxxxxxx
@.....b...b.....@
xxx.....A.....xxx
  xxx.b...b.xxx
    xxx.B.xxx
  xxx.b...b.xxx
xxx.....A.....xxx
@.....b...b.....@
xxxxxxxb.bxxxxxxx
      x...x
      xx.xx
       x.x
       x@x
ENDMAP

# 2 (50%) or 4 (50%) shops
NAME:    minmay_shoptagon
TAGS:    extra luniq_floating_shops transparent
DEPTH:   D:4-, Depths, Elf, Snake
ORIENT:  float
KFEAT:   A = any shop
SUBST:   a : . m:1 G:1
SUBST:   b : xcvbmGt
SUBST:   d : .:60 cvbmGt
SHUFFLE: AB, CD
SUBST:   C : .:80 xcvbmGtT
SUBST:   D : .:80 xcvbmGtT
SUBST:   B : A.
MAP
    xxx@xxx
   xxd...dxx
  xxd..D..dxx
 xxd.......dxx
xxd....B....dxx
xd...C...C...dx
x.....aaa.....x
@.D.A.aba.A.D.@
x.....aaa.....x
xd...C...C...dx
xxd....B....dxx
 xxd.......dxx
  xxd..D..dxx
   xxd...dxx
    xxx@xxx
ENDMAP

NAME:  nicolae_specific_store
TAGS:  extra transparent no_pool_fixup
DEPTH: D:4-, Depths, Orc, Elf, Shoals, Snake
KFEAT: D = general shop type:General suffix:Store
KFEAT: E = general shop type:Specific suffix:Store count:1
SUBST: G : GTUtwx, x : x:120 c:60 bv.
MAP
xx...xx
xG...Gx
xD...Ex
xG...Gx
xx...xx
ENDMAP

# Chance of X shops: 1: 15%, 2: 30%, 3: 30%, 4: 15%, 5: 5%, 6 : 5%
NAME:    nicolae_wooded_promenade
TAGS:    extra luniq_floating_shops transparent no_pool_fixup
DEPTH:   D:4-, Depths, Elf, Snake
KFEAT:   s = any shop
# s = shop, y and z = two different kinds of features
# Unshuffled corresponds to ysyzyz
SHUFFLE: DEFHJK/ysyyzy/syyyyz/syzzys/syyzzs/yszzsy/ysyzsz/sysyzy/syszyz/ \
         ysyszs/ysyszs/sssyzy/sssyzy/ssyzzs/ssysyz/syssys/ssyyss/sssysy/ \
         ssssys/ssssss
SUBST:   DFJ = y, HK = z, E = s, y : GGTTUt, z : GGTTUt, - : ww.
MAP
    xxxxxxxxxxx
    xtttttttttx
    xt.......tx
    xt.D.E.F.tx
    @.........@
wwwwwwwww-wwwwwwwww
wwwwwwwww-wwwwwwwww
    @.........@
    xt.H.J.K.tx
    xt.......tx
    xtttttttttx
    xxxxxxxxxxx
ENDMAP

# 3 shops, on different "floors"
NAME:  nicolae_shop_distant_corner_stores
TAGS:  transparent luniq_floating_shops extra no_descent
DEPTH: D:4-, !D:$, Depths:2-, !Depths:$
KFEAT: Ss = any shop
KMASK: {[()]}T`s = opaque
SUBST: { = {[(, } = }])
MAP
ccccc.
cT``n..
c`{`n...
c``sn..G.
cnnnn.....
.....S.....
 .....nnnnc
  .G..ns``c
   ...n`}`c
    ..n``Tc
     .ccccc
ENDMAP

# 25% chance of 4 shops, 50% chance of 5, 25% of 6
NAME:    nicolae_shop_national_dungeon_mall
TAGS:    transparent no_pool_fixup luniq_floating_shops extra
DEPTH:   D:5-, Depths
WEIGHT:  2
KFEAT:   S = any shop
SHUFFLE: DE, FH
SUBST:   DF = S, EH = T, T = T:16 U:1 V:1
COLOUR:  . = green
FTILE:   ._GSTUV = floor_grass
MAP
.....................
.G..D..E..D..E..D..G.
.....................
.G.WWWWWWWWWWWWWWW.G.
...wwwwwwwwwwwwwww...
.G.WWWWWWWWWWWWWWW.G.
.....................
.G..F..H..F..H..F..G.
.....................
ENDMAP
