Skip to content
Allofich edited this page Apr 17, 2020 · 29 revisions

Weapons

Bows

The bow attack is possible every (256-pc.attr[SPEED])/16+4 frames.

Bashing

If the melee attack didn't affect any targets, and one of 8 neighboring threatened cells contain a chest or a door, the bashing is performed.

(to do)

Arrows and spells

The speed of arrows and spells is 100 units/frame. Two collision checks are made per frame, for 50 and 100 unit distance.

The arrows and spells exist for 30 frames.

The spell projectiles have a light radius of 500.

Armor class

The armor class is separate for each of 7 paperdoll slots. It is calculated as the sum of the corresponding item AC, shield AC if the shield covers the corresponding slot, and any AC-affecting items the (N)PC has equipped.

7-item byte arrays for each shield type are located @45159, @45160, @45168, and @4516F. If the corresponding element is non-zero, the shield AC is added.

Hit chance

Successful attacks break the invisibility for 20 frames.

if attacker.race in (REDGUARD, DARKELF, WOODELF) then
   racial <- attacker.level*256/100
else
   racial <- 0
endif

chance1 <- 128+((attacker.level-defender.level)*5)*256/100+(attacker.luckBonus-defender.luckBonus)+racial+(attacker.hitBonus-defender.defenceBonus)-defender.AC[slot]
chance2 <- player.level*256/100+51

return (rnd(256)<max(chance1,chance2))

Critical hit

Critical hit is an x3 multiplier. It's chances are:

  • Thieves: 2%/level if no ranged weapon equipped (ranged weapons include daggers for some reason)
  • Assassins: 3%/level
  • Monks: 3%/(level*2)
  • Archers: 3%/level if a ranged weapon equipped
  • Everyone else who has Critical hit: 1%/level, no ranged weapon.

Damage modifiers

Weapons

The damage total is calculated in the order of the steps shown here.:

  1. The base minimum and maximum damage is retrieved and a random value chosen from between them as the base damage. The random value is chosen from the minDamage .. (maxDamage - 1) range. (This is probably a bug.)

If a weapon is equipped, that weapon's min-max damage is used. If no weapon is equipped, damage depends on if and what kind of gauntlets are equipped. These min-max damage values are stored in pairs in a 3-word array @475FC.

  1. If there is a racial bonus it is added. (Redguards and Wood Elf bonus are probably reversed from what they were supposed to be):
  • Dark Elves: npc.level/4
  • Redguards: npc.level/3 if a ranged weapon is equipped (see above).
  • Wood Elves: npc.level/3 if no ranged weapon is equipped.
  1. The damage is multiplied by the critical hit multiplier (x1 if no critical hit).

  2. For rangers, their npc.level+1 is added to the damage if the target is not undead. (This is broken in the original game(see below).)

int ApplyRangerBonus(NPCDATA* npcData, int damage)
{
  if (npcData->Class == 0xe) // is a Ranger
  {
    // There are 2 bugs here. The player's status flags are checked instead of the opponent's, and IsUndead() is
    // passed the current damage total although it expects the enemy type ID.
    if ((npcData->StatusFlags & 0x1000) && IsUndead(damage)) // The 0x1000 flag means a creature (non-class) enemy. 
    {
      return damage; // No bonus.
    }
    damage = damage + (npcData->Level + 1);
  }
  return damage;
}

bool IsUndead(int creatureID)
{
  int i = 7;
  int index = 0;
  do {
    if ((UndeadCreatureIDs[index] == creatureID)
    {
      return true;
    }
    index++;
    i--;
  } while (i != 0);
  return false;
}

UndeadCreatureIDs are the seven from the list @47624.

  1. If the target is undead and the weapon is silver, the damage is doubled.

  2. The damage to the weapon is calculated and applied.

  3. If the target is a Skeleton and the weapon is in blade/axe/bow family, the damage to the target is halved.

  4. The damage to the target's armor is calculated and applied.

  5. If the weapon is Volendrung or Auriel's Bow, the damage to the target is tripled.

  6. If the weapon is Volendrung and the target is not a Knight, the target is paralyzed for 10 minutes (?), and the weapon's health is decreased by 800.

  7. The damage is subtracted from the target's health.

  8. If the weapon is the Ebony Blade, half of the damage applied to the target is added to the player's health.

Material resistance

  • Golems are resistant to materials below ELVEN + (race - ICEGOLEM).
  • Fire demons and higher monsters are resistant to materials given in the 4-element array @4762B.
  • Vampires are also not resistant to silver.

Successful material resistance is equivalent to a miss.

Item degradation

itm <- defender.equipped[SHIELD]
if itm and not shieldHasAC(itm, slot) then itm <- none
if not itm then itm <- defender.equipped[slot]
if itm then
   dmg <- (damage * materialStrength[itm.material] + 50) / 100
   if itm.isArtifact then dmg <- dmg / 2
   itm.damage(dmg)
endif

From bashing

dmg <- damage
if itm.isArtifact then dmg <- dmg / 2
itm.damage(dmg)
Clone this wiki locally