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

Tutorials [LUA] Creating Actions/Movements & TalkActions

habiba

New Member
Joined
Aug 26, 2007
Messages
586
Reaction score
4
Location
Örebro, Sweden
ALL CREDITS TO ZERIIKLER

Welcome to the tutorial on Creating Actions.
Well, lets get going..

Every server has many functions to make your server do different things.
These functions include,
Code:
doTeleportThing(cid, newpos, <optional> pushmove)
doCreatureSay(cid, text, type)
doPlayerFeed(cid, food)
doPlayerAddMana(cid, mana)

All of those do different things, although their names pretty much explain themselves its nice to know how to use them ;)

Here's a list of all the LUA Functions.
(Functions from TheForgottenServer)

Code:
	setPlayerGroupId(cid, newGroupId)
	playerLearnInstantSpell(cid, name)
	canPlayerLearnInstantSpell(cid, name)
	getPlayerLearnedInstantSpell(cid, name)
	getPlayerInstantSpellCount(cid)
	getPlayerInstantSpellInfo(cid, index)
	getInstantSpellInfoByName(cid, name)
	getInstantSpellWords(name)
	setPlayerStorageValue(uid, valueid, newvalue)
	getGlobalStorageValue(valueid)
	setGlobalStorageValue(valueid, newvalue)
	getTilePzInfo(pos)
	getTileHouseInfo(pos)
	getItemRWInfo(uid)
	getThingfromPos(pos)
	getThing(uid)
	queryTileAddThing(uid, pos, <optional> flags)
	getThingPos(uid)
	doRemoveItem(uid, <optional> n)
	doPlayerFeed(cid, food)
 
	doPlayerSendDefaultCancel(cid, ReturnValue)
	doTeleportThing(cid, newpos, <optional> pushmove)
	doTransformItem(uid, toitemid, <optional> count/subtype)	
	doCreatureSay(cid, text, type)
	doSendMagicEffect(pos, type)
	doSendDistanceShoot(frompos, topos, type)
	doChangeTypeItem(uid, newtype)	
	doSetItemActionId(uid, actionid)
	doSetItemText(uid, text)
	doSetItemSpecialDescription(uid, desc)
	doSendAnimatedText(pos, text, color)
	doPlayerAddSkillTry(cid, skillid, n)
	doCreatureAddHealth(cid, health)
	doPlayerAddMana(cid, mana)
	doPlayerAddManaSpent(cid, mana)
	doPlayerAddSoul(cid, soul)
	doPlayerAddItem(uid, itemid, <optional> count/subtype)
	doPlayerAddItemEx(cid, uid, <optional: default: 0> useCidPosOnFail)
	doPlayerSendTextMessage(cid, MessageClasses, message)
	doPlayerRemoveMoney(cid, money)
	doShowTextDialog(cid, itemid, text)
	doDecayItem(uid)
	doCreateItem(itemid, type/count, pos)
	doCreateItemEx(itemid, <optional> count/subtype)
	doTileAddItemEx(pos, uid)
	doCreateTeleport(itemid, topos, createpos)
	doSummonCreature(name, pos)
	doConvinceCreature(cid, target)
	doRemoveCreature(cid)
	doMoveCreature(cid, direction)
	doPlayerSetTown(cid, townid)
	doPlayerSetVocation(cid,voc)
	doPlayerRemoveItem(cid,itemid,count)
	doPlayerAddExp(cid,exp)
	doPlayerSetGuildId(cid, id)
	doPlayerSetGuildRank(cid, rank)
	doPlayerSetGuildNick(cid, nick)
	doPlayerAddOutfit(cid,looktype,addons)
	doPlayerRemOutfit(cid,looktype,addons)
	doSetCreatureLight(cid, lightLevel, lightColor, time)
	doSetCreatureDropLoot(cid, doDrop)
	getCreatureCondition(cid, condition)
	isPlayer(cid)
	isCreature(cid)
	isContainer(uid)
	isMoveable(uid)
	getPlayerByName(name)
	getPlayerGUIDByName(name)
	registerCreatureEvent(uid, eventName)
	getContainerSize(uid)
	getContainerCap(uid)
	getContainerItem(uid, slot)
	doAddContainerItem(uid, itemid, <optional> count/subtype)
	getHouseOwner(houseid)
	getHouseName(houseid)
	getHouseEntry(houseid)
	getHouseRent(houseid)
	getHouseTown(houseid)
	getHouseAccessList(houseid, listid)
	getHouseByPlayerGUID(playerGUID)
	setHouseAccessList(houseid, listid, listtext)
	setHouseOwner(houseid, ownerGUID)
	getWorldType()
	getWorldTime()
	getWorldLight()
	getWorldCreatures(type)
	getWorldUpTime()
	broadcastMessage(message, type)
	getGuildId(guild_name)
	getPlayerSex(cid)
	doPlayerSetSex(cid, newSex)
	createCombatArea( {area}, <optional> {extArea} )
	createConditionObject(type)
	setCombatArea(combat, area)
	setCombatCondition(combat, condition)
	setCombatParam(combat, key, value)
	setConditionParam(condition, key, value)
	addDamageCondition(condition, rounds, time, value)
	addOutfitCondition(condition, lookTypeEx, lookType, lookHead, lookBody, lookLegs, lookFeet)
	setCombatCallBack(combat, key, function_name)
	setCombatFormula(combat, type, mina, minb, maxa, maxb)
	setConditionFormula(combat, mina, minb, maxa, maxb)
	doCombat(cid, combat, param)
	createCombatObject()
	doAreaCombatHealth(cid, type, pos, area, min, max, effect)
	doTargetCombatHealth(cid, target, type, min, max, effect)
	doAreaCombatMana(cid, pos, area, min, max, effect)
	doTargetCombatMana(cid, target, min, max, effect)
	doAreaCombatCondition(cid, pos, area, condition, effect)
	doTargetCombatCondition(cid, target, condition, effect)
	doAreaCombatDispel(cid, pos, area, type, effect)
	doTargetCombatDispel(cid, target, type, effect)
	doChallengeCreature(cid, target)
	numberToVariant(number)
	stringToVariant(string)
	positionToVariant(pos)
	targetPositionToVariant(pos)
	variantToNumber(var)
	variantToString(var)
	variantToPosition(var)
	doChangeSpeed(cid, delta)
	doSetMonsterOutfit(cid, name, time)
	doSetItemOutfit(cid, item, time)
	doSetCreatureOutfit(cid, outfit, time)
	getCreatureOutfit(cid)
	getCreaturePosition(cid)
	getCreatureName(cid)
	getCreatureSpeed(cid)
	getCreatureBaseSpeed(cid)
	getCreatureTarget(cid)
	isItemStackable(itemid)
	isItemRune(itemid)
	isItemDoor(itemid)
	isItemContainer(itemid)
	isItemFluidContainer(itemid)
	getItemName(itemid)
	getItemWeight(itemid, count)
	debugPrint(text)
	isInArray(array, value)
	addEvent(callback, delay, parameter)
	stopEvent(eventid)
	doPlayerPopupFYI(cid, message)
	mayNotLogout(cid, value)
	mayNotMove(cid, value)
	doPlayerAddPremiumDays(cid, days)
	doPlayerRemovePremiumDays(cid, days)
	getPlayerPremiumDays(cid)
	getPlayerSkullType(cid)
	getPromotedVocation(vocation)
	getPlayerBlessing(cid, blessing)
	doPlayerAddBlessing(cid, blessing)
	saveData()
	escapeString(str)

