Module:Monsters: Difference between revisions

Added a getMaxHit function
(Making things as clear as possible Spiders)
(Added a getMaxHit function)
Line 5: Line 5:
local AreaData = mw.loadData('Module:CombatAreas/data')
local AreaData = mw.loadData('Module:CombatAreas/data')


local Magic = require('Module:Magic')
local Shared = require('Module:Shared')
local Shared = require('Module:Shared')
local Icons = require('Module:Icons')
local Icons = require('Module:Icons')
Line 16: Line 17:
   end
   end


   for i, monster in pairs(MonsterData) do
   for i, monster in pairs(MonsterData.Monsters) do
     if(monster.name == name) then
     if(monster.name == name) then
       result = Shared.clone(monster)
       result = Shared.clone(monster)
Line 28: Line 29:
function p.getMonsterByID(ID)
function p.getMonsterByID(ID)
   local result = nil
   local result = nil
   for i, monster in pairs(MonsterData) do
   for i, monster in pairs(MonsterData.Monsters) do
     if(monster.id == ID) then
     if(monster.id == ID) then
       result = Shared.clone(monster)
       result = Shared.clone(monster)
    end
  end
  return result
end
function p.getSpecialAttack(name)
  local result = nil
  for i, attack in pairs(MonsterData.SpecialAttacks) do
    if(attack.name == name) then
      result = Shared.clone(attack)
      --Make sure every monster has an ID, and account for the 1-based indexing of Lua
      result.id = i - 1
    end
  end
  return result
end
function p.getSpecialAttackByID(ID)
  local result = nil
  for i, attack in pairs(MonsterData.SpecialAttacks) do
    if attack.id == ID then
      result = Shared.clone(attack)
     end
     end
   end
   end
Line 40: Line 64:
   local StatName = frame.args ~= nil and frame.args[2] or frame[2]
   local StatName = frame.args ~= nil and frame.args[2] or frame[2]
   local monster = p.getMonster(MonsterName)
   local monster = p.getMonster(MonsterName)
   if monster ~= nil then
   if monster == nil then
    return monster[StatName]
  else
     return "ERROR: No monster with that name found"
     return "ERROR: No monster with that name found"
   end
   end
  if StatName == 'HP' then
    return p.getMonsterHP(MonsterName)
  elseif StatName == 'maxHit' then
    return p.getMonsterMaxHit(MonsterName)
  elseif StatName == 'accuracyRating' then
    return p.getMonsterAR(MonsterName)
  elseif StatName == 'meleeEvasionRating' then
    return p.getMonsterER({MonsterName, 'Melee'})
  elseif StatName == 'rangedEvasionRating' then
    return p.getMonsterER({MonsterName, 'Ranged'})
  elseif StatName == 'magicEvasionRating' then
    return p.getMonsterER({MonsterName, 'Magic'})
  end
  return monster[StatName]
end
end


function p.getMonsterHP(frame)
function p.getMonsterHP(frame)
   local MonsterName = frame.args[1]
   local MonsterName = frame.args ~= nil and frame.args[1] or frame
   local monster = p.getMonster(MonsterName)
   local monster = p.getMonster(MonsterName)
   if monster ~= nil then
   if monster ~= nil then
Line 68: Line 106:


function p.getMonsterCombatLevel(frame)
function p.getMonsterCombatLevel(frame)
   local MonsterName = frame.args[1]
   local MonsterName = frame.args ~= nil and frame.args[1] or frame
   local monster = p.getMonster(MonsterName)
   local monster = p.getMonster(MonsterName)


Line 89: Line 127:


function p.getMonsterAR(frame)
function p.getMonsterAR(frame)
   local MonsterName = frame.args[1]
   local MonsterName = frame.args ~= nil and frame.args[1] or frame
   local monster = p.getMonster(MonsterName)
   local monster = p.getMonster(MonsterName)


Line 115: Line 153:


function p.getMonsterER(frame)
function p.getMonsterER(frame)
   local MonsterName = frame.args[1]
   local args = frame.args ~= nil and frame.args or frame
   local style = frame.args[2]
  local MonsterName = args[1]
   local style = args[2]
   local monster = p.getMonster(MonsterName)
   local monster = p.getMonster(MonsterName)


Line 168: Line 207:
   end
   end
   return result
   return result
end
function p.getMonsterMaxHit(frame)
  local MonsterName = frame.args ~= nil and frame.args[1] or frame
  local monster = p.getMonster(MonsterName)
  if monster == nil then
    return "ERROR: No monster with that name found"
  end
  local normalChance = 100
  local specialMaxHit = 0
  local normalMaxHit = p.getMonsterBaseMaxHit(frame)
  if monster.hasSpecialAttack then
    for i, specID in pairs(monster.specialAttackID) do
      local specAttack = p.getSpecialAttackByID(specID)
      if monster.overrideSpecialChances ~= nil then
        normalChance = normalChance - monster.overrideSpecialChances[i]
      else
        normalChance = normalChance - specAttack.chance
      end
      local thisMax = 0
      if specAttack.setDamage ~= nil then
        thisMax = specAttack.setDamage * 10
      else
        thisMax = normalMaxHit
      end
      if thisMax > specialMaxHit then specialMaxHit = thisMax end
    end
  end
  --Ensure that if the monster never does a normal attack, the normal max hit is irrelevant
  if normalChance == 0 then normalMaxHit = 0 end
  return math.max(specialMaxHit, normalMaxHit)
end
function p.getMonsterBaseMaxHit(frame)
  local MonsterName = frame.args ~= nil and frame.args[1] or frame
  local monster = p.getMonster(MonsterName)
  if monster == nil then
    return "ERROR: No monster with that name found"
  end
 
  local effStrLvl = 0
  local strBonus = 0
  if monster.attackType == Constants.attackType.Melee then
    effStrLvl = monster.strengthLevel + 9
    strBonus = monster.strengthBonus
  elseif monster.attackType == Constants.attackType.Ranged then
    effStrLvl = monster.rangedLevel + 9
    strBonus = monster.strengthBonusRanged
  elseif monster.attackType == Constants.attackType.Magic then
    local mSpell = nil
    if monster.selectedSpell ~= nil then Magic.getSpellByID(monster.selectedSpell) end
    if mSpell == nil then
      return math.floor(10 * monster.setMaxHit + (monster.setMaxHit * monster.damageBonusMagic / 100))
    else
      mw.logObject(mSpell)
      return math.floor(10 * mSpell.maxHit + (mSpell.maxHit * monster.damageBonusMagic / 100))
    end
  else
    return "ERROR: This monster has an invalid attack type somehow"
  end
  --Should only get here for Melee/Ranged, which use functionally the same damage formula
  return math.floor(10 * (1.3 + (effStrLvl/10) + (strBonus / 80) + ((effStrLvl * strBonus) / 640)))
end
end


return p
return p