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

Action TFS 1.x Potions System : Percents and Summons!

Codinablack

Dreamer
Content Editor
Joined
Dec 26, 2013
Messages
1,557
Solutions
11
Reaction score
774
Hello Otland!

Today I bring a release for everyone. I have worked on this script for awhile now and I have gotten it ready for everyone here. I became inspired when I seen a script for TFS 1.x for healing potions using a percent of max health, same thing with the mana potions for mana. Anyways the script was very very much bugged, and missed alot of features. It also relied heavily on functions from compat.lua instead of meta methods. So I did my best to convert it to something for an RPG type feel. During that process I decided to make options that you guys may want to change, and started creating a super configurable potions system.

CREDITS:

@Ninja for helping me with a problem determining if the summon was a guild or party members.
@otland for all the resources and help with learning.
@Limos and @forgee both special thanks for helping me to develop my skills and easing the learning process.

||||Features||||
-- Potions are based of Max Percents and individually configurable for each potion.
-- Potions are also based of Level and Magic level, which can be configured for all potions.
-- Potions can be used on Summons -- Configurable
--- Can be used on Guild Members Summon -- Configurable
--- Can be used on Party Members Summon -- Configurable
-- Potion's formula has min and max percents -- Configurable
-- Anti-Hotkey protection (realPvpMode) -- Configurable
-- Remove on Use -- Configurable
-- Splashable (with decay) -- Configurable for individual potions.
-- Level Requirements -- Configurable for individual potions.
-- Vocation Requirements -- Configurable for individual potions.
-- Unique Exhaust/Cooldown System -- Configurable for individual potions.
--- Potions with same "spellid" share same exhaust. However two potions with same "spellid" can have different exhaust values. Default set up for different exhausts for mana potions, health (little) and health (big), and spirit potion. Spell Id is sent as icon. Cooldown don't interfere with spells of same spell Id.
-- Misclick Protection: Doesn't allow use on stuff far away (good because it's splashable and if you have remove on use enabled), summons (if disabled), monsters, and Npc's.

If there is any other features I am missing that should be mentioned please let me know.

Only thing that should be explained that isn't in comments in the script is the table, but really that should be self-explanatory. If anyone has a problem, just post here and I will help you.

FULLY TESTED BUG FREE

If you do use this, please keep my credits in the script, and it wouldn't hurt to get a like. :D

[Lua] potions.lua - Pastebin.com

Version 1.1 is done.
Fixed enum causing debug.
Updated for tfs 1.1 compatibility
Cleaned up monster checks: Now depend upon Player:isCreatureFriend() method.

New version depends on this lib.
[TFS 1.X] Player:isCreatureFriend()

[Lua] potion - Pastebin.com

Sorry guys, apparently the code is over 1000 characters by itself.

NEW VERSION v12

Changelog:
  • Replaced some parameters eg. player = caster ect.
  • Updated for 1.2 and 1.3 (unoffically) compatibility.
  • Integrated isCreatureFriend function in from lib.
  • Updated Commentation.
  • Reworked some variables (removed unused, renamed, added new).
 

Attachments

Last edited by a moderator:
40 + views and not a single comment or like? I can't put the code on the page guys or I would. Just take a look at the damn thing, I have completely tested the script all features are fully functionable and it is way more optimized for TFS 1.0 than any others. Also I would like to not this is the only working script released here (or github) that actually makes the splash and with decay too. I mean I tried to think of everything, that config was made strictly for Otland users. I have no use for that config, for me those wouldn't need changed and if something did, then it would be a slight modification on the formula's and that would be easier than making that config.

Just take a look at it and leave a comment. At this point I don't even care if someone just drops in to tell me how horrible my organization of the code is, indentation and everything (especially since I know it is, I released it in such a hurry and I am not good at such things anyways).
 
I like that you used meta methods. Thumbs up.
Haven't had time to look through it closely, indentation could be better though, and in the beginning you might want to assign Item(itemEx.uid) to a variable instead of calling the constructor several times. You can also use isItem() and isCreature(), to see if it's an item or a creature.
Didn't see any obvious faults though, just that the attachment could have been a Lua file instead of a txt.

It's meant as constructive criticism, no offence intended.
 
Just curious about this piece of code
Code:
local caster = player

You could have just replaced
Code:
function onUse(player, item, fromPosition, itemEx, toPosition, isHotkey)
with
Code:
function onUse(caster, item, fromPosition, itemEx, toPosition, isHotkey)

And then swapped out player for caster, example
Code:
caster:sendTextMessage

Since the parameter caster / player is just a place holder and can be named anything as long as the values passed match the methods

Also why didn't you just add this to config?
Code:
local exhaust = Condition(CONDITION_EXHAUST_HEAL, CONDITIONID_HEAD)
local cooldown = Condition(CONDITION_SPELLCOOLDOWN, CONDITIONID_HEAD)