Now making a script consists of using these.
Just about, everything can be done in LUA.

There are also, created functions here, that people make for other people to use.
But lets just stick with the ones posted above.

To create a script(depending on what your making, "talkaction", "action", "movement" etc.) you can start with these.

For Action Scripts
Code:
function onUse(cid, item, frompos, item2, topos)
For Movement Scripts
Code:
function onStepIn(cid, item, position, fromPosition)
For Talk Action Scripts
Code:
function onSay(cid, words, param)
Or Creature Scripts.
But heres how Creature Scripts vary.
There can be a couple, depending on which distro you're using.
Code:
function onLogin(cid)
function onKill(cid)
function onDeath(cid)
function onLogout(cid)
Etc..

Now lets get started with making a nice basic script.

Part One: Actions

Actions are very common. They are used for a lot of different things.
Example: Eating Food, Doors, Shovels, Quests.. Etc.

So lets start our script off with this.
Code:
function onUse(cid, item, frompos, item2, topos)

Okay so we want our script to do something right?
So lets say we want someone to use a scroll, and maybe gain exp, or say something.
Or gain exp, and say something at the same time :eek:

So lets look at our functions.
We have..
Code:
doPlayerAddExp(cid,exp)
And
Code:
doCreatureSay(cid, text, type)

But what item are we going to use to give exp and make us say something?
Lets use
oqxi8o.jpg

Poem Scroll ^_^
ID: 6119
So now we know the functions and item we want to use, so lets make the script!

Code:
function onUse(cid, item, frompos, item2, topos)
if item.itemid == 6119 then
doPlayerAddExp(cid, 300)
doCreatureSay(cid, "YAY! EXP!", 3)
end
return 1
end

Now let me explain..
So now first, in this script, we're telling the server if the item's ID = 6119(poem scroll) then its going to add 300 exp, and the player will say "YAY! EXP!.

Now return 1 means, that its going to return no errors, like if that wasn't there, you would receive a cancel message in-game saying You cannot use this object.
But, the script will still work.
You can ether have return TRUE, which is the same as return 1.
return 0 means false. so return FALSE would be the same as return 0.

There are ways to make the script easier to config like this.
Code:
local itemID = 6119 -- The ID of the item that will give you EXP
local xp = 300 --How much EXP will be givin when item is used
 
 
 
 
local words = "YAY! EXP!" --What the player will say when item is used
function onUse(cid, item, frompos, item2, topos)
if item.itemid == itemID then
doPlayerAddExp(cid, xp)
doCreatureSay(cid, words, 3)
end
return 1
end

Which might be easier to do with new LUA learners so you can easily configure your script better :)

Now we have also in the script "doCreatureSay(cid, words, 3)"

"3" means, the way the player will say YAY! EXP!.
Here's the different ways you can say it.
Code:
TALKTYPE_SAY  = 1
TALKTYPE_WHISPER = 2
TALKTYPE_YELL = 3
TALKTYPE_PRIVATE_PN = 4
TALKTYPE_PRIVATE_NP = 5
TALKTYPE_PRIVATE = 6
TALKTYPE_CHANNEL_Y = 7
TALKTYPE_BROADCAST = 11
TALKTYPE_CHANNEL_R1 = 12
TALKTYPE_PRIVATE_RED = 13
TALKTYPE_CHANNEL_O = 14
TALKTYPE_CHANNEL_R2 = 16
TALKTYPE_ORANGE_1 = 18
TALKTYPE_ORANGE_2 = 19

This can be found in your Global.LUA

Now maybe you want the item to remove after you use it :huh:

Well you can add the function, doRemoveItem.

Let me show you how it would work.

Code:
local itemID = 6119 -- The ID of the item that will give you EXP
local xp = 300 --How much EXP will be givin when item is used
local words = "YAY! EXP!" --What the player will say when item is used
function onUse(cid, item, frompos, item2, topos)
if item.itemid == itemID then
doPlayerAddExp(cid, xp)
doCreatureSay(cid, words, 3)
doRemoveItem(cid, item.uid, 1)
end
return 1
end

Okie, so now we have "doRemoveItem(cid, item.uid, 1)" in there. That will indeed remove the item after you use it. If you want to know, what the "1" means, well it means how many is it going to remove. In our case we put 1. If you put two and the player had two scrolls, it wouldn't remove two. Only one. This works for other items, that stack. :p

So lets get into the script a little more.
Maybe you want only a specific vocation using this scroll, or only players above or below a level. Lets add that :)

Okej, So lets look though our functions.
Ahhh yes, "getPlayerVocation"
So lets put that in the script xD

