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

[LUA] How to make a simple spell script.

Animera

* * * * *
Joined
Dec 9, 2008
Messages
2,432
Solutions
5
Reaction score
603
Location
ANIMERA.ONLINE
Simple spell script by Animera.
Since the most people nowdays can't even script the most simple things i was searching for my friend a spell tutorial however they are all outdated so i decided to make my own tutorial. Today we are just going to edit a very simple script. But you will at least learn the basics.

Recommended:
Notepad++ (Link)

First open a spell you want to edit: I am going to edit the eternal winter.
data/spells/attack/eternal winter.lua
Now we got something like this
Code:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE)
setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_ICETORNADO)
setAttackFormula(combat, COMBAT_FORMULA_LEVELMAGIC, 2, 4, 3, 10)
local area = createCombatArea(AREA_CROSS5X5)
setCombatArea(combat, area)
function onCastSpell(cid, var)
return doCombat(cid, combat, var)
end
Code:
local combat = createCombatObject()
Nothing special but this is required if you want your spells get some extra things.
See it like a map, local combat~ is the map and it contain files it contains X and X and X etc. What those X are you will find it now out.
Code:
setCombatParam(combat, ***COMBAT_PARAM_TYPE***, COMBAT_ICEDAMAGE
This is one of the so called "file", but how can i see what it does?, i marked it with the 3 ***, as you saw on the last word it contained type, wich means what kind of damage it deals, I want it deals ice damage so i won't edit that but there are several kind of damages you want to choose.
Code:
COMBAT_NONE = 0
COMBAT_PHYSICALDAMAGE = 1
COMBAT_ENERGYDAMAGE = 2
COMBAT_EARTHDAMAGE = 4
COMBAT_POISONDAMAGE = 4
COMBAT_FIREDAMAGE = 8
COMBAT_UNDEFINEDDAMAGE = 16
COMBAT_LIFEDRAIN = 32
COMBAT_MANADRAIN = 64
COMBAT_HEALING = 128
COMBAT_DROWNDAMAGE = 256
COMBAT_ICEDAMAGE = 512
COMBAT_HOLYDAMAGE = 1024
COMBAT_DEATHDAMAGE = 2048
Instead of filling combat_deathdamage or something you could also use these numbers, but i recommend for people who are new with this to use the combat~ so you can easy read back what damage it deals.
Code:
setCombatParam(combat, ***COMBAT_PARAM_EFFECT***, CONST_ME_ICETORNADO)
This is another of the so called "file" but this one shows the effect, This time i am going to edit it in an other effect. so i use the "CONST_ME_ICETORNADO" to
Code:
setCombatParam(combat, ***COMBAT_PARAM_EFFECT***, CONST_ME_ICEATTACK)
Here is the list of options:
Code:
CONST_ME_DRAWBLOOD = 0
CONST_ME_LOSEENERGY = 1
CONST_ME_POFF = 2
CONST_ME_BLOCKHIT = 3
CONST_ME_EXPLOSIONAREA = 4
CONST_ME_EXPLOSIONHIT = 5
CONST_ME_FIREAREA = 6
CONST_ME_YELLOW_RINGS = 7
CONST_ME_GREEN_RINGS = 8
CONST_ME_HITAREA = 9
CONST_ME_TELEPORT = 10
CONST_ME_ENERGYHIT = 11
CONST_ME_MAGIC_BLUE = 12
CONST_ME_MAGIC_RED = 13
CONST_ME_MAGIC_GREEN = 14
CONST_ME_HITBYFIRE = 15
CONST_ME_HITBYPOISON = 16
CONST_ME_MORTAREA = 17
CONST_ME_SOUND_GREEN = 18
CONST_ME_SOUND_RED = 19
CONST_ME_POISONAREA = 20
CONST_ME_SOUND_YELLOW = 21
CONST_ME_SOUND_PURPLE = 22
CONST_ME_SOUND_BLUE = 23
CONST_ME_SOUND_WHITE = 24
CONST_ME_BUBBLES = 25
CONST_ME_CRAPS = 26
CONST_ME_GIFT_WRAPS = 27
CONST_ME_FIREWORK_YELLOW = 28
CONST_ME_FIREWORK_RED = 29
CONST_ME_FIREWORK_BLUE = 30
CONST_ME_STUN = 31
CONST_ME_SLEEP = 32
CONST_ME_WATERCREATURE = 33
CONST_ME_GROUNDSHAKER = 34
CONST_ME_HEARTS = 35
CONST_ME_FIREATTACK = 36
CONST_ME_ENERGYAREA = 37
CONST_ME_SMALLCLOUDS = 38
CONST_ME_HOLYDAMAGE = 39
CONST_ME_BIGCLOUDS = 40
CONST_ME_ICEAREA = 41
CONST_ME_ICETORNADO = 42
CONST_ME_ICEATTACK = 43
CONST_ME_STONES = 44
CONST_ME_SMALLPLANTS = 45
CONST_ME_CARNIPHILA = 46
CONST_ME_PURPLEENERGY = 47
CONST_ME_YELLOWENERGY = 48
CONST_ME_HOLYAREA = 49
CONST_ME_BIGPLANTS = 50
CONST_ME_CAKE = 51
CONST_ME_GIANTICE = 52
CONST_ME_WATERSPLASH = 53
CONST_ME_PLANTATTACK = 54
CONST_ME_TUTORIALARROW = 55
CONST_ME_TUTORIALSQUARE = 56
CONST_ME_MIRRORHORIZONTAL = 57
CONST_ME_MIRRORVERTICAL = 58
CONST_ME_SKULLHORIZONTAL = 59
CONST_ME_SKULLVERTICAL = 60
CONST_ME_ASSASSIN = 61
CONST_ME_STEPSHORIZONTAL = 62
CONST_ME_BLOODYSTEPS = 63
CONST_ME_STEPSVERTICAL = 64
CONST_ME_YALAHARIGHOST = 65
CONST_ME_BATS = 66
CONST_ME_SMOKE = 67
CONST_ME_INSECTS = 68
CONST_ME_NONE = 255
CONST_ME_LAST = CONST_ME_INSECTS
There are a lot of ways to find out how to know what does what..
1. use the /z (effectnumber) command ingame
2. check your other script files
3. or check this link: Lua - Spells Effects
Like i said before instead writing CONST_ME~ you can also using numbers like:
Code:
setCombatParam(combat, ***COMBAT_PARAM_EFFECT***, 43)
So we got now the damage type and the effect now the formula,
Code:
setAttackFormula(combat, COMBAT_FORMULA_LEVELMAGIC, 2, 4, 3, 10)
This is the formula, but i don't know how this new formula system works, i use another one i will explain in the next post. IF you just wanna use this system then experiment it with it. there are more formula's like
Code:
COMBAT_FORMULA_UNDEFINED = 0
COMBAT_FORMULA_LEVELMAGIC = 1
COMBAT_FORMULA_SKILL = 2
COMBAT_FORMULA_DAMAGE = 3
But now after all these things how does the SERVER know that the so called files belogns to that map?
Code:
1. local combat = createCombatObject()
2. setCombatParam(***combat***, COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE)
As you see on 1 it says local "combat"
and on the second you see between the *** as kind of proof that they fit together.
Now we fixed the first part.
I will write now the second.
 
Last edited:
Part 2 the area and such.
Now you see these 2 lines
Code:
1. local area = createCombatArea(AREA_CROSS5X5)
2. setCombatArea(***combat, area***)
As you see on 1. it shows that the area is AREA_CROSS5X5 but what is it?
I will show it later. Now look at 2. we see the so called map combat AND area
kind of connection between are and effect/damage etc.
Now we open another file
data/spells/lib/spells.lua
Here is a lot to see but the reason it stays here to shorten much scripts with same spell sizes, so here you can register your selfmade area's but i won't recommend it if you make a selfmade area for just 1 single spell. IF you want to edit all the size with the same area like hell's core then just use search function(ctrl+f) and search for AREA_CROSS5X5
Then you will find this:
Code:
AREA_CROSS5X5 = {
{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
{0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
{1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1},
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
{0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}
}
But what does it mean? each number 3 represent the place of the caster, 1 represents area, and 0 is just a empty onused field. but why do we use 0? because you will get a strange form i will show you:
Code:
{1},
{1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1},
{1}
A total different shape o_O however if you want to edit just an area for 1 spell then i recommend to do the following things
change
Code:
local area = createCombatArea(AREA_CROSS5X5)
to
Code:
local area = createCombatArea(arr1)
local arr1 = {
{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
{0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
{1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1},
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
{0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}
}
Then you can just edit the area for only this spell.
Then we got like this:
Code:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE)
setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_ICEATTACK)
setAttackFormula(combat, COMBAT_FORMULA_LEVELMAGIC, 2, 4, 3, 10)
local arr1 = {
{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
{0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
{1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1},
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
{0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}
}
local area = createCombatArea(arr1)
setCombatArea(combat, area)
function onCastSpell(cid, var)
return doCombat(cid, combat, var)
end
IF you want to make it bigger just change the 0 to 1 or vice versa.
now we get to the last part:
Code:
1.function onCastSpell(cid, var)
2. return doCombat(cid, combat, var)
3. end
This is a very simple part here you have to edit nothing i will just explain what it means.
1. Means what happens when you cast a spell.
2. Means that it will use the so called map combat with the "setCombatArea(combat, area)" damage and effect and area got together.
3. Means it is the end of the script.
As you saw i didn't edited much in the script just the effect, but with this tutorial it is easier to understand what everything means and would make editing way easier. I am gonna write now part 3.
 
Last edited:
Registering your spell
After creating your spell, what now? You could save it so your script that you made will be edited or you could save as to X file name and i will explain how to register the spell.
go to data/spells/spells.xml
because mine spell is simliar with eternal winter. I just copy the one where my eternal winter got registered
Code:
 <instant name="Eternal Winter" words="exevo gran mas frigo" lvl="60" mana="1200" prem="1" selftarget="1" exhaustion="2000" needlearn="0" event="script" value="attack/eternal winter.lua">
<vocation id="2"/>
<vocation id="6"/>
</instant>
This is a very easy part you have to fill in the following things:
instant name=""
Code:
Fill in the name of your new spell.
words=""
Code:
Fill in what you have to say to cast the spell.
lvl=""
Code:
 The level requirements.
mana=""
Code:
How much mana cost.
prem=""
Code:
 Premium required yes or no, 1 = yes 0 = no
selftarget=""
Code:
same as above 1 = yes and 0 = no but by writing 1 means it cast on yourself like in the number 3 of the area script, 0 i used as far as i know for distance spells) but to erase this from the register is same as 0 so its not required for distance spells.
exhaustion=""
Code:
 how much miliseconds you get exhausted remember its milisecond so 1000 milisecond is like 1 second.
needlearn=""
Code:
Does the player need to learn this, or people get automatic by reaching the level, same again with 1 and 0 but i recommend to use 0 if you aren't a good scripter.
event="script"
Code:
Event could be script or function, function is for some proffesional scripters that could make their own functions instead a lua script.
value=""
Code:
here you can write the function or the script file but because it is script you have to write this time the place where your script file is saved.
Now the last part:
Code:
<vocation id="X"/> X can be any number between 0-8.
But what vocation is what?
If you use custom vocations then check your vocations.xml or else check this list.
Code:
0. Rookgaard
1. Sorcerer
2. Druid
3. Paladin
4. Knight
5. Master sorcerer
6. Elder druid
7. Royal paladin
8. Elite knight
 
Last edited:
A little more things.

I made just an area spell, But in the createcombatarea a distance spell use one more thing.
Code:
setCombatParam(combat, COMBAT_PARAM_DISTANCEEFFECT, X)
X could be a number or const_ani~
Code:
CONST_ANI_SPEAR = 0
CONST_ANI_BOLT = 1
CONST_ANI_ARROW = 2
CONST_ANI_FIRE = 3
CONST_ANI_ENERGY = 4
CONST_ANI_POISONARROW = 5
CONST_ANI_BURSTARROW = 6
CONST_ANI_THROWINGSTAR = 7
CONST_ANI_THROWINGKNIFE = 8
CONST_ANI_SMALLSTONE = 9
CONST_ANI_DEATH = 10
CONST_ANI_LARGEROCK = 11
CONST_ANI_SNOWBALL = 12
CONST_ANI_POWERBOLT = 13
CONST_ANI_POISON = 14
CONST_ANI_INFERNALBOLT = 15
CONST_ANI_HUNTINGSPEAR = 16
CONST_ANI_ENCHANTEDSPEAR = 17
CONST_ANI_REDSTAR = 18
CONST_ANI_GREENSTAR = 19
CONST_ANI_ROYALSPEAR = 20
CONST_ANI_SNIPERARROW = 21
CONST_ANI_ONYXARROW = 22
CONST_ANI_PIERCINGBOLT = 23
CONST_ANI_WHIRLWINDSWORD = 24
CONST_ANI_WHIRLWINDAXE = 25
CONST_ANI_WHIRLWINDCLUB = 26
CONST_ANI_ETHEREALSPEAR = 27
CONST_ANI_ICE = 28
CONST_ANI_EARTH = 29
CONST_ANI_HOLY = 30
CONST_ANI_SUDDENDEATH = 31
CONST_ANI_FLASHARROW = 32
CONST_ANI_FLAMMINGARROW = 33
CONST_ANI_SHIVERARROW = 34
CONST_ANI_ENERGYBALL = 35
CONST_ANI_SMALLICE = 36
CONST_ANI_SMALLHOLY = 37
CONST_ANI_SMALLEARTH = 38
CONST_ANI_EARTHARROW = 39
CONST_ANI_EXPLOSION = 40
CONST_ANI_CAKE = 41
CONST_ANI_WEAPONTYPE = 254
CONST_ANI_NONE = 255
CONST_ANI_LAST = CONST_ANI_CAKE
There are lot of distance effect. the only way to find it out wich is what is
to copy from other spells, or use the /x (number) command ingame.
also in the spells.xml there are some things different like:
range="3"
Code:
How much sqm distance can you shoot it
casterTargetOrDirection="1"
Code:
 Example i have a distance area spell that isn't the same on other sides then it will change on direction
like this
wyTGKdzflU.png

blockwalls="1"
Code:
can the spell go trough walls or not
IF you wanna look what things you could use check the library
data/lib/000-constant.lua There stays the whole list.
 
Last edited:
More advanced

As i promised i will show a better formula style, wich i can at least.
Change
Code:
setAttackFormula(combat, COMBAT_FORMULA_LEVELMAGIC, 2, 4, 3, 10)
to
Code:
function onGetFormulaValues(cid, level, maglevel)
min = -(level * X + maglevel * X) * X
max = -(level * X + maglevel * X) * X
return min, max
end
setCombatCallback(combat, CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")
How does this work example this is mine formula and i am level 100 with m lvl 100.
Code:
min = -(level * 3 + maglevel * 4) * 2
max = -(level * 5 + maglevel * 8) * 2
1. Then the minimal damage i deal is (100 x 3 = 300) + (100x4=400) wich is 700 x 2 = 1400.
2. the maximal damage i deal is (100x5=500)+(100x8=800) wich is 1300 x 2 = 2600.
3. So beween 1400-2600 but it could be lower it depends on how much resistance the creature got.
You are also able to add a condition to your spells like this:
Code:
local condition = createConditionObject(CONDITION_ENERGY)
setConditionParam(condition, CONDITION_PARAM_DELAYED, 1)
addDamageCondition(condition, 1, 5000, -20)
addDamageCondition(condition, 1, 5000, -20)
addDamageCondition(condition, 1, 5000, -20)
setCombatCondition(combat, condition)
As you see on the local condition its a condition that gives you same condition like walking in a energy field.
There are several conditions like
Code:
CONDITION_NONE = 0
CONDITION_POISON = 1
CONDITION_FIRE = 2
CONDITION_ENERGY = 4
CONDITION_PHYSICAL = 8
CONDITION_HASTE = 16
CONDITION_PARALYZE = 32
CONDITION_OUTFIT = 64
CONDITION_INVISIBLE = 128
CONDITION_LIGHT = 256
CONDITION_MANASHIELD = 512
CONDITION_INFIGHT = 1024
CONDITION_DRUNK = 2048
CONDITION_EXHAUST = 4096
CONDITION_FOOD = 8192
CONDITION_REGENERATION = 8192
CONDITION_SOUL = 16384
CONDITION_DROWN = 32768
CONDITION_MUTED = 65536
CONDITION_ATTRIBUTES = 131072
CONDITION_FREEZING = 262144
CONDITION_DAZZLED = 524288
CONDITION_CURSED = 1048576
CONDITION_PACIFIED = 2097152
CONDITION_GAMEMASTER = 4194304
CONDITION_HUNTING = 8388608
and the
Code:
addDamageCondition(condition, 1, 5000, -20)
It does damage,
condition means that is used the energy condition, the "1" i forgot what it does, the 5000 is milisecond after how much the damage will appear, and the last one how much the energy deals.
And the last one is kind of proof that condition appear after the combat.
 
Last edited:
really good tut

this will help alot of noobs like me :D
 
Last edited:
This script is obvious. Sometimes, I just don't get people, which can't do any things like that.
Ekhmm... Leave this topic - good luck, guys... This should help you! =)
 
@up yes i agree on that, but i see so much download and run and real map servers with owners with no experience in anything, instead of crying about it i create instead a way too advanced tutorial, so they learn at least something themselves. First i just made this for 1 specific guy, but it seems there are more people who needed this then i tought hehe
 
COMBAT_NONE = 0
COMBAT_PHYSICALDAMAGE = 1
COMBAT_ENERGYDAMAGE = 2
COMBAT_EARTHDAMAGE = 4
COMBAT_POISONDAMAGE = 4
COMBAT_FIREDAMAGE = 8
COMBAT_UNDEFINEDDAMAGE = 16
COMBAT_LIFEDRAIN = 32
COMBAT_MANADRAIN = 64
COMBAT_HEALING = 128
COMBAT_DROWNDAMAGE = 256
COMBAT_ICEDAMAGE = 512
COMBAT_HOLYDAMAGE = 1024
COMBAT_DEATHDAMAGE = 2048
[/code]


I will write now the second.


How can i add more then 15 COMBATS? Like GRASS_DAMAGE or WATER_DAMAGE?
i need more types of damage.
 
at the same time? then you have to create a animated spell.. I won't recommend them since the most looks gay, or its just so messed up. I only require it when you know how to make it. Good question since i didn't made a tut about that. I think i will soon.. In the meanwhile ask at the request boards.
 
Back
Top