• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Monster Melee attack

bomba

Member
Joined
Feb 26, 2008
Messages
635
Reaction score
7
Location
Brazil
I created a melee basic attack spell to a rat.
But the damage is not calculated from the script.
For the rat damage to someone, I need to configure in the monster file.
And it is not the intention. :(

Script:
Code:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
setCombatParam(combat, COMBAT_PARAM_BLOCKARMOR, true)
setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_HITAREA)

function onGetFormulaValues(cid, level, skill, attack, factor)
  local attack =
  {
  balance = 5,
  weapon = 7,
  skill = 10
  } -- Max 7,5
    if getPlayerStorageValue(getCreatureTarget(cid), DAMAGE_REDUCTION) >= 1 then
      return -(((attack.balance*attack.weapon*attack.skill)/200)/getPlayerStorageValue(getCreatureTarget(cid), DAMAGE_REDUCTION)), -(((attack.balance*attack.weapon*attack.skill)/100)/getPlayerStorageValue(getCreatureTarget(cid), DAMAGE_REDUCTION))
    else
      return -((attack.balance*attack.weapon*attack.skill)/200), -((attack.balance*attack.weapon*attack.skill)/100)
    end
end

setCombatCallback(combat, CALLBACK_PARAM_SKILLVALUE, "onGetFormulaValues")

function onCastSpell(cid, var)
    if isPlayer(cid) == false then
      return doCombat(cid, combat, var)
    else
      return false
    end
end

If the rat.xml is:
Code:
    <attacks>
        <attack name="Rat" interval="2000" min="-1" max="-7" chance="100" range="1">
        </attack>
    </attacks>
The hit is min="-1" and max="-7"

But if the rat.xml is:
Code:
    <attacks>
        <attack name="Rat" interval="2000" chance="100" range="1">
        </attack>
    </attacks>
The rat can't hit :eek:
Why?
 
Monster damage doesn't use the formulas for combats.

Here is how I would do it:
Code:
function onCastSpell(cid, var)
   local attack =   {balance = 5,weapon = 7,skill = 10} -- Max 7,5
   local min = 0
   local max = 0
   local target = getCreatureTarget(cid)
   if isMonster(cid) and isCreature(target) then
     if getPlayerStorageValue(target, DAMAGE_REDUCTION) >= 1 then
       min = -(((attack.balance*attack.weapon*attack.skill)/200)/getPlayerStorageValue(target, DAMAGE_REDUCTION))
       max = -(((attack.balance*attack.weapon*attack.skill)/100)/getPlayerStorageValue(target, DAMAGE_REDUCTION))
     else
       min = -((attack.balance*attack.weapon*attack.skill)/200)
       max = -((attack.balance*attack.weapon*attack.skill)/100)
     end
     doTargetCombatHealth(cid, target, COMBAT_PHYSICALDAMAGE, min, max, CONST_ME_HITAREA)
   end
end

The only difference is armor and shields will not block the damage.
Now if you want your damage reduction script to work AND block armor and shield then you'll have to do:

Code:
<attacks>
<attack name="melee" interval="2000" chance="100" min="-1" max="-10">
</attack>
</attacks>

Then add a "onStatsChange" creaturescript for your players:

Code:
function onStatsChange(cid, attacker, type, combat, value)
   if type == 1 and combat == COMBAT_PHYSICALDAMAGE then
     if getPlayerStorageValue(target, DAMAGE_REDUCTION) >= 1 then
       value = value/getPlayerStorageValue(target, DAMAGE_REDUCTION)
       doTargetCombatHealth(attacker, cid, COMBAT_MELEEDAMAGE, value, value, CONST_ME_HITAREA)
     end
   end
   return true
end

There you go, 2 ways to do it.
 
Nice idea!
I modified to try block:
Code:
function onCastSpell(cid, var)
  local attack =
  {
  balance = 5,
  weapon = 7,
  skill = 10
  } -- Max 7,5

  local min = 0
  local max = 0
  local target = getCreatureTarget(cid)
  local get = target
    if isMonster(cid) and isCreature(target) then
        if getPlayerStorageValue(target, DAMAGE_REDUCTION) >= 1 then
          local formulaMinR = -((attack.balance*attack.weapon*attack.skill)/200)/getPlayerStorageValue(target, DAMAGE_REDUCTION)
          local formulaMaxR = -((attack.balance*attack.weapon*attack.skill)/100)/getPlayerStorageValue(target, DAMAGE_REDUCTION)
          min = ((formulaMinR) - (BLOCK))
          max = ((formulaMaxR) - (BLOCK))
        else
          local formulaMin = -((attack.balance*attack.weapon*attack.skill)/200))
          local formulaMax = -((attack.balance*attack.weapon*attack.skill)/100))
          min = ((formulaMin) - (BLOCK))
          max = ((formulaMax) - (BLOCK))
        end
      doTargetCombatHealth(cid, target, COMBAT_PHYSICALDAMAGE, min, max, CONST_ME_HITAREA)
    end
end

And I have a new idea to make armor and defense block...
Need help to the functions:
Code:
BLOCK = ((getPlayerArmor(get)*1.2)+(getPlayerDefense(get)*1.4)+(getPlayerSkill(get, SKILL_SHIELD)*1.6))

function getPlayerDefense(get)
  itemDef = ALL_EQUIPED_ITEM_WITH_DEF
  itemExtraDef = ALL_EXTRA_DEF_OF_ITEMS_EQUIPED
  return (getItemDefense(itemDef.uid)+getItemExtraDefense(itemExtraDef.uid))
end

function getPlayerArmor(get)
  itemArm = ALL_EQUIPED_ITEM_WITH_ARMOR
  return getItemArmor(itemArm.uid)
end
 
Last edited:
Nice idea!
I modified to try block:
Code:
function onCastSpell(cid, var)
  local attack =
  {
  balance = 5,
  weapon = 7,
  skill = 10
  } -- Max 7,5

  local min = 0
  local max = 0
  local target = getCreatureTarget(cid)
  local get = target
    if isMonster(cid) and isCreature(target) then
        if getPlayerStorageValue(target, DAMAGE_REDUCTION) >= 1 then
          local formulaMinR = -((attack.balance*attack.weapon*attack.skill)/200)/getPlayerStorageValue(target, DAMAGE_REDUCTION)
          local formulaMaxR = -((attack.balance*attack.weapon*attack.skill)/100)/getPlayerStorageValue(target, DAMAGE_REDUCTION)
          min = ((formulaMinR) - (BLOCK))
          max = ((formulaMaxR) - (BLOCK))
        else
          local formulaMin = -((attack.balance*attack.weapon*attack.skill)/200))
          local formulaMax = -((attack.balance*attack.weapon*attack.skill)/100))
          min = ((formulaMin) - (BLOCK))
          max = ((formulaMax) - (BLOCK))
        end
      doTargetCombatHealth(cid, target, COMBAT_PHYSICALDAMAGE, min, max, CONST_ME_HITAREA)
    end
end

And I have a new idea to make armor and defense block...
Need help to the functions:
Code:
BLOCK = ((getPlayerArmor(get)*1.2)+(getPlayerDefense(get)*1.4)+(getPlayerSkill(get, SKILL_SHIELD)*1.6))

function getPlayerDefense(get)
  itemDef = ALL_EQUIPED_ITEM_WITH_DEF
  itemExtraDef = ALL_EXTRA_DEF_OF_ITEMS_EQUIPED
  return (getItemDefense(itemDef.uid)+getItemExtraDefense(itemExtraDef.uid))
end

function getPlayerArmor(get)
  itemArm = ALL_EQUIPED_ITEM_WITH_ARMOR
  return getItemArmor(itemArm.uid)
end