Code:
local itemID = 6119 -- The ID of the item that will give you EXP
local xp = 300 --How much EXP will be givin when item is used
local words = "YAY! EXP!" --What the player will say when item is used
local vocs = 1, 5
function onUse(cid, item, frompos, item2, topos)
if item.itemid == itemID and getPlayerVocation(cid) == vocs then
doPlayerAddExp(cid, xp)
doCreatureSay(cid, words, 3)
doRemoveItem(cid, item.uid, 1)
end
return 1
end

So now we are telling the server if the item's ID is = to 6119, AND the players vocation is (1 or 5)
Sorcerer & Master Sorcerer

Ok so maybe we want the script to say something if your not a Sorcerer or a Master Sorcerer. So we add another function.
"doPlayerSendCancel"
Here's what it shall look like.
Code:
local itemID = 6119 -- The ID of the item that will give you EXP
local xp = 300 --How much EXP will be givin when item is used
local words = "YAY! EXP!" --What the player will say when item is used
local vocs = 1, 5
function onUse(cid, item, frompos, item2, topos)
if item.itemid == itemID and getPlayerVocation(cid) == vocs then
doPlayerAddExp(cid, xp)
doCreatureSay(cid, words, 3)
doRemoveItem(cid, item.uid, 1)
else
doPlayerSendCancel(cid, "Sorry, your not a Sorcerer or Master Sorcerer")
end
return 1
end

Now i added
Code:
else
doPlayerSendCancel(cid, "Sorry, your not a Sorcerer or Master Sorcerer")

else means if the player doesn't have the script requirements then its going to do something else. Like send them a cancel saying their not of vocation. If you didnt have something "else" then it just wouldn't do anything.

Ok so now we added the getPlayerVocation. Lets add a level requirement..

Again, looking though functions, and yes!
"getPlayerLevel"

So lets add it xD

Code:
local itemID = 6119 -- The ID of the item that will give you EXP
local xp = 300 --How much EXP will be givin when item is used
local words = "YAY! EXP!" --What the player will say when item is used
local vocs = 1, 5
local level = 20
function onUse(cid, item, frompos, item2, topos)
if item.itemid == itemID and getPlayerVocation(cid) == vocs and getPlayerLevel(cid) >= level then
doPlayerAddExp(cid, xp)
doCreatureSay(cid, words, 3)
doRemoveItem(cid, item.uid, 1)
else
doPlayerSendCancel(cid, "Sorry, your not a Sorcerer or Master Sorcerer And not level 20+")
end
return 1
end

Okie, so we added,
Code:
getPlayerLevel(cid) >= level
and also
Code:
local level = 20

Now, Let me explain this.
We are now telling the server to get the players level.
and ">=" means greater or equal to
Just like math right?
Yup
Heres how they go with explaining,
Code:
>
<
==
>=
<=
~=

">" Means just greater than
"<" Means just less than
"==" Means equal to
">=" Means greater than or equal to
"<=" Means less than or equal to
"~=" Means not equal to


Ok, so now lets talk about how you end your scripts.

Every script will be ended with "end"
There might be more than two ends, depending on how your script is.
an easy way to see when your script ends is by using NotePad++
You can download it from this link.
>>DOWNLOAD<<

On the left side of it, you'll see where your script starts and where it should end.
I STRONGLY Recommend using this program when you script.

I Hope you understood everything i explained.
I will write Part 2: Movements
When i have more time.

Hope you guys liked.
Comments? :huh:
 
Part 2: Movements!

Okay so, if you read the first part above, this part shall make more sense.
Lets get started shall we?

Ok so we start movement scripts with this.
Code:
function onStepIn(cid, item, position, fromPosition)

Or

Code:
function onStepOut(cid, item, position, fromPosition)

onStepIn is most common for scripts, like if you made a script for if you stepped on a tile and it teleported you somewhere, you wouldn't need an onStepOut function in your script.
A script like swimming, uses onStepIn, and onStepOut, i'll explain how it works, then we'll create our own :)

