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

Unarmored damage depends on the equipped gauntlets type. It is stored in pairs are 6-byte array @475FC.

The primary damage lies in the minDamage .. (maxDamage - 1) range. (That is probably a bug.)

If a weapon is equipped, a racial bonus is added:

  • Dark elves: npc.level/4
  • Redguards: npc.level/3 if a ranged weapon equipped (see above). (That is probably a bug.)
  • Wood elves: npc.level/3 if no ranged weapon equipped.

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

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.

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

The damage at this point is used to calculate the weapon degradation.

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

The damage at this point is used to calculate the target's armor degradation.

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

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.

If the weapon is Ebony Blade, the half of the damage is added to the player.

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