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

TFS 1.X+ Handler Pet Cooldown

zxmatzx

Advanced OT User
Joined
Dec 1, 2010
Messages
312
Solutions
27
Reaction score
155
Location
Brazil
GitHub
Mateuso8
Hello,
Im developing a pet system, and the pets will have skills. I was thinking of how to do the cooldown of skills. When the pet is summoned and cast a spell, will start the countdown to be possible cast again, but in meanwhile if i unsummon the pet, the countdown need to be freezed, and only restart the count when the pet was summoned again.

Maybe, when pet cast a skill, put the cooldown on a global table and a onThink event handle all cooldown decrescing. But Wouldn't that be too much stress for the server? 300 Players, with 200 summoned pets, with 5 skills each being checked every 1 sec, will be 200 index and 1000 keys to check every second.

And how to pass this info to OTC? I know i can pass the Table with skills cooldown, but on every onThink tick? Again every 1 sec?

I guess, i can do it work, but i want to know if have a better way to do. If i do how i described, the performace will be bad? Later i will try do some tests to check the performace using this parameters.

Thanks guys.

Hello zxmatzx,
If you can write it yourself, I assume you can also analyze some code. I find it better to point you out code to do analysis by yourself than trying to explain it.
Here's a Ruby Server (pokemon fork), that might be helpful. For cooldowns, they use conditions.
Please analyze how it acts over when player "desummons" pokemon.

Hello zxmatzx,
If you can write it yourself, I assume you can also analyze some code. I find it better to point you out code to do analysis by yourself than trying to explain it.
Here's a Ruby Server (pokemon fork), that might be helpful. For cooldowns, they use conditions.
Please analyze how it acts over when player "desummons" pokemon.
of course its good from you that you are trying to help but his problem not in the condition in freezing it when the pet is removed

Hello zxmatzx,
If you can write it yourself, I assume you can also analyze some code. I find it better to point you out code to do analysis by yourself than trying to explain it.
Here's a Ruby Server (pokemon fork), that might be helpful. For cooldowns, they use conditions.
Please analyze how it acts over when player "desummons" pokemon.
Thanks for answer!
I was looking Pokémon Servers to know how they do this. I will look this onde too. I don't know C++, but can try understand how it work. Can u think some way to do with Lua?
Thanks for your answer.

of course its good from you that you are trying to help but his problem not in the condition in freezing it when the pet is removed
Im looking what is the better way to do, i think he sended me a way to do with conditions. In any method that i choose, i will need to freeze the countdown when pet has removed.

I have no idea this will cause any type of lags or not but i am going to say it any way you can use 2 storages first one normal exhaust stores with os.time for the exhaust you need and another one function on Think when the pet is removed stores the value of seconds of the first storage in the second storage and when the pet is summoned the first storage takes the value of the second storage which is the same seconds.. or you can set exhaust after summoning a pet you can't use its skill before XX second

Thanks for answer!
I was looking Pokémon Servers to know how they do this. I will look this onde too. I don't know C++, but can try understand how it work. Can u think some way to do with Lua?
Thanks for your answer.
I think this is possible somehow to do with Lua, but all my ideas need some adjustments in C++.
I'd rather go with C++; it's fairly easier to maintain than in Lua.

Also, if you'd like to send it to client, you'll need C++ editions anyways.
This is how it's send in pokemon server: therubyproject/rubyserver (https://github.com/therubyproject/rubyserver/blob/8e5b7bc7c3ede0adfe4f7a3fe49794afc7c41f02/src/protocolgame.cpp#L2758)



But from fast analyzing how they "freeze" those conditions, I think they do not. It should be fairly easy to do so, just create new C++ variables.
I would dismiss Shadow_'s idea to make it storage if you use more than one "summon"/"pet" type, but his idea to have two variables: one for time an the second for seconds is good. I would need to do some benchmark tests first, tho, but I am afraid it'll be messy and slow making it storage, considering each and every summon has it's own cooldowns for various spells.