This is a basic swimming script.
(From TheForgottenServer)
Code:
local outfit =
	{
		lookType = 267,
		lookHead = 0,
		lookBody = 0,
		lookLegs = 0,
		lookFeet = 0,
		lookAddons = 0
	}

function onStepIn(cid, item, position, fromPosition)
	doSetCreatureOutfit(cid, outfit, -1)
end

function onStepOut(cid, item, position, fromPosition)
	doRemoveCondition(cid, CONDITION_OUTFIT)
end

Ok so we're basiclly telling the server when you step on a cirtin item, its going to setCreatureOutfit.(Change the players outfit)
Remember how i showed you can make scripts easier to config? well yes, heres what the script is doing, up at the top of the script "local outfit" its a table of the looks that the script is going to change. so its easier for configuring. where the -1 is in the function setCreatureOutfit is the time. but the reason we have -1 is because its going to be unlimited. UNTIL the next function comes in..
Code:
function onStepOut(cid, item, position, fromPosition)
So now, when you step out of the cirtin item, its going to "doRemoveCondition(cid, CONDITION_OUTFIT)"
Which simply means, that its going to remove the outfit back to your original outfit.
Pretty easy huh ?
Now lets make our own.

So at the first post, we have all the functions listed so lets find something :p

Maybe we wana walk on a tile and change our group ID :eek:
Lets try that? xD

So lets grab our starter..
Code:
function onStepIn(cid, item, position, fromPosition)

So now we look in our functions....(this is where you look though functions)
YEAH!
Code:
setPlayerGroupId(cid, newGroupId)
SHOULD WORK!!

So lets make the basics.
Code:
function onStepIn(cid, item, position, fromPosition)
if item.uid == 1234 then
setPlayerGroupId(cid, 3)
end
end

That script would make your groupID 3.
Let me explain.
if the items unique id is equal to 1234 then its going to set the players group id.
-end-
How easy is that?!
I know, real easy...
But what if a player with GroupID of 3 walks on it?
Well its going to setPlayerGroupId anyways :D
Lets make it so if a person already has groupID 3 they can't walk on it :huh:
So i found a function that will check what the players Group ID is.
Code:
getPlayerGroupId(cid)

So lets edit the script.
Code:
function onStepIn(cid, item, position, fromPosition)
if item.uid == 1234 and getPlayerGroupId(cid) ~= 3 then
setPlayerGroupId(cid, 3)
end
end
So now we just told the server, if the items uid is equal to 1234 AND the players groupID is not equal to 3 then...etc.
So now, nothing will happen if a GOD walks on that tile, but it will change the player without groupID 3 :p

Maybe we want it to push the person that already has groupID 3 away from the tile.
and say Your already a GOD.

YAY! LETS DO THAT BLZ!

Kk so we add these three functions. and this is where the script might get advanced...

Code:
getPlayerLookDir(cid)
doMoveCreature(cid, direction)
doPlayerSendCancel(cid, text)

getPlayerLookDir will check which way the player is facing
/\
< >
\/
UP,DOWN,LEFT,RIGHT.

So lets add this to the script.
Code:
if getPlayerLookDir(cid) == 0 then
newdir = 2
elseif getPlayerLookDir(cid) == 1 then
newdir = 3
elseif getPlayerLookDir(cid) == 2 then
newdir = 0
else
newdir = 1
end

This means, if the player is facing 0(which is down) then the newdir will be 2, not 2 as if the player is facing, but it going to change the script around.
Maybe if i show you the script you'll understand a bit better.

Code:
local text = "You're already a GOD"

function onStepIn(cid, item, position, fromPosition)

if getPlayerLookDir(cid) == 0 then
newdir = 2
elseif getPlayerLookDir(cid) == 1 then
newdir = 3
elseif getPlayerLookDir(cid) == 2 then
newdir = 0
else
newdir = 1
end

if item.uid == 1234 and getPlayerGroupId(cid) ~= 3 then
setPlayerGroupId(cid, 3)
else
doPlayerSendCancel(cid, text)
doMoveCreature(cid, newdir)
end
end

