CreatureEvent Passive Spells tfs 1.2

xydius

Just an otland wanderer
Joined
Feb 25, 2016
Messages
43
Reaction score
30
Hello fellow otlanders,
Im releasing this simple "script" i just made for my custom ot where players have a passive spell which are cast from time to time while the player is in combat and has a target.

  1. First go to creaturescripts and create a new file and name it however you want and paste this
    Lua:
    local config = {
        enabled = true,
        doChance = 10000, --chance to do spell 1000 = 1 %
        TALKTYPE_ORANGE_1 = TALKTYPE_MONSTER_SAY,
        TALKTYPE_ORANGE_2 = TALKTYPE_MONSTER_YELL
    }
    
    local voc = {
        {
            id = 1, --sorc
            spellname = "passive spell", --TODO think for proper names
            combatDamage = COMBAT_DEATHDAMAGE,
            CombatEffect = CONST_ME_MORTAREA,
            distEffect = CONST_ANI_DEATH
    
        },
        {
            id = 2, --druid
            spellname = "passive spell",
            combatDamage = COMBAT_ICEDAMAGE,
            CombatEffect = CONST_ME_ICEAREA,
            distEffect = CONST_ANI_ICE
    
        },
        {
            id = 3, --pally
            spellname = "passive spell",
            combatDamage = COMBAT_PHYSICALDAMAGE,
            CombatEffect = CONST_ME_HITAREA,
            distEffect = CONST_ANI_THROWINGSTAR
    
        },
        {
            id = 4, --knight
            spellname = "passive spell",
            combatDamage = COMBAT_PHYSICALDAMAGE,
            CombatEffect = CONST_ME_DRAWBLOOD,
            distEffect = CONST_ANI_LARGEROCK
        },
    }
    
    
    
    
    
    
    
    function onThink(creature, interval)
        if config.enabled then
            if creature:isPlayer() then
                local target = creature:getTarget()
                if target then
                    local chance = math.random(1, 100000)
                    if chance <= config.doChance then
                        local vocation = creature:getVocation():getBase():getId()
                        for i=1, #voc do
                            if vocation == voc[i].id then
                                local level = creature:getLevel()
                                local min = 0
                                local max = 0
                                if vocation == 1 or vocation == 2 then
                                    local maglevel = creature:getMagicLevel()
                                    min = (level / 5) + (maglevel * 1.4) + 8
                                    max = (level / 5) + (maglevel * 2.2) + 14
                                end
                                if vocation == 3 then
                                    local weapontype = nil
                                    local slotItem = creature:getSlotItem(CONST_SLOT_LEFT)
                                    if    slotItem then
                                        weaponType = slotItem:getType():getWeaponType()
                                    end
                                    local skill = SKILL_FIST
                                    if weaponType == 5 then
                                        skill = SKILL_DISTANCE
                                    end
                                    local skilllvl = creature:getEffectiveSkillLevel(skill)
                                    min = (level / 5) + skilllvl * 2
                                    max = (level / 5) + skilllvl * 5
                                end
                                if vocation == 4 then
                                    local weapontype = nil
                                    local attack = 10
                                    local uid = nil
                                    local slotItem = creature:getSlotItem(CONST_SLOT_LEFT)
                                    if slotItem then
                                        uid = slotItem:getUniqueId()
                                        attack = getItemAttribute(uid, ITEM_ATTRIBUTE_ATTACK, true)
                                        weaponType = slotItem:getType():getWeaponType()
                                    end
                                    local skill = SKILL_FIST
                                    if weaponType == 1 then
                                        skill = SKILL_SWORD
                                    end
                                    if weaponType == 2 then
                                        skill = SKILL_CLUB
                                    end
                                    if weaponType == 3 then
                                        skill = SKILL_AXE
                                    end
    
                                    local skilllvl = creature:getEffectiveSkillLevel(skill)
                                    min = (level / 5) + (skilllvl * attack * 0.01) + 1
                                    max = (level / 5) + (skilllvl * attack * 0.03) + 6
                                end
         
    
                                doCreatureSay(creature, voc[i].spellname, config.TALKTYPE_ORANGE_1)
                                doSendDistanceShoot(creature:getPosition(), target:getPosition(), voc[i].distEffect)
                                doTargetCombatHealth(creature, target, voc[i].combatDamage, -min, -max, voc[i].CombatEffect)
                            end
                        end
                       
                    end
                end
                if not target then
                    creature:unregisterEvent("PassiveSpells")
                end
            end
        end
    end
  2. Add this script on your creaturescripts.xml file like this just remmber to change "passive.lua" to your filename
    Code:
    <!-- Passive Spells -->
     <event type="think" name="PassiveSpells" script="passive.lua" />
  • Register the event, I suggest you register the event in creature.lua in events folder in "Creature: onTargetCombat(target)" function right after "if not self then return true end" add this
    Lua:
    if self:isPlayer() and target:isMonster() then
            self:registerEvent("PassiveSpells")
        end
