Skip to content
Carmina16 edited this page Apr 12, 2018 · 4 revisions

Dungeon loot

Loot zones

0  Generic
1  Palace (not available)
2  Nobles' houses
3  Dungeons
4  Towers and Crypts
5  Wilderness (unused?)

Each zone type corresponds to an item in the DWORD array @44150. Those are chances for generating a particular class of loot.

Loot generation

The maximum number of loot heaps is max(len(level.targets), 1).

Generating a particular heap (same algorithm for preplaced heaps in the MQ dungeons, mutatis mutandis):

chance <- chances[zoneType]
classes <- []
for i <- 0, 3
   if rnd() < <i-th byte in chance> then classes.append(True) else classes.append(False)
do
   id <- rnd() mod len(level.targets)
while id in seen
seen.append(id)
coord <- level.targets[id].pos
if classes[0] then lootitem <- generateGold()
addLootItem(currentFloor, coord, lootitem)
if classes[1] then lootitem <- generateMagicPotion()
if lootitem then addLootItem(currentFloor, coord, lootitem)
if classes[2] then lootitem <- generateArmorWeapon()
addLootItem(currentFloor, coord, lootitem)
if classes[3] then lootitem <- generateMagicArmorWeapon()
addLootItem(currentFloor, coord, lootitem)

Loot items are a combination of an inventory item, an amount of gold, associated with a certain floor and coordinates.

generateGold() <-
   a <- 1
   if zoneType == 0 or zoneType ==2 then
      a <- rnd(2, 11)
      if cityType == 0 then a <- a * 2
      if cityType == 2 then a <- a / 2
      if zoneType == 2 then a <- a * 10
   else if zoneType >= 3 then
      a <- rnd(1, 101) + currentFloor * currentFloor
   return a

getQuality() <- 
   if zoneType == 0 then return rnd(1, 6) # 1..5
   else if zoneType == 2 then return rnd(2, 11)
   else if zoneType == 3 then return ( currentFloor + 1 ) * 5
   else return ( currentFloor + 1 ) * 3

generateMagicPotion <-
   q <- getQuality()
   if getRandomSeed() & 1 then
      if q >= 3 then
         return generateMagicItem(q)
      endif
   else
      return generateRandomPotion() # 0..14
   endif
   return null

The magic items and potions generated in this way are unidentified.

generateArmorWeapon() <-
   rnd()
   q <- 16
   if rnd() & 1 then
      item <- generateArmor(q, slot=any, type=any)
   else
      item <- generateWeapon(q, slot=any)
   endif
   good <- condBool[zoneType]
   if good then
      idx <- rnd(1, 4)
      if idx == 3 then idx <- 2
   else
      idx <- rnd(3)
   endif
   cond <- condPct[idx]
   item.health <- (item.maxHealth * 100) / cond
   return item

condBool is a byte array @44164. condPct is a 3-item byte array @44169.

generateMagicArmorWeapon() <-
   rnd()
   q <- 16
   if rnd() & 1 then
      item <- generateMagicWeapon(q, slot=Any)
   else
      item <- generateMagicArmor(q, slot=Any)
   endif
   return item

generateMagicWeapon(q, slot) <-
   if slot != Any then
      q <- 20
      if weaponQuality[slot] < q then slot <- Any
   endif
   if slot == Any then
      do
         slot <- rnd() mod 18
      while weaponQuality[slot] < q
   endif
   item <- generateWeapon(q, slot=slot)
   item.hash <- 10 + slot
   v <- rnd(1,11)
   for i <- 0, 3
      if enchChance[i] > v then break
   if i == 0 then addWeapMaterial(item)
   else if i == 1 then addItemEnchantment(item, q)
   else addWeapMatEnch(item, q)
   return item

addWeapMaterial(item) <-
   v <- rnd(1,100)
   for i <- 0, 8
      if matChance[i] > v then break
   item.hash <- item.hash + 10 + i
   item.material <- i
   item.price <- max((item.price*matPriceMult[i])/4, 1)
   if i > 0 then
      item.minDamage <- item.minDamage + matBonus[i]/5
      item.maxDamage <- item.maxDamage + matBonus[i]/5
   else # iron
      item.maxDamage <- item.maxDamage - 2
   endif

addItemEnchantment(item, quality, withMat=False) <- 
   if not withMat then item.hash <- item.hash + 20
   if item.class == Armor then 
      qa <- magicArmorQualities
      pa <- magicArmorPrice
      sa <- magicArmorSpells
   else
      qa <- magicWeaponQualities
      pa <- magicWeaponPrice
      sa <- magicWeaponSpells
   endif
   do
      i <- rnd() mod 14
   while qa[i] > quality
   item.hash <- item.hash + i
   item.price <- pa[i]
   if sa[i] == 255 then
      item.attribute <- i
   else
      item.spell <- sa[i]

Loot flat selection

if classes[0] and not (classes[1] or classes[2] or classes[3]) then
   it <- 3
else
   it <- rnd(4, 7)
endif

Creature loot

The monster loot chances are stored in a DWORD array @3b135.

  • The gold is calculated as rnd(1,11) * (mon.level + 1)
  • The quality value for various item generation is mon.level + 1

Magic item generation

Clone this wiki locally