###############################################################################
# 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 = table.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
}}

NAME: serial_shops
TAGS: nolayout_encompass 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 }

    if (you.branch() ~= "D") then
      if ((you.branch() ~= "Shoals" and you.branch() ~= "Snake") or crawl.coinflip()) then
        dgn.place_maps { tag = "parchment_shop", count = 1 }
      end
    end
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:   parchment_shop
TAGS:   allow_dup extra parchment_shop transparent unrand
KFEAT:  O = book 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 pre_id
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-, !D:$, Depths,!Depths:$
: ks_random_setup(_G, false)
: ks_shop_vault(_G, '{}CC')
MAP
cDc
FOF
c+c
ENDMAP

NAME:  kennysheep_mini_moat
TAGS:  shop temple_overflow_generic_1
DEPTH: D:4-, !D:$, Depths,!Depths:$
: ks_random_setup(_G, false)
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-, !D:$, Depths,!Depths:$
: ks_random_setup(_G, false)
: 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() ~= dgn.br_depth(you.branch()) 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 ; athame | 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 = armour echo ; plate armour | crystal plate armour | \
               pearl dragon scales | shadow dragon scales | \
               storm dragon scales | golden 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
: if you.in_branch("Shoals") then
FTILE: @'tD = floor_rough_lightgreen
FTILE: .S = floor_grass
: else
FTILE: @'tD = floor_moss
FTILE: .S = floor_grass_dark
: end
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
SUBST:  ? : ?..
: decorative_floor(_G, '?', "assortment of trash")
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.
: kitem("D : " .. vault_species_skeletons(_G, "early"))
: kitem("E : " .. vault_species_skeletons(_G, "late"))
: kitem("F : " .. vault_species_skeletons(_G, "dungeon"))
: kitem("H : " .. vault_species_skeletons(_G, "all"))
MAP
   .---
   .-E-
---.---
-D-......
---.S.---
......-F-
  ---.---
  -H-.
  ---.
ENDMAP

NAME:    nicolae_shop_bimaterial_pillars
TAGS:    allow_dup extra shop transparent
KFEAT:   O = any shop
SHUFFLE: cvbn
MAP
 ... ...
..c...c..
.cvc.cvc.
..c...c..
 ...O...
..c...c..
.cvc.cvc.
..c...c..
 ... ...
ENDMAP

NAME:    nicolae_shopburst
TAGS:    allow_dup extra shop transparent
KFEAT:   S = any shop
SHUFFLE: DE, FH, JK, LM
SUBST:   DFJL = c, EHKM = .
MAP
  FHF
 cFHFc
DD...JJ
EE.S.KK
DD...JJ
 cLMLc
  LML
ENDMAP

NAME:   nicolae_shop_closed_for_inventory
TAGS:   extra shop transparent
DEPTH:  D:8-, Depths, Snake, Shoals
WEIGHT: 1
KFEAT:  - = iron_grate
KFEAT:  O = any shop
KPROP:  O = no_tele_into
KMASK:  O = opaque
MAP
.---
.-O-
.---
ENDMAP

NAME:    nicolae_shop_cornered_store
TAGS:    allow_dup extra shop transparent
KFEAT:   S = any shop
SHUFFLE: DEF
SUBST:   D = ., E : am, F : am.
SHUFFLE: ma
SUBST:   a = x
MAP
xxxxx
x...D.
x.S.E.
x...F.
xDEFa.
 ....@
ENDMAP

NAME:  nicolae_shop_flopsided
TAGS:  allow_dup extra shop transparent
KFEAT: O = any shop
SUBST: c : cvbnt
MAP
c.c.c
......
 c.O.c
 ......
  c.c.c
ENDMAP

NAME:    nicolae_shop_glassy
TAGS:    allow_dup extra shop transparent
KFEAT:   + = closed_clear_door
KFEAT:   S = any shop
SHUFFLE: +m`p/m+p`
SUBST:   ` = ., p = m
MAP
 .....
..`p`..
.`m+m`.
.p+S+p.
.`m+m`.
..`p`..
 .....
ENDMAP

# Unwind by reading under a tree by a pond. :)
NAME:   nicolae_shop_relaxation
TAGS:   no_pool_fixup allow_dup extra shop transparent
KFEAT:  S = scroll shop / book shop
: if crawl.coinflip() then
SUBST:  pq = t
NSUBST: r = W / w
: else
SUBST:  r = t, p = w
NSUBST: q = W / w
: end
MAP
  ...
 ..p..
..qrq..
.prSrp.
..qrq..
 ..p..
  ...
ENDMAP

NAME:  nicolae_shop's_first_dollar
TAGS:  extra shop transparent
KITEM: $ = gold q:1
KFEAT: O = any shop
KPROP: $ = no_tele_into
KMASK: $ = no_monster_gen
KMASK: $ = no_item_gen
KMASK: $ = no_trap_gen
KMASK: $ = opaque
MAP
xxxxx
xxm...
x$m.O.
xxm...
xxxxx
ENDMAP

NAME:  nicolae_shop_swords_in_saltire
TAGS:  extra shop transparent
KFEAT: S = weapon shop / antique weapon shop
MAP
v.....v
.v.T.v.
..v.v..
.T.v.T.
v.v.v.v
.v.S.v.
v.v.v.v
ENDMAP

NAME:    nicolae_shop_targeted
TAGS:    allow_dup extra shop transparent
KFEAT:   S = any shop
SHUFFLE: -G
TILE:    G : dngn_statue_orb
MAP
xx.G.
xx.-@
xS.G.
xx.-@
xx.G.
ENDMAP

NAME:   nicolae_shop_well_armoured
TAGS:   allow_dup extra shop transparent
KFEAT:  S = armour shop / antique armour shop
NSUBST: - = 2:@ / v
MAP
 v v v
vv-v-vv
 -...-
vv.S.vv
 -...-
vv-v-vv
 v v v
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-, Snake
MONS:    ball python w:5 / adder, water moccasin
MONS:    black mamba w:20 / naga ; sling, naga mage / naga ritualist, nagaraja
KFEAT:   v = general shop type:Serpentskin suffix:Sales count:7 ; \
         dart ego:poisoned w:8 | dart ego:curare w:4 | scroll of poison w:5 | \
         ring of poison resistance w:3 | randbook disc:alchemy w:6 | \
         staff of alchemy w:2 | any weapon ego:venom w:4 | \
         partisan ego:venom w:1 | medusa talisman w:2 | \
         serpent talisman randart w:2 | \
         any armour ego:poison_resistance w:6 | w:1 swamp dragon scales
NSUBST:  ? = 2:? / 2 = ?.. / *:.
: if you.absdepth() < 7 then
SUBST:   ? = 1
: elseif you.absdepth() < 12 then
SUBST:   ? = 122
: elseif you.absdepth() < 16 then
SUBST:   ? = 334
: else
SUBST:   ? = 45
: end
MAP
xxxxx
x???x
+?v?+
x???x
xxxxx
ENDMAP

#####################################################
# Custom earth shop
NAME:    guppyfry_shop_earth
TAGS:    no_monster_gen transparent
DEPTH:   D:8-, Depths
KMONS:   1 = patrolling rock fish / kobold geomancer / basilisk
KMONS:   2 = gargoyle / basilisk / boulder beetle / cyclops w:3
KMONS:   3 = stone giant / walking earthen tome w:4 / \
             deep troll earth mage / iron dragon w:4
KMONS:   D = pile of debris
ITEM:    stone
SUBST:   ? = 1dd
{{
local inv = "tin of tremorstones w:7 | wand of digging w:8 | \
             staff of earth w:4 | randbook disc:earth w:5 | \
             book of the earth w:2 | book of iron w:2 | \
             book of the moon w:2 | crystal plate armour w:1 | "
if you.absdepth() < 16 then
  inv = inv .. "pair of boots ego:earth | stone w:14 | large rock w:14 | \
                sling w:8 | medusa talisman w:6 | book of geomancy w:2"
  if you.absdepth() > 11 then
    subst("1 = 2")
  end
else
  inv = inv .. "pair of boots randart artprops:Earth | large rock w:20 | \
                sling randart w:4 | medusa talisman randart w:4 | \
                granite talisman w:2 | compendium of siegecraft w:2 | \
                book of annihilations w:2"
  subst("1 = 3")
end
}}
SUBST:   B : D., C : D.
: kfeat("S = general shop type:Pet suffix:Rocks count:7 ; " .. inv)
MAP
B.....C
.xx+xx.
.x???x.
.m?S?m.
.x???x.
.xx+xx.
C.....B
ENDMAP

#####################################################
# Custom blood shop
NAME:    guppyfry_shop_blood
TAGS:    no_monster_gen transparent
DEPTH:   D:11-, Depths
KMONS:   1 = vampire / vampire bat
KMONS:   2 = vampire mage / vampire knight
KFEAT:   v = general shop type:Blood suffix:Bar count:8 ; \
             dagger ego:vampirism w:15 | any weapon ego:vampirism w:15 | \
             scale mail ego:death good_item w:4 | \
             chain mail ego:death good_item w:4 | \
             plate armour ego:death good_item w:4 | \
             sanguine talisman w:8 | sanguine talisman randart w:2 | \
             randbook numspells:2 spells:sublimation_of_blood w:20 | \
             randbook disc:necromancy w:9 | w:1 book of annihilations
SHUFFLE: ABCD
SUBST:   A = 1, B = Y, C : 1Y., D = .
: if you.in_branch("Depths") then
SUBST:   1 = 2
: end
MAP
xxxxx
xABCx
+DvD+
xCBAx
xxxxx
ENDMAP

#####################################################
# Sells only evil items.
NAME:   nicolae_evil_shop
TAGS:   transparent extra
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 | scale mail ego:death good_item w:5 | \
:   chain mail ego:death good_item w:4 | \
:   plate armour ego:death good_item w:5 | scroll of torment | \
:   staff of necromancy | book of necromancy | book of death | \
:   book of unlife | book of decay | book of the grave | \
:   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 | \
:   skull_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
TAGS:   no_monster_gen no_trap_gen transparent extra
DEPTH:  D:6-, Depths
WEIGHT: 2
NSUBST: s = 1: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") or you.depth() > 11 then
KFEAT: _ = altar_the_shining_one / altar_zin / altar_elyvilon
: end
KPROP: 1 = no_tele_into
KMASK: 1 = opaque
MONS: angel
MAP
nnn...
n1ns.s
nnn...
ENDMAP

#####################################################
# All bardings, all the time.
NAME: nicolae_barding_shop
TAGS: transparent
DEPTH: D:8-, Depths, Snake, !Snake:$
WEIGHT: 1
: 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
TAGS: no_monster_gen no_item_gen transparent extra
DEPTH: D:8-, Depths
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 air | book of annihilations | book of blasting | \
   book of conjurations | book of duality | book of fire | book of flames | \
   book of lightning | book of power | book of storms | \
   book of spectacle | randbook disc:conjuration | staff of conjuration | \
   wand of flame | wand of mindburst | any beam wand | any blast wand | \
   orb ego:stardust | orb ego:pyromania | lightning rod | phial of floods | \
   condenser vane | scroll of immolation | manual of conjurations | \
   manual of evocations
FTILE: ' = floor_rough_red
COLOUR: ' = red
MAP
  ...
 ..x..
..'''..
.x's'x.
..'''..
 ..x..
  ...
ENDMAP

#####################################################
# Contains only four items, associated with one of each of the four elemental
# schools. As time went on, the original setup with elemental-themed evokers
# stopped working out as well, so the items are now elemental-branded weapons,
# elemental-related rings, elemental staves, and elemental randbooks.
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 equip = {}
  if crawl.coinflip() then
    equip = {"any weapon ego:flaming", "any weapon ego:freezing",
             "any weapon ego:electrocution", "any weapon ego:heavy"}
  else
    equip = {"pair of gloves ego:fire", "helmet ego:ice",
             "cloak ego:air", "pair of boots ego:earth"}
  end
  local rings     = {"ring of protection from fire",
                     "ring of protection from cold", "ring of flight",
                     "ring of protection"}
  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 = equip[choices[1]] .. " | " .. rings[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:5 | \
   any magical staff randart w:5 | orb randart w:2 | any talisman randart w:2
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
TAGS:    no_pool_fixup no_descent extra
WEIGHT:  5
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 haste w:3 | \
           potion of invisibility w:8 | ring of flight w:5 | wand of digging w:4
KFEAT:   C = cache_of_fruit
SHUFFLE: Aa/Bb
SUBST:   Aa = t, B = ..t, b = ., C = CC.
MAP
  wwwwwwwww
 wwwwwwwwwww
 wwwwwwwwwww
 wwwwBABwwww
@wwwa...Awww
@wwwbCS>Bwww
@wwwa...Awww
 wwwwBABwwww
 wwwwwwwwwww
 wwwwwwwwwww
  wwwwwwwww
ENDMAP

# You can't eat the purple anymore. But you can drink it. Drink the purple.
NAME:  nicolae_transmutations_shop
TAGS:  transparent no_item_gen no_monster_gen extra
DEPTH: D:8-, Depths, Zot
KFEAT: S = general shop type:Changing suffix:Room count:9 ; \
           potion of mutation w:15 | potion of lignification w:15 | \
           wand of polymorph w:5 | amulet of wildshape | any talisman | \
           staff of alchemy | randbook disc:alchemy spells:irradiate w:6 | \
           randbook disc:alchemy spells:fulsome_fusillade w:6 | \
           plutonium_sword w:1 | manual of shapeshifting w:5 | \
           manual of alchemy w:5 | flux bauble w:5
: single_cloud(_G, "F", "mutagenic fog", true)
COLOUR: m = magenta
TILE:   m = dngn_transparent_wall_magenta
: vault_metal_statue_setup(_G, "G", "alchemical conduit")
MAP
.........
.mmmmmmm.
.mFFFFFm.
.G....Fm.
....S.Fm.
.G....Fm.
.mFFFFFm.
.mmmmmmm.
.........
ENDMAP

NAME:   doesnt_shop_hydraphobe
TAGS:   transparent no_pool_fixup extra
DEPTH:  D:5-11
WEIGHT: 5
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_grass_dark
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
: local d = "damaged ego:none"
: kfeat("S = general shop type:Lightly-Used suffix:Armoury ; " ..
:           "demon whip " .. d .. " | eveningstar " .. d .. " | " ..
:           "quick blade " .. d .. " | demon blade " .. d .. " | " ..
:           "double sword " .. d .. " | eveningstar " .. d .. " | " ..
:           "executioner's axe " .. d .. " | partisan " .. d .. " | " ..
:           "demon trident " .. d .. " | bardiche " .. d .. " | " ..
:           "lajatang " .. d .. " | hand cannon " .. d .. " | " ..
:           "triple crossbow " .. d .. " | longbow " .. d .. " | " ..
:           "crystal plate armour " .. d .. " | barding " .. d .. " | " ..
:           "pearl dragon scales " .. d .. " | " ..
:           "golden dragon scales " .. d)
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 | " ..
             "orb ego:pyromania w:5 | " ..
             "book of fire w:5 | book of ice w:5 | " ..
             "the unrestrained analects w:5 | any blast wand"

-- 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 ; \
        giant club ego:heavy w:20 | giant spiked club ego:heavy | \
        great mace ego:heavy | executioner's axe ego:heavy w:2 | \
        triple sword ego:heavy w:2 | bardiche ego:heavy w:5 | \
        triple crossbow ego:heavy w:5 | dark maul w:1 | sniper w:1 | \
        double sword ego:heavy | broad axe ego:heavy | \
        eveningstar ego:heavy w:5 | morningstar ego:heavy w:5 | \
        plate armour w:25 | crystal plate armour w:5 | tower shield w:15 | \
        book of the fortress w:15 | large rock w:25 | granite talisman w:15
MAP
S
ENDMAP

# top tier equipment for a single gold... if you're on zot:5
NAME:   hellmonk_bargain_basement
TAGS:   extra
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
KFEAT:  t = petrified_tree
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 extra
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 extra
DEPTH:  D:4-, Depths, Orc, Elf, Shoals, Snake, Vaults
KMONS:  DE = generate_awake 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 | scale mail ego:archery w:4 | \
        chain mail ego:archery w:4 | plate armour ego:archery w:4 | \
        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 extra
DEPTH:   D:4-, Depths, Orc, Elf, Shoals, Snake, Vaults
KFEAT:   S = general shop type:Gadget suffix:Gallery count:6 use_all ; \
         any wand | any wand | any wand | any wand | any misc | orb
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 extra
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 | any hex wand charges:18 | \
         wand of polymorph charges:18 | wand of mindburst charges:30 | \
         wand of flame charges:40 w:5
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 extra
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 extra
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 extra
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() > 12 then
KMONS:  D = fire dragon / ice dragon / swamp dragon
:else
KMONS:  D = steam dragon / acid dragon
:end
MAP
 xxx
xxll@
xl..lx
xlD.lx
xxllxx
 xxxx
ENDMAP

NAME:   monkooky_shop_mail_order
TAGS:   transparent extra
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 .. " ; " ..
             "ring mail w:5 | ring mail good_item | " ..
             "scale mail w:5 | scale mail good_item | " ..
             "chain mail w:5 | 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 extra
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", "partisan w:6", "demon trident w:3"}
local egos = {"chaos", "draining", "distortion", "electrocution",  "flaming",
              "freezing", "heavy", "speed", "spectral", "protection", "pain"}
local kstr = "S = general shop name:" .. name .. " type:Alliterative " ..
             "suffix:Armaments count:" .. count .. " ; dagger ego:devious | " ..
             scythe("speed") .. " | " .. scythe("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:     transparent no_item_gen extra
DEPTH:    D:4-, Depths
KITEM:    O = 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 protection from fire | staff of fire | wand of flame w:5 | \
          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:25 | fire dragon scales w:5 | \
          pair of gloves ego:fire w:5 | orb ego:pyromania
KFEAT:    C = c
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 }
TILE:     c = wall_stone_gray
TILE:     C = wall_stone_scorched
MAP
xxxCC@@ccxxx
xx''....ttxx
x''......ttx
x'O.V..T.Ptx
x''......ttx
xx''....ttxx
xxxCC@@ccxxx
ENDMAP

# Using a subvault so only these trees become dead trees.
# TODO: Fix this not working.
NAME:   nicolae_sub_dead_trees
TAGS:   unrand nico_deadtrees
SUBST:  t = tt.
COLOUR: t = brown
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, which is guaranteed
# to have an artefact property which doesn't normally generate, and also
# ordinary rings whose pluses have been set via vault syntax to something
# besides the default pluses for that type of ring.
# For the special randart, the available artprops are those that can go on rings
# and either have weight 0 for random generation (everything but MP), or have a
# preset value (MP+/-12) which we can exceed. For MP, the values go from
# +13 to +15 -- the low end is to exceed the max MP bonus of +12, the high end
# is a nice round multiple of 5. For HP, the values are +5 to +15, capped by the
# HP from the old Amulet of Vitality.
# 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 ) + 2
  local artprops = {"rMut", "Clar", "RMsl", "SH:5",
     "HP:" .. (crawl.roll_dice(10, 2) - 5),
     "MP:" .. (crawl.roll_dice(2, 2) + 11)}
  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 artprops:" ..
             util.random_from(artprops))
}}
MAP
  vvv..
 v...v..
v.....v.
v..P..b@
v.....v.
 v...v..
  vvv..
ENDMAP

NAME:   nicolae_shop_dragon_depot
TAGS:   transparent no_item_gen no_tide extra
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",
    "golden 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 extra
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
WEIGHT: 5
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
WEIGHT: 5
KFEAT:  S = book shop type:Tiny suffix:Tomes count:8 ; \
            any randbook numspells:2
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 extra
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",
   "athame", "scimitar", "great sword", "broad axe", "battleaxe", "glaive",
   "morningstar", "dire flail", "great mace", "trident", "arbalest", "bardiche",
   "executioner's axe", "eveningstar", "lajatang", "hand cannon",
   "triple crossbow", "partisan"}
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, Crypt), 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:8 ; orb w:5 | " ..
             "orb randart w:20 | manual of evocations w:1 | " ..
             "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
if not you.unrands("Charlatan's Orb") then
      kstr = kstr .. " | Charlatan's Orb 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 / thermic dynamo
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: + = .
FTILE: .123S = floor_crystal
: elseif you.in_branch("Crypt") then
MONS:  revenant soulmonger / 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 appropriateness, draconian scorcher, lich
: end
MAP
   ccccc
  ccccccc
 ccc212ccc
ccc.....ccc
cc3.....3cc
cc...S...cc
cc3.....3cc
ccc.....ccc
 ccc...ccc
  ccb+bcc
ENDMAP

# Wiglaf says his gran stitched his ever-iconic hat, so.
NAME:   mainiacjoe_granny_wiglaf_hat_shop
TAGS:   transparent no_monster_gen no_item_gen no_trap_gen extra
DEPTH:  Vaults, Crypt, Depths, Snake:$
WEIGHT: 5
KFEAT:  O = altar_okawaru
{{
local shopname = util.random_from({"type:Magnificent suffix:Millinery",
    "type:Humble suffix:Haberdashery", "type:Hat suffix:Hut"})
local cannon = crawl.coinflip()
local count = 5
if cannon then
    count = count + 1
end
local kstr = "S = armour shop name:Granny_Wiglaf " .. shopname ..
    " count:" .. count .. " greed:15 use_all no_mimic ; " ..
    " | hat randart tile:thelm_cap_jester" ..
    " | hat randart tile:thelm_hat_wizard"

local egos = util.random_subset({"intelligence", "see_invisible",
                                 "willpower", "sniping", "ice"}, 2)
kstr = kstr .. " | hat ego:" .. egos[1] .. " tile:thelm_cap | " ..
       "hat ego:" .. egos[2] .. " tile:thelm_hat_explorer2"

unrand_list = {"hat of the Bear Spirit", "crown of Dyrovepreva",
               "mask of the Dragon", "hat of the Alchemist",
               "hat of Pondering", "hood of the Assassin"}
possible_unrands = {}
for i, k in pairs(unrand_list) do
    if not you.unrands(k) then
        table.insert(possible_unrands, " | " .. k)
    end
end
if next(possible_unrands) == nil then
    kstr = kstr .. " | hat randart tile:thelm_hat_santa"
else
    kstr = kstr .. util.random_from(possible_unrands)
end

if cannon then
    kstr = kstr .. " | randbook owner:Granny_Wiglaf title:Secret_Sauce" ..
                   " numspells:1 spells:hellfire_mortar"
end
kfeat(kstr)
}}
FTILE:  .@O = floor_cobble_blood
MAP
    xxxxx
  xxx...xxx
 xx.......xx
 x....O....x
xx.........xx
x...x...x...x
@.xxx.S.xxx.@
xxx x...x xxx
    xxxxx
ENDMAP

# I realized there weren't any theme shops that were just themed around magic in
# general, combining magic-themed items from various item classes. Also gives
# the new conduit decorations a chance to shine.
# I just included all potions, scrolls, wands, and jewellery as magical by their
# very nature, so I wouldn't have to pick out specific different item types.
# 1/3 randbooks, 1/3 consumables, 1/4 gear, 1/12 magic manuals
NAME:  nicolae_shop_magical_conduits
TAGS:  transparent extra
DEPTH: D:6-, Depths, Elf, Snake, Shoals, Zot, !Zot:$
KFEAT: G = metal_statue
# The w:10 in the shop def is here for bug workaround purposes.
KFEAT: S = general shop type:Magical suffix:Supplies w:10 ; \
  randbook w:48 | any potion w:16 | any scroll w:16 | any wand w:16 | \
  orb w:6 | any magical staff w:6 | hat w:6 | robe w:6 | helmet ego:ice w:2 | \
  cloak ego:air w:2 | pair of gloves ego:fire w:2 | \
  pair of boots ego:earth w:2 | any ring w:6 | \
  any amulet w:6 | manual of spellcasting w:2 | manual of conjurations w:1 | \
  manual of hexes w:1 | manual of summonings w:1 | manual of necromancy w:1 | \
  manual of alchemy w:1 | manual of translocations w:1 | \
  manual of fire magic w:1 | manual of air magic w:1 | \
  manual of ice magic w:1 | manual of earth magic w:1
: local conduittype = {"arcane", "dimensional", "misfortune",
:   "soul", "fiery", "alchemical", "icy", "earthen", "storm"}
: local whichconduit = crawl.random2(#conduittype) + 1
: vault_metal_statue_setup(_G, "G", conduittype[whichconduit] .. " conduit")
MAP
 . .
G.S.G
 . .
ENDMAP

# Only in early D, since by later on you'd probably know what most things are,
# and then there's not much point to it being antique.
NAME:   nicolae_shop_antique_consumables
TAGS:   allow_dup transparent extra luniq
DEPTH:  D:2-8
KMONS:  P = pile of debris
KFEAT:  S = antiques shop type:Antique suffix:Scrolls ; any scroll / \
            antiques shop type:Antique suffix:Potions ; any potion
NSUBST: P = 1:. / 2:P / * = ...PP
MAP
cPcPc
P...P
c.S.c
P...P
cPcPc
ENDMAP

# In case you have some spare change and some open slots.
NAME:   nicolae_shop_hand_me_the_aux
TAGS:   transparent extra
DEPTH:  D:4-7
WEIGHT: 5
# Having duplicates of mundane aux armors is a little boring, so do some lua
# to get only one of each.
: local auxes = {"hat mundane", "helmet mundane", "pair of gloves mundane",
:   "cloak mundane", "pair of boots mundane", "barding mundane",
:   "buckler mundane"}
: local inventory = util.random_subset(auxes, 5)
: kfeat("S = armour shop type:Wardrobe suffix:Accessories count:5 use_all ; " ..
:   util.join(" | ", inventory))
KFEAT:  - = iron_grate
SUBST:  a : vv., p : v-., q : v-, r : v-., s : vv.
NSUBST: ` = 2:@ / .
MAP
   .`.
 vvs.avv
 vqr.pqv
.ap...rs.
`...S...`
.sr...pa.
 vqp.rqv
 vva.svv
   .`.
