Animera
* * * * *
Dear folks!
For a long time i wanted to give something back to the community, as i've received many support here myself (from questions in my 'noob times', to the development of TFS in general).
But i didn't want to share just 'something'. But something that may be usefull in general (for all kinds of servers). I have some other plans of scripts that i gonna release in the near future (that i actually made for my server, but this i just scripted it out of boredom).
Spell Level system: How does it work ?
By casting spells, the individual spell will gain 'skilltries', if the spell levels up, it increases in damage and/or area. Optionable with a level cap. (The level system is storage based, so if you're a bit handy with scripts you could even make quests that upgrade a spell or something else).
To make use of the spell level system you would need to have the more flexible spell system setup of mine, which can be found here:
Do not get confused with different text colors, spell cast effects, leech/crit effect, i used whirlwind blade lv1 as a example as it is the 'exori/berserk' spell compared to the vanilla servers...
Flexible Spells Lib How does it work ?
As many of us know that combat area's need to be set up on beforehand, which reduces the manipulation options if we want to change the size/shape of a certain spell by using factors that can only be calculated when it get's 'casted'.. Glad we can index areas beforehand in combination of the doAreaCombatHealth function to create a more flexible system (and it's more simple if you ask me...).
This does means if you want to use it you need to rewrite all your spells, or just the spells that you want to make use of this flexible spell system (e.g. the spell level system).
Because i was lazy i used codex NG custom skill system for the spells (which was just what i needed anyway lol, no reason to reinvent the wheel. RIP buddy).
Example of usage (This is a berserk spell):
Create a new file -> data/lvlspellslib.lua
data/global.lua - Add this somewhere on the first lines.
data/global.lua - Add this somewhere in the file (Credits to codex NG for writing the custom skill functions!)
data/globalevents/startup.lua - Add this somewhere before the startup function!
Create a new file called creaturescripts/firstlogin.lua (or paste it wisely in login.lua, if you know the first login block)
Animera
For a long time i wanted to give something back to the community, as i've received many support here myself (from questions in my 'noob times', to the development of TFS in general).
But i didn't want to share just 'something'. But something that may be usefull in general (for all kinds of servers). I have some other plans of scripts that i gonna release in the near future (that i actually made for my server, but this i just scripted it out of boredom).
Spell Level system: How does it work ?
By casting spells, the individual spell will gain 'skilltries', if the spell levels up, it increases in damage and/or area. Optionable with a level cap. (The level system is storage based, so if you're a bit handy with scripts you could even make quests that upgrade a spell or something else).
To make use of the spell level system you would need to have the more flexible spell system setup of mine, which can be found here:
Do not get confused with different text colors, spell cast effects, leech/crit effect, i used whirlwind blade lv1 as a example as it is the 'exori/berserk' spell compared to the vanilla servers...
Flexible Spells Lib How does it work ?
As many of us know that combat area's need to be set up on beforehand, which reduces the manipulation options if we want to change the size/shape of a certain spell by using factors that can only be calculated when it get's 'casted'.. Glad we can index areas beforehand in combination of the doAreaCombatHealth function to create a more flexible system (and it's more simple if you ask me...).
This does means if you want to use it you need to rewrite all your spells, or just the spells that you want to make use of this flexible spell system (e.g. the spell level system).
Because i was lazy i used codex NG custom skill system for the spells (which was just what i needed anyway lol, no reason to reinvent the wheel. RIP buddy).
Example of usage (This is a berserk spell):
Code:
local spellname, effect, area, damagetype = "Berserk", CONST_ME_HITAREA, "AREA_SQUARE1X1", COMBAT_PHYSICALDAMAGE
function onCastSpell(creature, variant)
local lvl, mlvl, skill, attack = creature:getLevel(), creature:getMagicLevel(), creature:getWepSkill(), creature:getAtk()
local min = (lvl / 5) + ((skill * 2) + attack) * 0.5
local max = (lvl / 5) + ((skill * 2) + attack) * 1.5
return creature:doLevelCombat(variant, spellname, effect, area, damagetype, min, max)
end
Create a new file -> data/lvlspellslib.lua
Code:
----------------------------------------------------------------------------------------------------------
-- Flexible Spells System Written by @Animera from Otland.net --
-- --
-- Want to see more awesome features? Check my server: Animera.Online --
-- Want a awesome feature yourself? I also take occasionaly jobs as freelancer. PM @ Otland --
----------------------------------------------------------------------------------------------------------
SPELLS_LEVEL_LIST = {
["Berserk"] = {lvlstorage = 1000, dmgmultiplier = 1.1, increaseSize = true, maxlvl = 5}, -- multiplier for every lvl!
["Energy Beam"] = {lvlstorage = 1001, dmgmultiplier = 1.5, increaseSize = false, maxlvl = 100},
["Eternal Winter"] = {lvlstorage = 1002, dmgmultiplier = 1.2, increaseSize = false, maxlvl = 200}
}
function Player:doLevelCombat(variant, spellname, effect, area, damagetype, min, max)
local spelllvl = SPELLS_LEVEL_LIST[spellname].lvlstorage
local mox = self:lvlDmg(spellname, SPELLS_LEVEL_LIST[spellname].lvlstorage, min, max)
if doAreaCombatHealth(self, damagetype, variant:getNumber() > 0 and variant:getPosition() or self:getPosition(), getSpellArea(area, spellname, self:getStorageValue(spelllvl)), -mox, -mox, effect) == true then
if SPELLS_LEVEL_LIST[spellname] then
if self:getStorageValue(spelllvl) < SPELLS_LEVEL_LIST[spellname].maxlvl then
self:addCustomSkillTry(spellname, spelllvl)
end
end
return true
end
return false
end
function getSpellArea(defaultarea, spellname, level)
level = level - 1
for i = 1, #SPELLS_LEVEL_AREAS do
if SPELLS_LEVEL_AREAS[i] == defaultarea then
if SPELLS_LEVEL_LIST[spellname] then
if not SPELLS_LEVEL_LIST[spellname].increaseSize then
return arrs[i]
end
end
if i+level < #SPELLS_LEVEL_AREAS then -- to prevent bug if reached last array..
return arrs[i+level]
else
print(">> Spell level system warning: Spell has reached maximum potential, create more areas or lower max level limit.")
return arrs[#arrs] -- just use biggest area then...
end
end
end
end
function Player:lvlDmg(spellname, lvlstorage, min, max)
if SPELLS_LEVEL_LIST[spellname] then
local level, mult = self:getStorageValue(SPELLS_LEVEL_LIST[spellname].lvlstorage), (SPELLS_LEVEL_LIST[spellname].dmgmultiplier - 1)
min = min * (1 + ((level * mult)))
max = max * (1 + ((level * mult)))
return math.random(min, max)
end
print(">> Spell level system warning: This spell isn't registered yet.")
return math.random(min, max)
end
function Player:getAtk()
local hands = {CONST_SLOT_LEFT, CONST_SLOT_RIGHT}
for i = 1, #hands do
local wep = self:getSlotItem(hands[i])
if wep then
if wep:getType():getAttack() > 0 and wep:getType():getWeaponType() > 0 then
return wep:getType():getAttack(), wep:getType():getWeaponType()
end
end
end
return 0
end
function Player:getWepSkill()
local hands = {CONST_SLOT_LEFT, CONST_SLOT_RIGHT}
for i = 1, #hands do
local wep = self:getSlotItem(hands[i])
if wep then
if wep == 1 then return self:getEffectiveSkillLevel(SKILL_SWORD)
elseif wep == 2 then return self:getEffectiveSkillLevel(SKILL_CLUB)
elseif wep == 3 then return self:getEffectiveSkillLevel(SKILL_AXE)
end
end
end
return 10
end
data/global.lua - Add this somewhere on the first lines.
Code:
dofile('data/lvlspellslib.lua')
data/global.lua - Add this somewhere in the file (Credits to codex NG for writing the custom skill functions!)
Code:
function Player:getCustomSkill(storage)
return self:getStorageValue(storage)
end
function Player:addCustomSkill(skillName, storage)
local skillStorage = math.max(1, self:getStorageValue(storage))
local skillTries = math.max(0, self:getStorageValue(storage + 1))
self:setStorageValue(storage, skillStorage + 1)
self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You advanced to " .. string.lower(skillName) .. " level "..self:getCustomSkill(storage)..".")
self:getPosition():sendMagicEffect(math.random(29,31))
self:setStorageValue(storage + 1, 0)
end
function Player:addCustomSkillTry(skillName, storage)
local skillStorage = math.max(1, self:getStorageValue(storage))
local skillTries = math.max(0, self:getStorageValue(storage + 1))
self:setStorageValue(storage + 1, skillTries + 1)
if skillTries > math.floor(20 * math.pow(1.1, (skillStorage - 11)) / 10) then
self:addCustomSkill(skillName, storage)
end
end
function Player:getCustomSkillPercent(storage)
local skillStorage = math.max(1, self:getStorageValue(storage))
local skillTries = math.max(0, self:getStorageValue(storage + 1))
local triesNeeded = math.floor(20 * math.pow(1.1, (skillStorage - 11)) / 10)
local percent = math.floor(100 * (1 - skillTries / triesNeeded))
if percent > 1 and percent <= 100 then
return percent
else
percent = 1
return percent
end
end
data/globalevents/startup.lua - Add this somewhere before the startup function!
Code:
dofile('data/spells/lib/spells.lua')
SPELLS_LEVEL_AREAS = { -- areas.. higher number is higher level, where spell starts is based on 'base area' exori starts at 1, gfb at 4...
[1] = "AREA_SQUARE1X1",
[2] = "AREA_SQUARE2X2",
[3] = "AREA_CIRCLE2X2",
[4] = "AREA_CIRCLE3X3",
[5] = "AREA_CROSS5X5"
}
arrs = {}
for y = 1, #SPELLS_LEVEL_AREAS do
table.insert(arrs, createCombatArea(_G[SPELLS_LEVEL_AREAS[y]]))
end
Create a new file called creaturescripts/firstlogin.lua (or paste it wisely in login.lua, if you know the first login block)
Code:
function setSpellLvl(self, count) -- reduces pressure on server launch, if you have a lot of spells...
if not count then count = 1 end
local self = Player(self)
if not self then return end
local voc = self:getVocation:getId()
if self:canLearnSpell(SPELLS_LEVEL_LIST[SPELLS[count]]) then
player:setStorageValue(SPELLS[count].lvlstorage, 1)
end
if count < #SPELLS then addEvent(setSpellLvl, 10, self:getId(), count+1) end
end
function onLogin(player)
if player:getLastLoginSaved() <= 0 then setSpellLvl(player:getId()) end
return true
end
Animera
Last edited: