Skip to content
Carmina16 edited this page May 11, 2018 · 27 revisions

General notes

The sprite size formula:

# mul2 == mul3 == 160
# scale2 == 200
# var3 == ???

baseH <- ((sprite.H * obj.Scale)/256*scale2)/256
baseW <- (sprite.W * obj.Scale)/256

pX,pY <- project(obj.X-camera.X,obj.Y-camera.Y)
if pY<=20 then return
pX <- pX + var3

WW <- (baseW*mul2)/pY
HH <- (baseH*mul3)/pY

XX <- (pX*mul2)/pY + centerX - WW/2
YY <- (((sprite.Z+camera.Z)-baseH)*mul3)/pY + centerY

Monsters

The monster races are 1-based. The lists below are indexed by race - 1. There are 24 different monster types.

  • Names: szlist @3A8EE
  • Level: byte array @42096 (zero-based, as with the player)
  • Hit points: 48-entry WORD array @420DE (min, max format)
  • Base experience: DWORD array @4213E.
  • Experience multiplier: byte array @4219E
  • Sound: byte array @4201E. An index into the VOC szlist @437CD
  • Damage: 48-entry byte array @421B6 (min, max format)
  • Magical effects: WORD array @420AE (these go into the NPC's ActiveEffects)
  • Scale: WORD array @42066 (in 1/256s, 0 = 100%)
  • Y offset: signed byte array @42036
  • Has no corpse: byte array @4204E
  • Blood: byte array @4762F (index into animation list @42EFC)
  • Disease chance: signed byte array @42212. Negative values have special meaning.

TODO: spells and regeneration

Creature experience is calculated as baseExperience + maxHP * experienceMultiplier.

  • Animation: @4222B. Monsters have a special 3-frame death animation at the index 5 (...6).
00..05  walk
06..07  look around (a special sequence of 6, 0, 7, 0)
08..11  attack (damage is done  in the frame 10)

Humanoids

Humanoids have an animation combined of walk and attack part. The attack part is also overlaid with a weapon animation, when applicable.

  • If an NPC has a cuirass, or at least 3 other items, of a certain armor type, that type is used for the sprite (indices 0..2)
  • Otherwise, it is 3
  • For spellcasters, it is 4, for Monks 5, and for Barbarians 6.

The sprite type array is located @45D20.

  • The weapon index is 0 to 2 for swords, axes, and maces correspondingly.
  • If the sprite index was 0, weapon index increases by 3, if 6 by 6.

A female variant is not selected for the plate armor sprite (index 0).

The weapon sprite array is located @45D97

  • For monks and mages, the special attack animations are used, MNKKIC, MAGSWD, and MAGSTF.

Humanoids do not have the death animation, they are replaced with a 'corpse' sprite (ITEM 2).

Townsfolk

Townsfolk do not have NPC properties. They are dying with a single hit, yielding 1..4 gold and corresponding message.

Male sprites (@4559A) are chosen by the tileset. Special female sprites are chosen for the desert tileset (FMGEND) and snow/snow overcast weather (FMGENW).

Color transformation

For clothing transformation, the random value Data & 0x7fff is used. colorBase is a byte array @47096.

val <- seed
for i <- 0, 16
   flag <- val & 0x8000
   val <- ror16(val)
   if flag then
      block <- val & 0xF
      dest <- colorBase[i]
      if dest == 128 and block == 11 then continue  # no green hair
      src <- colorBase[block]
      for j <- 0, 10
         new[src+j] <- old[dest+j]

For skin transformation, the following values are used:

  • Bretons, Nords, Wood Elves, Khajiits - no transformation
  • Dark Elves - 52
  • High Elves - 192
  • Argonians - 116
  • Everyone else - 148

skinColor is a byte array @470A6.

for i <- 0, 10
   new[skinColor[i]] <- old[VAL+i]
Clone this wiki locally