Here are your functions completed (I haven't tested them so let me know if they work)
Code:
function getPlayerDefense(get)
  local defenseTotal = 0
  for a = 1, 10 do
    local item = getPlayerSlotItem(get, slot)
    if item then
      local defense = getItemAttribute(item.uid, "defense")
      if defense then
        defenseTotal = defenseTotal + defense
      end
      defense = getItemAttribute(item.uid, "extradefense")
      if defense then
        defenseTotal = defenseTotal + defense
      end
    end
  end
  return defenseTotal
end

function getPlayerArmor(get)
  local armorTotal = 0
  for a = 1, 10 do
    local item = getPlayerSlotItem(get, slot)
    if item then
      local armor= getItemAttribute(item.uid, "armor")
      if armorthen
        armorTotal = armorTotal + armor
      end
    end
  end
  return armorTotal
end
 
rmjlhw.png


lib:
Code:
function getPlayerDefense(get)
  local defenseTotal = 0
  for a = 1, 10 do
    local item = getPlayerSlotItem(get, slot)
    if item then
      local defense = getItemAttribute(item.uid, "defense")
      if defense then
        defenseTotal = defenseTotal + defense
      end
      defense = getItemAttribute(item.uid, "extradefense")
      if defense then
        defenseTotal = defenseTotal + defense
      end
    end
  end
  return defenseTotal
end

function getPlayerArmor(get)
  local armorTotal = 0
  for a = 1, 10 do
    local item = getPlayerSlotItem(get, slot)
    if item then
      local armor= getItemAttribute(item.uid, "armor")
      if armor then
        armorTotal = armorTotal + armor
      end
    end
  end
  return armorTotal
end

spell:
Code:
function onCastSpell(cid, var)
  local BLOCK = ((getPlayerArmor(target)*1.4)+(getPlayerDefense(target)*1.6)+(getPlayerSkill(target, SKILL_SHIELD)*1.8))
  local attack =
  {
  balance = 5,
  weapon = 7,
  skill = 10
  } -- Max 7,5

  local min = 0
  local max = 0
  local target = getCreatureTarget(cid)
  local get = target
    if isMonster(cid) and isCreature(target) then
        if getPlayerStorageValue(target, DAMAGE_REDUCTION) >= 1 then
          local formulaMinR = -((attack.balance*attack.weapon*attack.skill)/200)/getPlayerStorageValue(target, DAMAGE_REDUCTION)
          local formulaMaxR = -((attack.balance*attack.weapon*attack.skill)/100)/getPlayerStorageValue(target, DAMAGE_REDUCTION)
          min = ((formulaMinR) - (BLOCK))
          max = ((formulaMaxR) - (BLOCK))
        else
          local formulaMin = -((attack.balance*attack.weapon*attack.skill)/200)
          local formulaMax = -((attack.balance*attack.weapon*attack.skill)/100)
          min = ((formulaMin) - (BLOCK))
          max = ((formulaMax) - (BLOCK))
        end
      doTargetCombatHealth(cid, target, COMBAT_PHYSICALDAMAGE, min, max, CONST_ME_HITAREA)
    end
end
 
Now I edited the script to:
Code:
function onCastSpell(cid, var)
  local attack =
{
  balance = 5,
  weapon = 7,
  skill = 10
} -- Max 7,5

  local min = 0
  local max = 0
  local target = getCreatureTarget(cid)
  local BLOCK = ((getPlayerArmor(target)*1.4)+(getPlayerDefense(target)*1.6)+(getPlayerSkill(target, SKILL_SHIELD)*1.8))
  local get = target
    if isMonster(cid) and isCreature(target) then
        if getPlayerStorageValue(target, DAMAGE_REDUCTION) >= 1 then
          local formulaMinR = -((attack.balance*attack.weapon*attack.skill)/200)/getPlayerStorageValue(target, DAMAGE_REDUCTION)
          local formulaMaxR = -((attack.balance*attack.weapon*attack.skill)/100)/getPlayerStorageValue(target, DAMAGE_REDUCTION)
          min = ((formulaMinR) - (BLOCK))
          max = ((formulaMaxR) - (BLOCK))
        else
          local formulaMin = -((attack.balance*attack.weapon*attack.skill)/200)
          local formulaMax = -((attack.balance*attack.weapon*attack.skill)/100)
          min = ((formulaMin) - (BLOCK))
          max = ((formulaMax) - (BLOCK))
        end
      doTargetCombatHealth(cid, target, COMBAT_PHYSICALDAMAGE, min, max, CONST_ME_HITAREA)
    end
end

and now the error is only "item not found"
 
Libs:
Code:
function getCreatureTotalArmor(cid)
    local armor, it = 0, {}
    for i = 1, 10 do
        it[i] = getPlayerSlotItem(cid, i)
        if it[i].itemid ~= 0 and getItemArmor(it[i].uid) ~= nil then
            armor = armor + getItemArmor(it[i].uid)
        end
    end
    return armor
end

function getCreatureTotalDefense(cid)
    local defense, it = 0, {}
    for i = 1, 10 do
        it[i] = getPlayerSlotItem(cid, i)
        if it[i].itemid ~= 0 and getItemDefense(it[i].uid) ~= nil then
            defense = defense + getItemDefense(it[i].uid)
        end
    end
    return defense
end
 
Error:
2ikv1bm.jpg


Script:
Code:
function onCastSpell(cid, var)
  local attack =
{
  balance = 5,
  weapon = 7,
  skill = 10
} -- Max 7,5

  local min = 0
  local max = 0
  local target = getCreatureTarget(cid)
  local BLOCK = ((getCreatureTotalArmor(target)*1.4)+(getCreatureTotalDefense(target)*1.6)+(getPlayerSkill(target, SKILL_SHIELD)*1.8))
  local get = target
    if isMonster(cid) and isCreature(target) then
        if getPlayerStorageValue(target, DAMAGE_REDUCTION) >= 1 then
          local formulaMinR = -((attack.balance*attack.weapon*attack.skill)/200)/getPlayerStorageValue(target, DAMAGE_REDUCTION)
          local formulaMaxR = -((attack.balance*attack.weapon*attack.skill)/100)/getPlayerStorageValue(target, DAMAGE_REDUCTION)
          min = ((formulaMinR) - (BLOCK))
          max = ((formulaMaxR) - (BLOCK))
        else
          local formulaMin = -((attack.balance*attack.weapon*attack.skill)/200)
          local formulaMax = -((attack.balance*attack.weapon*attack.skill)/100)
          min = ((formulaMin) - (BLOCK))
          max = ((formulaMax) - (BLOCK))
        end
      doTargetCombatHealth(cid, target, COMBAT_PHYSICALDAMAGE, min, max, CONST_ME_HITAREA)
    end
end

Libs:
Code:
function getCreatureTotalArmor(cid)
    local armor, it = 0, {}
    for i = 1, 10 do
        it[i] = getPlayerSlotItem(cid, i)
        if it[i].itemid ~= 0 and getItemArmor(it[i].uid) ~= nil then
            armor = armor + getItemArmor(it[i].uid)
        end
    end
    return armor
end

function getCreatureTotalDefense(cid)
    local defense, it = 0, {}
    for i = 1, 10 do
        it[i] = getPlayerSlotItem(cid, i)
        if it[i].itemid ~= 0 and getItemDefense(it[i].uid) ~= nil then
            defense = defense + getItemDefense(it[i].uid)
        end
    end
    return defense
end
 
Monster damage doesn't use the formulas for combats.

Here is how I would do it:
Code:
function onCastSpell(cid, var)
   local attack =   {balance = 5,weapon = 7,skill = 10} -- Max 7,5
   local min = 0
   local max = 0
   local target = getCreatureTarget(cid)
   if isMonster(cid) and isCreature(target) then
     if getPlayerStorageValue(target, DAMAGE_REDUCTION) >= 1 then
       min = -(((attack.balance*attack.weapon*attack.skill)/200)/getPlayerStorageValue(target, DAMAGE_REDUCTION))
       max = -(((attack.balance*attack.weapon*attack.skill)/100)/getPlayerStorageValue(target, DAMAGE_REDUCTION))
     else
       min = -((attack.balance*attack.weapon*attack.skill)/200)
       max = -((attack.balance*attack.weapon*attack.skill)/100)
     end
     doTargetCombatHealth(cid, target, COMBAT_PHYSICALDAMAGE, min, max, CONST_ME_HITAREA)
   end
end

The only difference is armor and shields will not block the damage.
Now if you want your damage reduction script to work AND block armor and shield then you'll have to do:

Code:
<attacks>
<attack name="melee" interval="2000" chance="100" min="-1" max="-10">
</attack>
</attacks>

Then add a "onStatsChange" creaturescript for your players:

Code:
function onStatsChange(cid, attacker, type, combat, value)
   if type == 1 and combat == COMBAT_PHYSICALDAMAGE then
     if getPlayerStorageValue(target, DAMAGE_REDUCTION) >= 1 then
       value = value/getPlayerStorageValue(target, DAMAGE_REDUCTION)
       doTargetCombatHealth(attacker, cid, COMBAT_MELEEDAMAGE, value, value, CONST_ME_HITAREA)
     end
   end
   return true
end

There you go, 2 ways to do it.


HOLY MOLY that script is amazing!! This was the only thing i missed how to fully control a monster. how to set custom damage.
 
Back
Top