ENDMAP

NAME:  nicolae_shop_information_kiosk
TAGS:  transparent extra no_rotate no_vmirror no_pool_fixup
DEPTH: D:1-7
KFEAT: S = general shop type:Information suffix:Kiosk count:4 use_all ; \
           scroll of identify q:1 | scroll of identify q:2 | \
           scroll of revelation q:1 | scroll of revelation q:2
MAP
   ...
  .WWW.
 .WwSwW.
.WwwwwwW.
.WwwcwwW.
.WwwcwwW.
 .WwcwW.
  .WWW.
   ...
ENDMAP

# Thirteen years after the custom earth shop: the custom air shop.
NAME:  regret_index_shop_air
TAGS:  transparent no_monster_gen patrolling no_pool_fixup
DEPTH: D:6-, Shoals, Vaults, Elf, Depths
MONS:  steam dragon w:7 / sky beast / wyvern
MONS:  tengu warrior, tengu conjurer / harpy / deep elf zephyrmancer w:2
MONS:  wind drake / harpy w:14 / skyshark w:6
MONS:  ironbound thunderhulk / sphinx marauder / polterguardian
MONS:  deep elf zephyrmancer w:7 / air elemental / \
       dancing weapon ; scimitar ego:electrocution
MONS:  chonchon w:3 / spriggan air mage w:7 / spark wasp / storm dragon
{{
local inv = "steam dragon scales randart artprops:rElec w:15 | " ..
            "any weapon ego:electrocution w:65 | manual of air magic w:5 | " ..
            "book of air | book of the senses w:5 | book of lightning"
local low = "staff of air | storm dragon scales w:15 | cloak ego:air w:5 | " ..
            "eel talisman w:15 | parchment disc:air w:5 | " ..
            "trismegistus codex | book of storms"
local high = "staff of air randart | storm dragon scales good_item w:15 | " ..
             "cloak ego:air good_item w:4 | cloak randart ego:air w:1 | " ..
             "eel talisman randart w:5 | storm talisman | " ..
             "codex of conductivity | maxwell's memoranda"
if items.pickable("lightning rod") then
  inv = inv .. " | lightning rod w:15"
end
if items.pickable("condenser vane") then
  low = low .. " | condenser vane"
end

if you.in_branch("D") then
  if you.absdepth() < 9 then
    inv = inv .. " | " .. low
    nsubst("0 = 2:1 / 1:1. / *:.")
  elseif you.absdepth() < 12 then
    inv = inv .. " | " .. low
    nsubst("0 = 2:1 / 1:1. / *:.")
  else
    inv = inv .. " | " .. low .. " | " .. high
    nsubst("0 = 1:2 / 1:3 / 2 = 23. / *:.")
  end
elseif you.in_branch("Shoals") then
  inv = inv .. " | " .. low .. " | " .. high
  nsubst("0 = 2:4 / 2 = 4.. / *:.")
  subst("+ = W")
elseif you.in_branch("Vaults") then
  inv = inv .. " | " .. low .. " | " .. high
  nsubst("0 = 1:5 / 2 = 5.. / *:.")
elseif you.in_branch("Elf") then
  inv = inv .. " | " .. low .. " | " .. high .. " | " .. high
  nsubst("0 = 4:6 / *:6.")
else -- Depths
  inv = inv .. " | " .. high .. " | " .. high .. " | manual of air magic"
  nsubst("0 = 3:7 / 2 = 7. / *:.")
end

kfeat("S = general shop type:Acquisitions suffix:Aerie count:8 ; " .. inv)
}}
SUBST: G : GGw....
TILE:  v = dngn_metal_wall_cyan
: vault_metal_statue_setup(_G, "G", "storm conduit")
MAP
 .  .  .