Shall i explain ?
Now we just told the server that if the player doesn't already have groupID 3 then we're going to change it to 3. But if they do.. We're going to send a cancel saying "You're already a GOD" and push them away from the tile.
Make sense yet?
No?
Let me break it down more then :)

Code:
doPlayerSendCancel(cid, text)
Means that its going to say
Code:
local text = "You're already a GOD"
Then,
Code:
doMoveCreature(cid, newdir)
Means that its going to move the player in a new direction if they're already a GOD.(groupID 3)

Understand yet?
I hope so, because thats as far as i can break it down.

So we just made a nice script that will change a players GroupID to 3 if their a regular player, but if their already a GOD, then it will just push them away.

So wait, we can do more right? :rolleyes:
Maybe we want a teleport and some text when you "successfully" walk on the tile.

Lets add...
Code:
doTeleportThing(cid, pos)
doPlayerSendTextMessage(cid, MessageClasses, message)


So lets make script?

Code:
local text = "You're already a GOD"
local text2 = "You're now a GOD :D"
local place = {x=xxxx, y=xxxx, z=xxxx} --Where they will be teleported to
function onStepIn(cid, item, position, fromPosition)

if getPlayerLookDir(cid) == 0 then
newdir = 2
elseif getPlayerLookDir(cid) == 1 then
newdir = 3
elseif getPlayerLookDir(cid) == 2 then
newdir = 0
else
newdir = 1
end

if item.uid == 1234 and getPlayerGroupId(cid) ~= 3 then
setPlayerGroupId(cid, 3)
doTeleportThing(cid, place)
doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, text2)
else
doPlayerSendCancel(cid, text)
doMoveCreature(cid, newdir)
end
end

WHOA WTF JUST HAPPENED!?!?
Let me explain then ;)

All we made was a teleport function that teleports you after you get your groupID changed to 3.
But if your group ID is already 3, it will not teleport you.
We also added a textmessage that comes up when you get your groupID changed to 3, that says "You're now a GOD :D" but if your groupID is already 3, then again, its just going to push you away...
So there, you just made a nice little Movement script.
:D
 
Thanks for posting my tutorial :D
I didn't feel like changing
Lua:
 to just regular code :p
Thanks though :D
 
Thanks, helped me ;D

but i should make

PHP:
function onStepIn(cid, item, position, fromPosition)
if item.uid == 1234 and getPlayerGroupId(cid) < 3 then
setPlayerGroupId(cid, 3)
end
end

instead of
PHP:
function onStepIn(cid, item, position, fromPosition)
if item.uid == 1234 and getPlayerGroupId(cid) ~= 3 then
setPlayerGroupId(cid, 3)
end
end

what i changed is
PHP:
getPlayerGroupId(cid) ~= 3 then

;)
 
Last edited:
#UP
Lol man, you are saying, if the player has group.id < 3 you will get group.id = 3?
And if you are god? u will be transformed to a gm? :/
Is better use group.id >= 1, so you will get group.id 3 :)

MY english sucks, i know :<
 
#UP
Lol man, you are saying, if the player has group.id < 3 you will get group.id = 3?
And if you are god? u will be transformed to a gm? :/
Is better use group.id >= 1, so you will get group.id 3 :)

MY english sucks, i know :<

No, Zonet was right in this case. Using ~= 3 will cause even God's to become regular Gamemasters, though with < 3 it will only allow players below group 3 to become that group :thumbup:
 
Goof job man, really the script of the get exp per itens, it's so smarth of you... I loved!

//Bye
 
Im newbie to OT and now learning LUA.
Im reading this tutorial which was made in 12th August 2008, 17:55 so its a bit outdated and asking mod's to change things what is see has been changed since then.

there was for action scripts:
Code:
function onUse(cid, item, frompos, item2, topos)
now are:
Code:
function onUse(cid, item, fromPosition, itemEx, toPosition)

for Talk action scripts was:
Code:
function onSay(cid, words, param)
now are:
Code:
onSay(cid, words, param, channel)

im just learning, but in case someone else find this tutorial useful and dont get in wrong.

//Very useful tut.
 
Back
Top