I think this is possible somehow to do with Lua, but all my ideas need some adjustments in C++.
I'd rather go with C++; it's fairly easier to maintain than in Lua.

Also, if you'd like to send it to client, you'll need C++ editions anyways.
This is how it's send in pokemon server: therubyproject/rubyserver (https://github.com/therubyproject/rubyserver/blob/8e5b7bc7c3ede0adfe4f7a3fe49794afc7c41f02/src/protocolgame.cpp#L2758)



But from fast analyzing how they "freeze" those conditions, I think they do not. It should be fairly easy to do so, just create new C++ variables.
I would dismiss Shadow_'s idea to make it storage if you use more than one "summon"/"pet" type, but his idea to have two variables: one for time an the second for seconds is good. I would need to do some benchmark tests first, tho, but I am afraid it'll be messy and slow making it storage, considering each and every summon has it's own cooldowns for various spells.
Im sure that i can't do this with C++, i really don't know how to do. I wrote this Lua pseudo-code, i think can work. I can't test atm because im not in home, but i think will work. I don't covered all the checks, but with this we can understand how will work, need to check performace too.



Lua:
PETS_SKILLS_COOLDOWN = {
--[player1_guid] = {
        --[petId] = {[skillId1] = 2000, [skillId2] = 1400, [skillId3] = 10000},
               --},
--[player2_guid] = {
        --[petId] = {[skillId1] = 2000, [skillId2] = 1400, [skillId3] = 10000},
               --}
}

PETS_SKILLS_COOLDOWN_STOPED = {
--[player1_guid] = {
        --[petId1] = {[skillId1] = 2000, [skillId2] = 1400, [skillId3] = 10000},
        --[petId2] = {[skillId1] = 4000, [skillId2] = 1200, [skillId3] = 5000},
               --},
--[player2_guid] = {
        --[petId1] = {[skillId1] = 2000, [skillId2] = 1400, [skillId3] = 10000},
        --[petId2] = {[skillId1] = 4000, [skillId2] = 1200, [skillId3] = 5000},
               --},
}

function summonPet(player, petId)
    --DO PET SUMMON STUFF
    
    local playerGuid = player:getGuid()--get player GUID
    
    local stopedPetCooldown = PETS_SKILLS_COOLDOWN_STOPED[playerGuid][petId]--get player stoped cooldown
    if stopedPetCooldown then--If have
        PETS_SKILLS_COOLDOWN[playerGuid][petId] = stopedPetCooldown--Running cooldown = stoped cooldown
        PETS_SKILLS_COOLDOWN_STOPED[playerGuid][petId] = nil --stoped cooldown = nil
    end
end

function unsummonPet(player, petId)
    --DO PET UNSUMMON STUFF
    
    local playerGuid = player:getGuid()--get player GUID
    
    for i = 1, #PETS_SKILLS_COOLDOWN[playerGuid][petId] do--For each skill that pet have
        if PETS_SKILLS_COOLDOWN[playerGuid][petId][i] > 0 then --check if cooldown is higher than 0
            PETS_SKILLS_COOLDOWN_STOPED[playerGuid][petId][i] = PETS_SKILLS_COOLDOWN[playerGuid][petId][i]--if is higher, assing the value to stoped cooldown table
        end
    end
    PETS_SKILLS_COOLDOWN[playerGuid][petId] = nil--running cooldown = nil
end