And thats pretty much it, it is a bit configurable but it lacks of some stuff for example passive spells can go through walls LOL and have no exhaustion thats why i recommend leaving a low chance to cast.

P.D.
It uses the exact same formulas for "exori mort" for mages, "exori con" for paladins and "exori hur" for knights in tfs 1.2 version 10.98-10.99
If i add some of this later I will edit this post.
If you encounter any issue let me know and ill try to fix it.
If you have any suggestion feel free to let me know so i can improve this code.
 

Yuggi

Member
Joined
May 18, 2017
Messages
64
Reaction score
8
This is really interesting and I have never used onThink, could somebody explain what it does?
onThink(creature, interval) what's the interval there?
 
OP
xydius

xydius

Just an otland wanderer
Joined
Feb 25, 2016
Messages
43
Reaction score
30
This is really interesting and I have never used onThink, could somebody explain what it does?
onThink(creature, interval) what's the interval there?
Im actually new to onThink also while i was looking how to do this i came up with this.
What i understand about it is that once it is triggered, every 500 ms it tries to do whatever it is supposed to do.
As far as i know to change the interval it might need source edits (someone correct me if this not the case) but i guess it also can be done with a counter for example.
Lua:
local count = 0

function onThink(creature, interval)
count++ (dont know if count++ work havent tried it in lua)
if count == 4  then
    --do stuff
count =0
end
end
so every 4 "loops" it will do the stuff so basically 500ms * 4 == 2 seconds

Thats why i unregister the event once you are not targeting anything because i really dont know it it lags the server or not.
 

ond

Legendary OT User
Joined
Mar 24, 2008
Messages
2,667
Reaction score
397
Location
Sweden
...
so every 4 "loops" it will do the stuff so basically 500ms * 4 == 2 seconds

Thats why i unregister the event once you are not targeting anything because i really dont know it it lags the server or not.
I think onThink interval is executed every 1000 ms. You could handle it by storage value. Also, ++ operator doesn't exist in LUA, use count = count + 1
 

Yuggi

Member
Joined
May 18, 2017
Messages
64
Reaction score
8
sholdnt the script "return true" somewhere after it has executed?
im thinking else it wil case lagg?
 
OP
xydius

xydius

Just an otland wanderer
Joined
Feb 25, 2016
Messages
43
Reaction score
30
sholdnt the script "return true" somewhere after it has executed?
im thinking else it wil case lagg?
Uhh maybe, i havent really tested it with a full server just me doing random stuff on a cuatom server im doing probably the best idea is to add return true before last end on the creaturescripts file
 

Yuggi

Member
Joined
May 18, 2017
Messages
64
Reaction score
8
yeah because my cpu usage went up to 150% from 10% after the script has been runing for some time, and i just did small minor edits that shouldnt affect it ^^
or maybe this onthink thing just causes lag
 

Yuggi

Member
Joined
May 18, 2017
Messages
64
Reaction score
8
150% ?
oh shit
do u have to post useless replies in all threds?
yes if you use top command in linux it will go over 100% if it goes over the amount the cpu can handle and if u have 4 cores and all of them are fully used it will say 400%.
 
OP
xydius

xydius

Just an otland wanderer
Joined
Feb 25, 2016
Messages
43
Reaction score
30
yeah because my cpu usage went up to 150% from 10% after the script has been runing for some time, and i just did small minor edits that shouldnt affect it ^^
or maybe this onthink thing just causes lag
Holy shit thats a lot lol when i get back home from vacations i might look at that and maybe come with a better idea
 

Yuggi

Member
Joined
May 18, 2017
Messages
64
Reaction score
8
soooo! guys any idea why my server laggs when using this `?

Code:
function onThink(creature, interval)
    if creature:isPlayer() then
        local target = creature:getTarget()
        if target then
            if creature:getStorageValue(7608) == 2 then
                local cooldowna = creature:getStorageValue(23157)
               if cooldowna ~= nil then
                    creature:setStorageValue(23157, 0)
                end      
                if cooldowna >= 5 then 
                    creature:setStorageValue(23157, 0)
                    if creature:getPosition():isSightClear(target:getPosition()) then
                        Position(target:getPosition() + Position(-6, -5, 0)):sendDistanceEffect(target:getPosition(), 34)
                        doTargetCombatHealth(creature, target, COMBAT_FIREDAMAGE, -(creature:getLevel() * 1.5 * 0.7), -(creature:getLevel() * 2 * 0.8), CONST_ME_FIREAREA)
                    end
                else
                    creature:setStorageValue(23157, cooldowna+1)
                end
            end
        end
    end
end
[/img]

the idea is after a player has gained a storagevalue he will automatically shoot this spell at his target every 5seconds. but for some reason it laggs the server? my cpu usage goes very high and stuff like i said in some posts before
 

RazorBlade

Retired Snek
Joined
Nov 7, 2009
Messages
2,030
Reaction score
589
Location
Canada
soooo! guys any idea why my server laggs when using this `?

