YOU MUST KNOW SOMETHING ABOUT THE COMMANDS
if/then/else/elseif/end
PART 1: Scripts, and setting them up.
Scripts only know what you tell them, and they have to read everything in order.
The way to set a script up correctly is:
The first if is ended last. This means:
Code:
function
if1
if2
else2
end2
else1
end1
end function
In some cases this may differ, but for basic scripts it will look like this.
PART 2: GLOBAL / LOCAL values.
A global value is a value that the script already registers. Lets say we had this function.
function onUse(cid) -- The script now ONLY knows that if the item specified in XML file is used, then run this file. Right now, it would do NOTHING! exept load an error
--
Now the global event that is specified here is (cid). There is no value other then the server now knows (cid) is being used. It doesnt know who cid is, just that its a thing using the item.--
If we wanted to set that global value, so it registers something immidiatly, we can do this:
Lua:
cidname = "demon"
if not (getCreatureName(cid) == cidname) then
Know the script knows if its not a demon using the item. then immediatly end the script without doing anything (false).
You notice I put () around (getCreatureame(cid) == cidname) This is acually ONLY cutting memory usage down. It tells the script to load
(getCreatureName(cid) == cidname) instead of...getCreatureName(cid).....==......cidname.... Its nothing by itself, but with multiple scripts it will bog down.
A local value is just a value we give to the script to help us script. It would be something like this.
Lua:
function onUse(cid)
local vocation = getPlayerVocation(cid) --Must be after the function because cid is unregistered until then.--
if (vocation == 1) then
return true
end
end
This is saying if its a sorc, then true. In the game this would do nothing, the player would use the item, but nothing would happen.
Now we can also do this.
Lua:
if (vocation == 1) then
local money = 5000
elseif (vocation == 2)
local money = 6000
end
Now if you notice, I didnt tell the game to do anything. I just told it to get a value. Just showing this is a possibility.
PART 3: GETTING STARTED.
The first thing to do is study up on the LUA_FUNCTION that are givin. Check around Otland how some are used ect.
The next thing to do is figure out what script you need, and then how to create it.
The reason we want to think about "how" to create it first, is because we can create things to help us before starting, also we dont want to
start scripting one way and figure out it wont work.
Lets make a jailing script. First, what will we need?
1) A way to teleport them there
2) A way to teleport them out
Look how simple it seems, and if you learn the scripts, it is just as easy.
So, a way to get them there. Well, thank god for Gm's that can use talkactions. So we will make a talkaction.
So what function will tell us talkaction?
Lua:
function onSay(cid, words, param, channel)
Okay, now the server knows when I say the words specified in the XML file, start this file. (then error cuz theres nothing there.)
Lua:
function onSay(cid, words, param, channel)
if (param == "") then
return false
end
Now, You see I put if the player says nothing, return false. This doesn't SEEM nessacary. But there are commands that require you to specify the inital value.
In this case PARAM WILL NEED TO BE SPECIFIED. As of right now its speficied as NOT nothing, because if it was nothing, it would return false.
So now that the script is at param is not nothing. We can add this.
Lua:
function onSay(cid, words, param, channel)
if (param == "") then
return false
end
t = string.explode(param, "")
--This is telling the script that there will be more params used. (so not just !param, it will be !param param)--
--Now how do we call the second command?--
t[1] --We use t because its specified on the server as the explode.--
--if we put explode = string.explode(param, "") it would be-- explode[1]
--Now to make it a little easier to read then t[1] we can add this:--
t[1] = player
Now we can type player everytime we want to tell the script to call the second param said by the player.
Now we have:
Lua:
function onSay(cid, words, param, channel)
if (param == "") then
return false
end
t = string.explode(param, "")
t[1] = player
Now that we have all the information that the script needs before starting the script, we can start
Lua:
function onSay(cid, words, param, channel)
if (param == "") then
return false
end
t = string.explode(param, "")
t[1] = player
if getPlayerAccess(cid) >= 3 then
if (param == "/jail") then
if (isPlayer(player)) then
Im sure you can figure out what this is saying. You see (isPlayer(player)) The script will check and see if the second param said by the player, is acually a player.
Lua:
function onSay(cid, words, param, channel)
if (param == "") then
return false
end
t = string.explode(param, "")
t[1] = player
if getPlayerAccess(cid) >= 3 then
if (param == "/jail") then
if (isPlayer(player)) then
setPlayerStorageValue(player, Jailed, 1)
-- /\ Notice player is used and not CID, thats because the player we want to change is not cid (cid calls for the player used the scirpt unless specified as different as shown is PART 1)--
Storage values are one tibia scripts most loved functions. You can make anytype of storage and set a value on it.
We put jail, this is just so the storage name is jail, if we put apple it would be apple, if we put 30001, it would be the same as first player items, and probably cause an error.
That means we dont want to put storage values that are used
Lua:
local jailPos = {x = 1000, y = 1000, z = 7}
function onSay(cid, words, param, channel)
if (param == "") then
return false
end
t = string.explode(param, "")
t[1] = player
if getPlayerAccess(cid) >= 3 then
if (param == "/jail") then
if (isPlayer(player)) then
setPlayerStorageValue(player, Jailed, 1)
doTeleportThing(player, jailPos)
Used the first local now. The script will teleport the player. NOTE: Position automatically calls for XYZ.
Thats why jailPos will work, XYZ of jailPos is specified. (MAKE SURE YOU PUT THE NAME IN CORRECT WHEN PLACING A LOCAL VALUE IN THE SCRIPT! IT IS CAP SENSORED)
Lua:
local jailPos = {x = 1000, y = 1000, z = 7}
local MSG_TYPE = MESSAGE_STATUS_CONSOLE_RED
local jailMSG = "You have been jailed"
function onSay(cid, words, param, channel)
if (param == "") then
return false
end
t = string.explode(param, "")
t[1] = player
if getPlayerAccess(cid) >= 3 then
if (param == "/jail") then
if (isPlayer(player)) then
setPlayerStorageValue(player, Jailed, 1)
doTeleportThing(player, jailPos)
doPlayerSendTextMessage(player, MSG_TYPE, jailedMSG)
Added a few more locals, If I thought about the script before hand, these locals would be places already. But for tutorial purposes Im doing it this way.
The player will now get a message AFTER teleported. If you put it before he would get the message before (not that it matters here) but in some cases it does.
As this next function.
Lua:
local jailPos = {x = 1000, y = 1000, z = 7}
local MSG_TYPE = MESSAGE_STATUS_CONSOLE_RED
local jailMSG = "You have been jailed"
local EFFECT_TYPE = 10
function onSay(cid, words, param, channel)
if (param == "") then
return false
end
t = string.explode(param, "")
t[1] = player
if getPlayerAccess(cid) >= 3 then
if (param == "/jail") then
if (isPlayer(player)) then
setPlayerStorageValue(player, Jailed, 1)
doTeleportThing(player, jailPos)
doPlayerSendTextMessage(player, MSG_TYPE, jailedMSG)
doSendMagicEffect(jailPos, EFFECT_TYPE) -- If this was before the teleport it would send the effect before the player teleported (understand?)--
else
doPlayerSendCancel(cid, "This is not a player")
return false
end
Now we have our first else. The else is connected to the last IF used. That is why the cancel is "this is not a player" It is connected to the
(isPlayer(player))
Always make sure to return false on a else, UNLESS the else is directing the script to be true, then put return true.
Then end that if.
Lua:
local jailPos = {x = 1000, y = 1000, z = 7}
local MSG_TYPE = MESSAGE_STATUS_CONSOLE_RED
local jailMSG = "You have been jailed"
local EFFECT_TYPE = 10
function onSay(cid, words, param, channel)
if (param == "") then
return false
end
t = string.explode(param, "")
t[1] = player
if getPlayerAccess(cid) >= 3 then
if (param == "/jail") then
if (isPlayer(player)) then
setPlayerStorageValue(player, Jailed, 1)
doTeleportThing(player, jailPos)
doPlayerSendTextMessage(player, MSG_TYPE, jailedMSG)
doSendMagicEffect(jailPos, EFFECT_TYPE)
else
doPlayerSendCancel(cid, "This is not a player")
return false
end
elseif (param == "/unjail") then
The first elseif introduced. The elseif is on the (param =="jail") if. You will no what im talking about when I say "on" if you use NotePad++.
So elseif the person says "/unjail"
When you use elseif it doesnt open an IF, so there is no end needed on it. Though you may have an if in the elseif that requiers an end.
Lua:
local jailPos = {x = 1000, y = 1000, z = 7}
local MSG_TYPE = MESSAGE_STATUS_CONSOLE_RED
local jailMSG = "You have been jailed"
local EFFECT_TYPE = 10
function onSay(cid, words, param, channel)
if (param == "") then
return false
end
t = string.explode(param, "")
t[1] = player
if getPlayerAccess(cid) >= 3 then
if (param == "/jail") then
if (isPlayer(player)) then
setPlayerStorageValue(player, Jailed, 1)
doTeleportThing(player, jailPos)
doPlayerSendTextMessage(player, MSG_TYPE, jailedMSG)
doSendMagicEffect(jailPos, EFFECT_TYPE)
else
doPlayerSendCancel(cid, "This is not a player")
return false
end
elseif (param == "/unjail") then
if (isPlayer(player)) then
if getPlayerStorageValue(player, Jailed) == 1 then
You see I told the script to check if the player has the jaled storage. This is so if its not a jaield player, it wont do anything. We wouldn't want to
have our script send a player to the temple thats trying to hunt :/
Lua:
local jailPos = {x = 1000, y = 1000, z = 7}
local MSG_TYPE = MESSAGE_STATUS_CONSOLE_RED
local jailMSG = "You have been jailed"
local EFFECT_TYPE = 10
local templePos = {x = 1000, y = 1000, z = 7} -- if you typed getPlayerTownId(player) YOU WOULD GET AN ERROR! This is because its player isn't known yet to the script.--
-- You can put it in the script, look down to see how --
local unjailMSG = "You have been unjailed!"
function onSay(cid, words, param, channel)
if (param == "") then
return false
end
t = string.explode(param, "")
t[1] = player
if getPlayerAccess(cid) >= 3 then
if (param == "/jail") then
if (isPlayer(player)) then
setPlayerStorageValue(player, Jailed, 1)
doTeleportThing(player, jailPos)
doPlayerSendTextMessage(cid, MSG_TYPE, jailedMSG)
doSendMagicEffect(jailPos, EFFECT_TYPE)
else
doPlayerSendCancel(cid, "This is not a player")
return false
end
elseif (param == "/unjail") then
if (isPlayer(player)) then
if getPlayerStorageValue(player, Jailed) == 1 then
local templePos = getPlayerTownId(player) -- You would put this here instead of making the local up there. --
doTeleportThing(player, templePos)
doPlayerSendTextMessage(player, MSG_TYPE, unjailMSG)
doSendMagicEffect(templePos, EFFECT_TYPE)
else
doPlayerSendCancel(cid, "This player is not jailed!")
return false
end
else
doPlayerSendCancel(cid, "You do not have access to these commands")
return false
end
This else if connected to the Access if. You notice it is wrapped over both param scripts. This means it will ask for it for both.
We could add if (param == "!something else") then after all that if we wanted a player to be able to use a command in here. (it would be out of the access request)
But for this script we dont need players to say anything. So now we can end everything.
Lua:
local jailPos = {x = 1000, y = 1000, z = 7}
local MSG_TYPE = MESSAGE_STATUS_CONSOLE_RED
local jailMSG = "You have been jailed"
local EFFECT_TYPE = 10
local templePos = {x = 1000, y = 1000, z = 7}
local unjailMSG = "You have been unjailed!"
function onSay(cid, words, param, channel)
if (param == "") then
return false
end
t = string.explode(param, "")
t[1] = player
if getPlayerAccess(cid) >= 3 then
if (param == "/jail") then
if (isPlayer(player)) then
setPlayerStorageValue(player, Jailed, 1)
doTeleportThing(player, jailPos)
doPlayerSendTextMessage(cid, MSG_TYPE, jailedMSG)
doSendMagicEffect(jailPos, EFFECT_TYPE)
else
doPlayerSendCancel(cid, "This is not a player")
return false
end
elseif (param == "/unjail") then
if (isPlayer(player)) then
if getPlayerStorageValue(player, Jailed) == 1 then
local templePos = getPlayerTownId(player)
doTeleportThing(player, templePos)
doPlayerSendTextMessage(player, MSG_TYPE, unjailMSG)
doSendMagicEffect(templePos, EFFECT_TYPE)
else
doPlayerSendCancel(cid, "This player is not jailed!")
return false
end
else
doPlayerSendCancel(cid, "You do not have access to these commands")
return false
end
return true
end
Now the script is complete! Now if you have learned something from this, or you're clever, or you've just seen this script before. You will know that WE DONT HAVE
A WAY FOR THE PLAYERS TO GET OUT. Unless a gm kicks them out.
So we need to add a kick time. The way we are going to do this is adding a global event.
It gives function onThink(intraval)
So how do we get it to kick them?
Lua:
function onThink(intraval)
for i, pid in ipairs(getPlayersOnline()) do
if getPlayerStorageValue(pid, jailed) > 0 then
setPlayerStorageValue(pid, jailed - 1)
doTeleportThing(pid, getPlayerTownId(pid))
return true
end
end
end
Loops/tables will not be explained in this tutorial, You can purchase my advanced tutorials witch recover this, and alot more, including the loops/tables, and other functions of lua.
Thats it for that script! Just sets the players storage value down everytime its specified. So if you want the jail time 10 minutes, in the XML file make the intraval 600
That sums up this tutorial. I hope I helped some new scripters.
Yes I know theres a better system (i've made it) this is to help noob scripters.