• 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!

Lua Monster reflect Elemental damage by a %, TFS 1.4

Harkenzord

Member
Joined
Dec 25, 2020
Messages
49
Reaction score
11
Solution
Not tested, but should work.

Register this inside the monster. (I put this directly above loot, but anywhere should be fine)
XML:
<script>
    <event name="onHealthChange_MonsterReflect" />
</script>

And put this into data/scripts
Lua:
local reflectTable = {
    ["rat"] = {
        {combatType = COMBAT_FIREDAMAGE, reflectPercentage = 10}, -- add all types of elements you want to reflect
        {combatType = COMBAT_ICEDAMAGE, reflectPercentage = 20},  -- if you only want to reflect 1 type of damage, only have 1 entry in this table.
        {combatType = COMBAT_DEATHDAMAGE, reflectPercentage = 400} -- minimum reflectPercentage is 1.
    },
    ["demon"] = { -- keep monster names lowercase
        {combatType = COMBAT_FIREDAMAGE...
Not tested, but should work.

Register this inside the monster. (I put this directly above loot, but anywhere should be fine)
XML:
<script>
    <event name="onHealthChange_MonsterReflect" />
</script>

And put this into data/scripts
Lua:
local reflectTable = {
    ["rat"] = {
        {combatType = COMBAT_FIREDAMAGE, reflectPercentage = 10}, -- add all types of elements you want to reflect
        {combatType = COMBAT_ICEDAMAGE, reflectPercentage = 20},  -- if you only want to reflect 1 type of damage, only have 1 entry in this table.
        {combatType = COMBAT_DEATHDAMAGE, reflectPercentage = 400} -- minimum reflectPercentage is 1.
    },
    ["demon"] = { -- keep monster names lowercase
        {combatType = COMBAT_FIREDAMAGE, reflectPercentage = 10}
    }
}

local effects = {
    [COMBAT_PHYSICALDAMAGE] = CONST_ME_DRAWBLOOD,
    [COMBAT_ENERGYDAMAGE] = CONST_ME_ENERGYAREA,
    [COMBAT_EARTHDAMAGE] = CONST_ME_POISONAREA,
    [COMBAT_FIREDAMAGE] = CONST_ME_FIREAREA,
    [COMBAT_ICEDAMAGE] = CONST_ME_ICEAREA,
    [COMBAT_HOLYDAMAGE] = CONST_ME_HOLYAREA,
    [COMBAT_DEATHDAMAGE] = CONST_ME_MORTAREA,
    --[COMBAT_HEALING] = CONST_ME_MAGIC_GREEN
}

local healthChange = CreatureEvent("onHealthChange_MonsterReflect")

function healthChange.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if not creature then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
  
    local reflectIndex = reflectTable[creature:getName():lower()]
    if not reflectIndex then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
  
    if attacker:isPlayer() then -- remove this check, if you want the monsters to reflect to all creatures, instead of only players
        for i = 1, #reflectIndex do
            if reflectIndex[i].combatType == primaryType then
                local damage = math.floor((primaryDamage * (reflectIndex[i].reflectPercentage / 100)) + 0.5)
                if damage < 1 then
                    damage = 1
                end
                doTargetCombat(creature, attacker, primaryType, -damage, -damage, effects[primaryType])
            end
            if reflectIndex[i].combatType == secondaryType then
                local damage = math.floor((secondaryDamage * (reflectIndex[i].reflectPercentage / 100)) + 0.5)
                if damage < 1 then
                    damage = 1
                end
                doTargetCombat(creature, attacker, secondaryType, -damage, -damage, effects[secondaryType])
            end
        end
    end
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

healthChange:register()
 
Last edited:
Solution
Not tested, but should work.

Register this inside the monster. (I put this directly above loot, but anywhere should be fine)
XML:
<script>
    <event name="onHealthChange_MonsterReflect" />
</script>

And put this into data/scripts
Lua:
local reflectTable = {
    ["rat"] = {
        {combatType = COMBAT_FIREDAMAGE, reflectPercentage = 10}, -- add all types of elements you want to reflect
        {combatType = COMBAT_ICEDAMAGE, reflectPercentage = 20},  -- if you only want to reflect 1 type of damage, only have 1 entry in this table.
        {combatType = COMBAT_DEATHDAMAGE, reflectPercentage = 400} -- minimum reflectPercentage is 1.
    },
    ["demon"] = { -- keep monster names lowercase
        {combatType = COMBAT_FIREDAMAGE, reflectPercentage = 10}
    }
}

local effects = {
    [COMBAT_PHYSICALDAMAGE] = CONST_ME_DRAWBLOOD,
    [COMBAT_ENERGYDAMAGE] = CONST_ME_ENERGYAREA,
    [COMBAT_EARTHDAMAGE] = CONST_ME_POISONAREA,
    [COMBAT_FIREDAMAGE] = CONST_ME_FIREAREA,
    [COMBAT_ICEDAMAGE] = CONST_ME_ICEAREA,
    [COMBAT_HOLYDAMAGE] = CONST_ME_HOLYAREA,
    [COMBAT_DEATHDAMAGE] = CONST_ME_MORTAREA,
    --[COMBAT_HEALING] = CONST_ME_MAGIC_GREEN
}

local healthChange = CreatureEvent("onHealthChange_MonsterReflect")

function healthChange.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if not creature then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
 
    local reflectIndex = reflectTable[creature:getName():lower()]
    if not reflectIndex then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
 
    if attacker:isPlayer() then -- remove this check, if you want the monsters to reflect to all creatures, instead of only players
        for i = 1, #reflectIndex do
            if reflectIndex[i].combatType == primaryType then
                local damage = math.floor((primaryDamage * (reflectIndex[i].reflectPercentage / 100)) + 0.5)
                if damage < 1 then
                    damage = 1
                end
                doTargetCombat(creature, attacker, primaryType, -damage, -damage, effects[primaryType])
            end
            if reflectIndex[i].combatType == secondaryType then
                local damage = math.floor((secondaryDamage * (reflectIndex[i].reflectPercentage / 100)) + 0.5)
                if damage < 1 then
                    damage = 1
                end
                doTargetCombat(creature, attacker, secondaryType, -damage, -damage, effects[secondaryType])
            end
        end
    end
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

healthChange:register()
Tested it, working perfectly.

Thanks :D
 
Not tested, but should work.

Register this inside the monster. (I put this directly above loot, but anywhere should be fine)
XML:
<script>
    <event name="onHealthChange_MonsterReflect" />
</script>

And put this into data/scripts
Lua:
local reflectTable = {
    ["rat"] = {
        {combatType = COMBAT_FIREDAMAGE, reflectPercentage = 10}, -- add all types of elements you want to reflect
        {combatType = COMBAT_ICEDAMAGE, reflectPercentage = 20},  -- if you only want to reflect 1 type of damage, only have 1 entry in this table.
        {combatType = COMBAT_DEATHDAMAGE, reflectPercentage = 400} -- minimum reflectPercentage is 1.
    },
    ["demon"] = { -- keep monster names lowercase
        {combatType = COMBAT_FIREDAMAGE, reflectPercentage = 10}
    }
}

local effects = {
    [COMBAT_PHYSICALDAMAGE] = CONST_ME_DRAWBLOOD,
    [COMBAT_ENERGYDAMAGE] = CONST_ME_ENERGYAREA,
    [COMBAT_EARTHDAMAGE] = CONST_ME_POISONAREA,
    [COMBAT_FIREDAMAGE] = CONST_ME_FIREAREA,
    [COMBAT_ICEDAMAGE] = CONST_ME_ICEAREA,
    [COMBAT_HOLYDAMAGE] = CONST_ME_HOLYAREA,
    [COMBAT_DEATHDAMAGE] = CONST_ME_MORTAREA,
    --[COMBAT_HEALING] = CONST_ME_MAGIC_GREEN
}

local healthChange = CreatureEvent("onHealthChange_MonsterReflect")

function healthChange.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if not creature then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
 
    local reflectIndex = reflectTable[creature:getName():lower()]
    if not reflectIndex then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
 
    if attacker:isPlayer() then -- remove this check, if you want the monsters to reflect to all creatures, instead of only players
        for i = 1, #reflectIndex do
            if reflectIndex[i].combatType == primaryType then
                local damage = math.floor((primaryDamage * (reflectIndex[i].reflectPercentage / 100)) + 0.5)
                if damage < 1 then
                    damage = 1
                end
                doTargetCombat(creature, attacker, primaryType, -damage, -damage, effects[primaryType])
            end
            if reflectIndex[i].combatType == secondaryType then
                local damage = math.floor((secondaryDamage * (reflectIndex[i].reflectPercentage / 100)) + 0.5)
                if damage < 1 then
                    damage = 1
                end
                doTargetCombat(creature, attacker, secondaryType, -damage, -damage, effects[secondaryType])
            end
        end
    end
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

healthChange:register()

Is it working, i have just a question,

Why having 2 different scripts on the server using the function onHealthChange ( maybe is another thing, primarydamage, secondaryDamage.. ) it disables one of the scripts ?
Example i got a script onHealthChange to add a condition while attacking a monster.
Adding this one it disables my first script
 
Not tested, but should work.

Register this inside the monster. (I put this directly above loot, but anywhere should be fine)
XML:
<script>
    <event name="onHealthChange_MonsterReflect" />
</script>

And put this into data/scripts
Lua:
local reflectTable = {
    ["rat"] = {
        {combatType = COMBAT_FIREDAMAGE, reflectPercentage = 10}, -- add all types of elements you want to reflect
        {combatType = COMBAT_ICEDAMAGE, reflectPercentage = 20},  -- if you only want to reflect 1 type of damage, only have 1 entry in this table.
        {combatType = COMBAT_DEATHDAMAGE, reflectPercentage = 400} -- minimum reflectPercentage is 1.
    },
    ["demon"] = { -- keep monster names lowercase
        {combatType = COMBAT_FIREDAMAGE, reflectPercentage = 10}
    }
}

local effects = {
    [COMBAT_PHYSICALDAMAGE] = CONST_ME_DRAWBLOOD,
    [COMBAT_ENERGYDAMAGE] = CONST_ME_ENERGYAREA,
    [COMBAT_EARTHDAMAGE] = CONST_ME_POISONAREA,
    [COMBAT_FIREDAMAGE] = CONST_ME_FIREAREA,
    [COMBAT_ICEDAMAGE] = CONST_ME_ICEAREA,
    [COMBAT_HOLYDAMAGE] = CONST_ME_HOLYAREA,
    [COMBAT_DEATHDAMAGE] = CONST_ME_MORTAREA,
    --[COMBAT_HEALING] = CONST_ME_MAGIC_GREEN
}

local healthChange = CreatureEvent("onHealthChange_MonsterReflect")

function healthChange.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if not creature then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
 
    local reflectIndex = reflectTable[creature:getName():lower()]
    if not reflectIndex then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
 
    if attacker:isPlayer() then -- remove this check, if you want the monsters to reflect to all creatures, instead of only players
        for i = 1, #reflectIndex do
            if reflectIndex[i].combatType == primaryType then
                local damage = math.floor((primaryDamage * (reflectIndex[i].reflectPercentage / 100)) + 0.5)
                if damage < 1 then
                    damage = 1
                end
                doTargetCombat(creature, attacker, primaryType, -damage, -damage, effects[primaryType])
            end
            if reflectIndex[i].combatType == secondaryType then
                local damage = math.floor((secondaryDamage * (reflectIndex[i].reflectPercentage / 100)) + 0.5)
                if damage < 1 then
                    damage = 1
                end
                doTargetCombat(creature, attacker, secondaryType, -damage, -damage, effects[secondaryType])
            end
        end
    end
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

healthChange:register()
[2024-02-06 09:53:32.607] [error] C:\otserv-canary-main\canary-main\data-otservbr-global/monster\humanoids\crazed_summer_rearguard.lua
[2024-02-06 09:53:32.608] [error] ...vbr-global/monster\humanoids\crazed_summer_rearguard.lua:113: unexpected symbol near '<'
 
[2024-02-06 09:53:32.607] [error] C:\otserv-canary-main\canary-main\data-otservbr-global/monster\humanoids\crazed_summer_rearguard.lua
[2024-02-06 09:53:32.608] [error] ...vbr-global/monster\humanoids\crazed_summer_rearguard.lua:113: unexpected symbol near '<'

TFS , The Forgotten Server.
CS, Canary Server.
 
Back
Top