Code:
function onThink(creature, interval)
    if creature:isPlayer() then
        local target = creature:getTarget()
        if target then
            if creature:getStorageValue(7608) == 2 then
                local cooldowna = creature:getStorageValue(23157)
               if cooldowna ~= nil then
                    creature:setStorageValue(23157, 0)
                end     
                if cooldowna >= 5 then
                    creature:setStorageValue(23157, 0)
                    if creature:getPosition():isSightClear(target:getPosition()) then
                        Position(target:getPosition() + Position(-6, -5, 0)):sendDistanceEffect(target:getPosition(), 34)
                        doTargetCombatHealth(creature, target, COMBAT_FIREDAMAGE, -(creature:getLevel() * 1.5 * 0.7), -(creature:getLevel() * 2 * 0.8), CONST_ME_FIREAREA)
                    end
                else
                    creature:setStorageValue(23157, cooldowna+1)
                end
            end
        end
    end
end
[/img]

the idea is after a player has gained a storagevalue he will automatically shoot this spell at his target every 5seconds. but for some reason it laggs the server? my cpu usage goes very high and stuff like i said in some posts before
first of all why are you setting the storage to 0 if the cooldown isn't nil? it'll never be nil, if they don't have the storage it's -1 not nil. You're basically just setting it to 0 every second. It should never be able to reach 5. It should never be able to reach 2. Does your spell even cast?
 

jo3bingham

Legendary OT User
Joined
Mar 3, 2008
Messages
992
Reaction score
423
soooo! guys any idea why my server laggs when using this `?

Code:
function onThink(creature, interval)
    if creature:isPlayer() then
        local target = creature:getTarget()
        if target then
            if creature:getStorageValue(7608) == 2 then
                local cooldowna = creature:getStorageValue(23157)
               if cooldowna ~= nil then
                    creature:setStorageValue(23157, 0)
                end     
                if cooldowna >= 5 then
                    creature:setStorageValue(23157, 0)
                    if creature:getPosition():isSightClear(target:getPosition()) then
                        Position(target:getPosition() + Position(-6, -5, 0)):sendDistanceEffect(target:getPosition(), 34)
                        doTargetCombatHealth(creature, target, COMBAT_FIREDAMAGE, -(creature:getLevel() * 1.5 * 0.7), -(creature:getLevel() * 2 * 0.8), CONST_ME_FIREAREA)
                    end
                else
                    creature:setStorageValue(23157, cooldowna+1)
                end
            end
        end
    end
end
[/img]

the idea is after a player has gained a storagevalue he will automatically shoot this spell at his target every 5seconds. but for some reason it laggs the server? my cpu usage goes very high and stuff like i said in some posts before
isSightClear() is very costly to call, and onThink() is triggered every 1000ms. Which means, potentially, it’s being called every second. That’s why you’re lagging and seeing high CPU usage.
 

Yuggi

Member
Joined
May 18, 2017
Messages
64
Reaction score
8
@RazorBlade yes it work.. every second they get +1 storage idk much about coding but its working (only lagg is the problem but i don tthink anything u mentioned affects this lagg i have)

hmm only few players like 6 has this on my server, but it doesnt lagg from the start it only laggs after being online for some hours.. hmm maybe there is somethink other wrong? and isSightClear i think is needed else players could shoot through walls
 

jo3bingham

Legendary OT User
Joined
Mar 3, 2008
Messages
992
Reaction score
423
and isSightClear i think is needed else players could shoot through walls
Yes, that may be, but it’s still probably the cause of the lag and high CPU usage. You could remove it from the script to see if it is. If you remove it and it doesn’t help then you can rule it out.
 

Madzix

Member
Joined
Sep 8, 2016
Messages
61
Reaction score
65
@Jo3Bingham
Actually "isSightClear" isn't that much costly at all event the tfs path finding using it to check per node so the server might end using this function even ten thousands times every seconds.

However the script provided by Yuggi shouldn't work at all not to mention lagging.
 
Top