--Interval = 1000
function onThink(interval, lastExecution)
    for playerKey, playerValue in pairs(PETS_SKILLS_COOLDOWN) do--get all players Keys(GUID) and Values(Pets List)
        if Player(playerKey) then--if can find player, then is online
            for petIndex = 1, #playerValue do--for each pet player have(this always will be 1, because can have only 1 pet summoned) in running cooldown table
                for skillIndex = 1, #PETS_SKILLS_COOLDOWN[playerKey][petIndex] do--for each skill pet have in running cooldown table
                    local oldSkillCooldown = PETS_SKILLS_COOLDOWN[playerKey][petIndex][skillIndex]--get skill cooldown
                    if oldSkillCooldown ~= nil and oldSkillCooldown > 0 then--if higher than 0 and ~= nil
                        local newValue = PETS_SKILLS_COOLDOWN[playerKey][petIndex][skillIndex] - 1000 --decress 1000ms(onThink interval)
                        if newValue > 0 then--if newValue higher than 0, then skill still in cooldown
                            PETS_SKILLS_COOLDOWN[playerKey][petIndex][skillIndex] = newValue --assing the new skill cooldown
                        else--if cooldown finished
                            PETS_SKILLS_COOLDOWN[playerKey][petIndex][skillIndex] = nil--set cooldown to nil
                        end
                    end
                end
            end
        else--can't find the player, then remove the player from table and store old cooldown
            local playerPetsCooldown = PETS_SKILLS_COOLDOWN[playerKey]
            PETS_SKILLS_COOLDOWN_STOPED[playerKey] = playerPetsCooldown
            PETS_SKILLS_COOLDOWN[playerKey] = nil
        end
    end
end

I can do more checks, and if i want to send the cooldowns to client, just need to send the PETS_SKILLS_COOLDOWN[playerGuid][summonedPetId] and read the data there. I tryed to identify the code to better understanding. AGAIN, NOT TESTED CODE. What u think about this? Looking for feedback.
Thanks guys.

I think when you unsummon the pet you should calculate the remaining time left on cooldown and save that value, then reapply the cooldown with updated cooldown such as os.time() + remainingCooldown for example.

I think when you unsummon the pet you should calculate the remaining time left on cooldown and save that value, then reapply the cooldown with updated cooldown such as os.time() + remainingCooldown for example.
You mean create a timestamp to when the cooldown will finish? If i have 3000 as value, then will finish in 3 onThink ticks(3 seconds), why change this?

And about the code? What do you think? Any problem? U would make in another way? If yes, why?
Sorry for all those questions, just trying to understand why do, to learn with it.
Thanks for reply.

You mean create a timestamp to when the cooldown will finish? If i have 3000 as value, then will finish in 3 onThink ticks(3 seconds), why change this?

And about the code? What do you think? Any problem? U would make in another way? If yes, why?
Sorry for all those questions, just trying to understand why do, to learn with it.
Thanks for reply.
Usually when you have a cooldown, you set the end time to os.time() + seconds, meaning the current time + seconds is the end timestamp. If you check for current time and compare with end time, if the end time is <= the current time then the cooldown is over. Using this way, once you unsummon, you can check endtime - os.time() to get remaining duration of the cooldown and save that remaining duration in the table, then when you resummon you add that cooldown back by using os.time() + remainingduration.

Usually when you have a cooldown, you set the end time to os.time() + seconds, meaning the current time + seconds is the end timestamp. If you check for current time and compare with end time, if the end time is <= the current time then the cooldown is over. Using this way, once you unsummon, you can check endtime - os.time() to get remaining duration of the cooldown and save that remaining duration in the table, then when you resummon you add that cooldown back by using os.time() + remainingduration.
I know, just don't did this way because it's not the real code that i will use, i will write when get home. Just wanting to know if have a better way to do or if my code have some problem or something that i can improve. If my way to handler with table keys/values are correct, or can be better. Should i always pass the info to OTC when finish onThink? Or have a better way? Any tip or advice will help.

I think when you unsummon the pet you should calculate the remaining time left on cooldown and save that value, then reapply the cooldown with updated cooldown such as os.time() + remainingCooldown for example.
I understand now what u said. I coded in your way and don't need for onThink event. Working all ok! Thanks!

@topic
Solved, thanks to all the answers. If someone want to make a "timer" to handler cooldown time, don't need. Just follow Delusion tip, will work without a "timer"(onThink).
 
All the posts in this thread were merged unintentionally. The readability is affected in the thread but the content should remain the same.
I apologize for any inconvenience this might have caused.

If the thread starter is looking for further assistance, I refer that person to create a new thread.
 
Back
Top