Why is config global? Is this script imported elsewhere?

I know you said you were in a rush to release it but its a good idea to be clear about what each variable or table is like you have potion.level and then you have level which can be confusing to people when they have changed your script around for their own purposes and then run into a problem because they either don't know lua or just thought it was unnecessary at the time.

I'm sure it could be shortened up a bit but good job!
Thank you for your contribution to the community :)
 
@forgee I seen that about item.uid is and thought about it but felt like it wasn't being used enough to add another line. I didn't use isItem () or isCreature I thought because those were probably in compat.lua (didn't check), and I was trying to do it in a learning type process and did optimizations like that later and missed it. Thanks! As for the .lua instead of .txt it wouldn't let me for some reason said invalid extension.

@artofwork I had no idea I could actually replace the parameter like that. That is great to know thank you very much. As for the script being used elsewhere it is not. I am still new to tables and was going off of the script thia one was based off of, the only other TFS 1.0 potions script for percents. As for the condition in the configuration that is a good idea.

Thanks both of you, when I get home going to work on updating this, on my phone right now, sorry for any typos this autocorrect sux.
 
Last edited:
Ok guys I am working on fixing all the things you pointed out. @Limos thanks for the like and the tutorial. I have tried to adjust my indentation accordingly. Anyways @forgee, I didn't really care for the idea of using anything that is in a lib, simply because I wanted it to be a self-contained script, without any dependencies, however seeing as how much code it would remove from my script, I believe I am going to go ahead and incorporate that as well. I believe with this update I am working on, I should be within the character limit. Anyways I did find a bug in the script after playing around with it and trying to see if I could move some stuff and change some stuff. The line that checks if there CGID and CPID aren't 0, it will execute even when you use it on yourself. I had made a quick fix by adding local cast = false, and after each addhealth adding cast = true, then checking for the in the same line checking for CGID and CPID, now that I am typing this out, I believe I have already figured out a better way would be to just move the line inside the check for if the creature is a monster....

Hopefully an updated version for this will be done by the weekend.... I suppose the thread would get more attention with some .gifs too, so I will work on that as well. Thanks everyone :D
 
I was way off about the characters, I didn't realize there was another zero in there, im up to the ten thousands for amount of characters. As for the isItem(), and isSummon() I am not going to use because: For the summon, I create a meta table in my script that gets used several times the way I use it, as for the isItem, its the same thing as the new way I have written it. local targetItem=Item(itemEx.uid). if targetItem then. That checks to see if it's an Item meta class (i think thats the right word, meta class?), and only works if it is, so wouldn't this be same as Item(itemEx.uid):isItem()? I don't know. I am using an TFS 1.0 not 1.1, but my 1.0 has altered source I have added, soon I will update it all to 1.1 and just reapply all the source edits I have made. Then I will convert it to 1.1 and I believe in 1.1 I can just use targetItem (replacement parameter for itemEx) and it already pushes the user data so I don't have to pull the uid, that would make the script a whole lot simpler.

@Limos, soon I will post an update to the original. Please let me know what you think about the tabbing used now.

Last thing I think I have to do before releasing here again (aside from complete debugging again (im ocd)), is just clear up some variables as @artofwork pointed out...
 
I just wanted to show you something because even this is a bit much for me hehe

Code:
local p = {} -- call this somewhere outside of onUse()
p = -- keeping it simple, define this in onUse
        {
            CGID = 0,
            CPID = 0,
            mlevel = caster:getMagicLevel(),
            plevel = caster:getLevel(),
            potion = POTIONS[item.itemid],
            exhaust = config.exhaust,
            cooldown = config.cooldown,
            targetItem = Item(itemEx.uid),
            target = Creature(itemEx.uid),
            pos = caster:getPosition(),
            voc = caster:getVocation():getId(),
            groupaccess = caster:getGroup():getAccess()
        }
        -- might seem confusing but were updating the table with values from the table
        --[[
                example
            local p = {} -- empty table
                 p = {a = 1}
                 p.b = p.a -- assign p.a value to p.b
                 -- and tada
                 p = {a = 1, b = 1}
        ]]
        p.healthmax = p.target:getMaxHealth()
        p.manamax = p.target:getMaxMana()
        p.hpPercent = p.potion.healthpercent
        p.health = p.potion.health
        p.mpPercent = p.potion.manapercent
        p.mana = p.potion.mana

Then you can just call p.voc or p.groupaccess to keep it less messy, but also so you can pass the whole table to another function
Like this, no need to re-declare stuff because its already been done
Code:
function addHPorMana(p) -- the p table is passed to here
    if p.target:isPlayer() then
        if p.health == true then
            p.target:addHealth( math.random((((p.healthmax/100)*p.hpPercent ) + ((p.level/12)*config.lvl ) + ((p.mlevel/18)*config.mlvl ))*config.forMin, ((((p.healthmax/100)*p.hpPercent ) + ((p.level/12)*config.lvl )+ ((p.mlevel/18))*config.mlvl )*config.forMax)))
        end
        if p.mana == true then
            p.target:addMana( math.random((((p.manamax/100)*p.mpPercent ) + ((p.level/18)*config.lvl ) + ((p.mlevel/12)*config.mlvl ))*config.forMin, ((((p.manamax/100)*p.mpPercent ) + ((p.level/18)*config.lvl )+ ((p.mlevel/12))*config.mlvl )*config.forMax)))
        end
    end
end

-- onUse is somewhere down here

p = -- is defined inside of onUse

addHPorMana(p) -- you call it in here


If you notice programming is not exactly read from right to left.. but more like up left sideways upsidedown lol

Tables are fun but functions are better, you need to learn to consolidate code while making it reusable.
 
I just wanted to show you something because even this is a bit much for me hehe

Code:
local p = {} -- call this somewhere outside of onUse()
p = -- keeping it simple, define this in onUse
        {
            CGID = 0,
            CPID = 0,
            mlevel = caster:getMagicLevel(),
            plevel = caster:getLevel(),
            potion = POTIONS[item.itemid],
            exhaust = config.exhaust,
            cooldown = config.cooldown,
            targetItem = Item(itemEx.uid),
            target = Creature(itemEx.uid),
            pos = caster:getPosition(),
            voc = caster:getVocation():getId(),
            groupaccess = caster:getGroup():getAccess()
        }
        -- might seem confusing but were updating the table with values from the table
        --[[
                example
            local p = {} -- empty table
                 p = {a = 1}
                 p.b = p.a -- assign p.a value to p.b
                 -- and tada
                 p = {a = 1, b = 1}
        ]]
        p.healthmax = p.target:getMaxHealth()
        p.manamax = p.target:getMaxMana()
        p.hpPercent = p.potion.healthpercent
        p.health = p.potion.health
        p.mpPercent = p.potion.manapercent
        p.mana = p.potion.mana

Then you can just call p.voc or p.groupaccess to keep it less messy, but also so you can pass the whole table to another function
Like this, no need to re-declare stuff because its already been done
Code:
function addHPorMana(p) -- the p table is passed to here
    if p.target:isPlayer() then
        if p.health == true then
            p.target:addHealth( math.random((((p.healthmax/100)*p.hpPercent ) + ((p.level/12)*config.lvl ) + ((p.mlevel/18)*config.mlvl ))*config.forMin, ((((p.healthmax/100)*p.hpPercent ) + ((p.level/12)*config.lvl )+ ((p.mlevel/18))*config.mlvl )*config.forMax)))
        end
        if p.mana == true then
            p.target:addMana( math.random((((p.manamax/100)*p.mpPercent ) + ((p.level/18)*config.lvl ) + ((p.mlevel/12)*config.mlvl ))*config.forMin, ((((p.manamax/100)*p.mpPercent ) + ((p.level/18)*config.lvl )+ ((p.mlevel/12))*config.mlvl )*config.forMax)))
        end
    end
end

-- onUse is somewhere down here

p = -- is defined inside of onUse

addHPorMana(p) -- you call it in here


If you notice programming is not exactly read from right to left.. but more like up left sideways upsidedown lol

Tables are fun but functions are better, you need to learn to consolidate code while making it reusable.

I didn't realize I could set that all inside a table, then create a function like that, and use the tables data later on the way you did that. It was great. I don't think of it as something necessary here per se, since I have made for the people what I wanted to make, however for my private potions system in which I will incorporate all kinds of liquids and conditions and uses for the potions, this is brilliant! That is why I love Otland, I am learning everytime I visit. Thanks :D
 
exelent i used tfs 1.0

and i need one script potion : player to level its low 100 not can use potion in friends


can help me ?
 
I get the following error in the console to use a potion

Pwyav5p.png


use TFS 1.0
 
This was written for 1.
I get the following error in the console to use a potion

Pwyav5p.png


use TFS 1.0

I need to see the script, did you alter it? Because on the one I posted it doesn't have caster on line 43. And its not on line 28 either. Plus it doesn't make sense, why would it just now be having a problem with caster, when caster is used plenty more times before that line.... :(
 
http://www.speedy*****malware.localhost/g5rkV/potions.lua
so I have

so I have, excuse my english
 
You removed the credits, that is why the lines are not the same as what I have. Anyways, change

Code:
function onUse(caster, item, fromPosition, itemEx, toPosition, isHotkey)

to

Code:
function onUse(cid, item, fromPosition, itemEx, toPosition, isHotkey)
local caster = Player(cid)

and that should solve the problem. Anyone else who has this problem is because they are using an older version of tfs 1.x that userdata is not passed, but cid is passed instead.
 
Back
Top