• 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!
  • If you're using Gesior 2012 or MyAAC, please review this thread for information about a serious security vulnerability and a fix.

Weapon Tier System / Critical System using Action IDs TFS 1.3

sawkagt

New Member
Joined
May 17, 2022
Messages
4
Reaction score
1
Hi!

The following guide will show how to implement a tier system on all weapons inside the game.

What is this system for?
This system will increase the damage given by the player based on the weapon tier. In this tutorial, I use the animation for the "FATAL" hit.
I consider it as an alternative for the Exaltation Forge system, and also pretty simple!

We'll be going throught the following steps:

1. Creating an action for a specific item to change other items' tiers (action ID's)
2. Creating creature scripts to check health and mana changes and trigger the system
3. Adding some properties to player login and creature spawn so every player and creature can trigger the system

Considerations:
I'd like to thank @Roddet, who helped me out with some parts of the coding.

Without any further ado, let's go:

1. Creating an action for a specific item to change other items' tiers (action ID's):

in data\scripts\actions, create itemtier.lua and paste the following code:

Lua:
local weapontierpotion = Action()
function weapontierpotion.onUse(player, item, fromPosition, target, toPosition, isHotkey)

    local it = ItemType(target:getId())
    if it:getWeaponType() == WEAPON_NONE or it:getWeaponType() == WEAPON_SHIELD then
        player:say("Process not started! This item cannot be upgraded.",TALKTYPE_MONSTER_SAY)
        return true  
    end

    local chance = math.random(0, 100)
    local aid = target:getActionId() -- this will be either 0, 1000, 2000, 3000, 4000 or 5000. Can be higher if you change maxtier.
    local rate = 80 - aid/100 -- this will be 80, 70, 60, 50, 40 or 30. You can change if you want.
    local upgrade = aid + 1000
    local downgrade = aid - 1000
    local candowngrade = true
    local maxtier = 5 -- You can change if you want

    if aid >= maxtier * 1000 then
        player:say("This item cannot be upgraded any further!",TALKTYPE_MONSTER_SAY)
        return true
    end
   
    if rate > chance then
        target:setActionId(upgrade)
        player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN)
        player:say("Congratulations! Your item is now upgraded!",TALKTYPE_MONSTER_SAY)
        item:remove(1)  
        return true
       
    else if chance >= 90 and candowngrade == true and aid >= 1000 then
        target:setActionId(downgrade)
        player:say("Oh no! Your item has downgraded to the previous tier",TALKTYPE_MONSTER_SAY)
        player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)
        item:remove(1)
        return true
    else

        player:say("Process failed!",TALKTYPE_MONSTER_SAY)
        player:getPosition():sendMagicEffect(CONST_ME_BLOCKHIT)
        item:remove(1)  
        return true
    end
    end
end

weapontierpotion:id(36170) -- here, you can replace the ID 36170 with any other item ID. It's the item that will work as your tier changer.
weapontierpotion:register()

2. Creating creature scripts to check health and mana changes and trigger the system:

In data\creaturescripts\scripts, we will create two files, one to check health changes and the other to check mana changes.
I called them fatalhealth.lua and fatalmana.lua

In fatalhealth.lua, use the following code:

Code:
function onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)

    if (not attacker or not creature) then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end

    if primaryType == COMBAT_HEALING then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
   
    if attacker:isPlayer() then
    if attacker:getSlotItem(CONST_SLOT_LEFT):getActionId() >= 1000 then
    local tier = attacker:getSlotItem(CONST_SLOT_LEFT):getActionId()/1000
    local chance = tier * 5 --tier 1 = 5%, tier 2 = 10% ... tier 5 = 25%. Of course, you can change these values.
    local mult = 1 + tier/5 -- Of course, you can change these values.
   
        if chance >= math.random(1,100) then
            creature:getPosition():sendMagicEffect(230)
            return primaryDamage * mult, primaryType, secondaryDamage * mult, secondaryType
        end  
    end  
    end  
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end
Code:

In fatalmana.lua, use the following code:

Code:
function onManaChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)

     if (not attacker or not creature) then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end

    if primaryType == COMBAT_HEALING then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
   
    if attacker:isPlayer() then
    if attacker:getSlotItem(CONST_SLOT_LEFT):getActionId() >= 1000 then
    local tier = attacker:getSlotItem(CONST_SLOT_LEFT):getActionId()/1000
    local chance = tier * 5
    local mult = 1 + tier/5
   
        if chance >= math.random(1,100) then
            creature:getPosition():sendMagicEffect(230)
            -- creature:say("FATAL!", TALKTYPE_MONSTER_SAY)
            return primaryDamage * mult, primaryType, secondaryDamage * mult, secondaryType
        end  
   

    end  
    end  
   
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

Lastly, go to data\creaturescripts\creaturescripts.xml and insert the following:

Code:
<creaturescripts>

    <event type="healthchange" name="fatalhealth" script="fatalhealth.lua"/>  
    <event type="manachange" name="fatalmana" script="fatalmana.lua"/>  
   
</creaturescripts>

3. Adding some properties to player login and creature spawn so every player and creature can trigger the system:

Let's change the monsters first.
Go to data\events\scripts and open monster.lua

Look for the function Monster onSpawn and insert the following:

Code:
function Monster:onSpawn(position)
    self:registerEvent("fatalhealth") -- <<<<<<<<< INSERT THIS LINE
    if self:getType():isRewardBoss() then
        self:setReward(true)
    end

Now, for the players. If you have the following path, you can follow it. If not, you can create it, it's merely for organization.

Go to data\scripts\creaturescripts\others and open or create the file login_events.lua. Paste the following code:

Code:
local loginEvents = CreatureEvent("LoginEvents")
function loginEvents.onLogin(player)

    local events = {
        "fatalhealth",
        "fatalmana"
    }

    for i = 1, #events do
        player:registerEvent(events[i])
    end
    return true
end
loginEvents:register()
Post automatically merged:

Of course, it's important for the players to see the tier of the item they're using:

So, as an additional step, you can do the following:

Go to data\events\scripts and open player.lua

Inside the function Player onLook, paste the following:

Lua:
            local actionId = thing:getActionId()
            if actionId ~= 0 then
                local tier = actionId/1000
                description = string.format("%s, Tier: %d", description, tier)
            end

Also, change the function onLookInTrade:

Code:
function Player:onLookInTrade(partner, item, distance)
    local description = "You see "
    description = description .. item:getDescription(distance)
    local actionId = item:getActionId()
    if actionId ~= 0 then
        local tier = actionId/1000
        description = string.format("%s, Tier: %d", description, tier)
    end
    self:sendTextMessage(MESSAGE_INFO_DESCR, description)   
end
 
Last edited:

sharinn

Active Member
Joined
Aug 27, 2011
Messages
141
Solutions
6
Reaction score
28
GitHub
ArturKnopik
using actionid is bad idea, you must track all action used in server, you can have situation when some weapon can give some quest reward or set some specyfic storage etc
 
OP
OP
S

sawkagt

New Member
Joined
May 17, 2022
Messages
4
Reaction score
1
using actionid is bad idea, you must track all action used in server, you can have situation when some weapon can give some quest reward or set some specyfic storage etc

You are absolutely right.
I would say it's a bad idea IF you don't take care. You can pretty much check what action IDs are being used and avoid them.
So, it would be more of a precaution.
In my example, pretty simple, 5 action IDs to check. If you want to expand, however, it can get a little tricky.
But still, I think it's pretty good for what I need, and can help someone as well.

Cheers!
 
Top