.......v.
 .Gv+vv.
  vv00v
vvv0S0vvv
  v00vv
 .vv+vG.
.v.......
 .  .  .
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., 1 = 1:9 .:1
SUBST:   x : xc v:2 b:2
SHUFFLE: BC
FTILE:   @At = floor_moss
FTILE:   .1BCT = floor_sprouting_squares
# 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.
FTILE:   t = floor_moss
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.
: if you.in_branch("Orc") then
KMONS: t = fungus
: end
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_dark
MAP
.....................
.G..D..E..D..E..D..G.
.....................
.G.WWWWWWWWWWWWWWW.G.
...wwwwwwwwwwwwwww...
.G.WWWWWWWWWWWWWWW.G.
.....................
.G..F..H..F..H..F..G.
.....................
ENDMAP

# It's so old that the shop owners don't even know what they're selling anymore.
# 2-4 shops
NAME:   nicolae_shops_antique_district
TAGS:   transparent extra
DEPTH:  D:5-, Depths
KMONS:  1 = withered plant
KFEAT:  _ = altar_ecumenical
KFEAT:  ^ = web
KFEAT:  s = abandoned_shop
KFEAT:  S = antiques shop / antique weapon shop / antique armour shop
NSUBST: S = 2:S / 2:s / Ss
SUBST:  t = ttt`, ` = 111^````
COLOUR: t = brown
FTILE:  '`_V1sS^t = floor_pebble_darkgray
TILE:   t = dngn_tree_dead
: set_feature_name("tree", "dead tree")
MAP
xxxxxxxxxxxxx
xxxxxtStxxxxx
xxtSt'''tStxx
.```'```'```.
@`V`'`_`'`V`@
.```'```'```.
xxtSt'''tStxx
xxxxxtStxxxxx
xxxxxxxxxxxxx
ENDMAP

# Just 2 shops
NAME:  nicolae_shops_duplex
TAGS:  extra luniq_floating_shops transparent
DEPTH: D:4-, Depths, Elf
KFEAT: S = any shop
MAP
xxx.@.xxx
xcccncccx
xcT...Tcx
.c.cSc.c.
@..ccc..@
.c.cSc.c.
xcT...Tcx
xcccncccx
xxx.@.xxx
ENDMAP

# 2-4 shops
NAME:    nicolae_shops_little_town_plaza
TAGS:    extra luniq_floating_shops transparent
DEPTH:   D:4-, Depths, Elf
KFEAT:   p = general shop / antiques shop
KFEAT:   q = book shop
KFEAT:   r = distillery shop
KFEAT:   s = scroll shop
SHUFFLE: GT-/TG`
SUBST:   - = ., ` : x., G : GGt
SHUFFLE: xc
NSUBST:  S = p / q / rt / st
MAP
xx-G-xx
xS...Sx
-..T..-
G.TxT.G
-..T..-
xS...Sx
xx-G-xx
ENDMAP
