• 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 Help with some Actions

multrayzor

New Member
Joined
Mar 17, 2014
Messages
58
Reaction score
2
So...i´ve been trying to figure out how to 2 to actions, here is what i need to do:

One action is to be used on a tile that needs to access a player storage value, and let the player pass or not depending on the value. like the PoI hall that lead to the tp with rewads(those lightning things). For this one im not pretty sure which function to use to active it, i don´t recall seing a function called onStep :/

The other action is pretty simple but i´ve been strugling on it, it is to be used on a lever that will spawn a certain tile/object at a certain position when used. or remove a certain tile/object. what is the function to create/delete an item in a position?

Thanks in advance,
Gabe
 
function onStepIn(cid, item, position, fromPosition)



tile1 = {x=32367, y=32181, z=7, stackpos=0} --change tilepos
doCreateItem(9999,1,tile1) --change itemID --change tile ID


Hope that helps.
 
Thats helpful indeed, but how do i let or not the player pass through that? do i have to "tp" him back or is there a better way to do it?
 
You can use this to teleport the player back when stepping on a tile.
Code:
doTeleportThing(cid, fromPosition)
 
You check the storage and then teleport the player. You can try to search for the code that doesn't allow people to enter houses, that should work for you (I have no idea where it is).
 
Code:
function onStepIn(cid, item, position, fromPosition)
   if getPlayerStorageValue(cid, 40002) < (item.uid - 50000) then
     doTeleportThing(cid, fromPosition)
   end
end

For each part of the quest completed the storage value increases 1, starting at 0(nothing completed).
And each tile has a uniqueid starting 50001, increasing 1 by 1.

Is everything okay? i mean, it should go like this:
Step on tile 1, check if you have completed the first part, if not, teleports you back to the preview sqm(doesnt let you pass), if it is completed nothing happens(lets you pass).
 
One day you'll regret coding it this way :)
  • Set the storage so it matches the stage of the quest (0, 1, 2, 3 ...)
  • Use the tiles to index an array with the "passing value" in it, and test that.
  • Give the tiles the same action id, and start the script on that.
You can also use this approach, but loop on the tile numbers starting with 50000 ... but the problem with linking the script logic to the tile numbers is that it will get ugly if you want to reuse it for another quest.

If you're short of space for tiles you could do this with a door or a lever too.

(BTW - there's a nice quest system in "Resources" - I think it would make this a bit easier)
 
Thank you all for all the answers, thats what i ended up with:

Checking for thrones of the quest done:
Code:
function onStepIn(cid, item, position, fromPosition)
   if getPlayerStorageValue(cid, 40002) < (item.uid - 50000) then
     doTeleportThing(cid, fromPosition)
     doPlayerSendTextMessage(cid, 22, "Strange forces push you back.")
   end
end

updating quest on eachthrone:
Code:
function onStepIn(cid, item, position, fromPosition)
   if item.uid == 50008 then
     seal = "Verminor."
   elseif item.uid == 50009 then
     seal = "Infernatil."
   elseif item.uid == 50010 then
     seal = "Tafariel."
   elseif item.uid == 50011 then
     seal = "Apocalypse."
   elseif item.uid == 50012 then
     seal = "Pumin."
   elseif item.uid == 50013 then
     seal = "Bazir."
   elseif item.uid == 50014 then
     seal = "Ashfalor."
   end
   if ((getPlayerStorageValue(cid, 40002) <= -1) then
     setPlayerStorageValue(cid, 40002, 1)
     doTeleportThing(cid, fromPosition)
     doPlayerSendTextMessage(cid, 22, "You absorbed the spirit of" .. seal ..)
   else   
     setPlayerStorageValue(cid, 40002, (getPlayerStorageValue(cid, 40002) + 1))
     doTeleportThing(cid, fromPosition)
     doPlayerSendTextMessage(cid, 22, "You absorbed the spirit of" .. seal ..)
end

Not the best code i belive but both scripts are activated each by 1 action id only. it only uses the unique.id to check which throne it is for the message.
Feedback is welcome as always, thank you all.
 
seals = {
[50008] = "Verminor",
[50009] = "Infernatil",
[50010] = "Tafariel",
[50011] = "Apocalypse",
[50012] = "Pumin",
[50013] = "Bazir",
[50014] = "Ashfalor"
}

local seal = seals[item.uid]

if ( seal == nil ) then -- item id not in table (bad actionid?)

You could make the entries look like this;
[50011] = {4, "Apocalypse"},
and merge the scripts.

In that case the two values would be in seals[50011][1] and seals[50011][2]
 
Last edited:
thanks, ill implement that, and merge the 2 scripts into 1.
another question, is there a function to remove an item from a certain place? like, to remove stones when i push a lever, i know you can replace it for a walkable item using doTransformItem, but it sounds bad to keep changing the items in the map instead of just deleting them.
 
If it's a door with a condition attached, you might want to transform them so that other people can do the quest.

An item should be deleted after it's used.

Try this: doRemoveItem(uid)
If that doesn't work, this should do it: doRemoveItem(uid, 1)


BTW - I don't think that script is quite right as I explained it (too much wine this evening :)

Try indexing it with the Storage, and have the entries like like this:
{ 50010, "Tafariel"}
You'll still get a nil if you lookup the table at seals[-1] (or seals[0] if you want to standardize the incrementing code)

PS: It's just as easy to do this with a single tile if you like. Less visually impressive though (at least if you've built a nice shrine with statues of each demon etc), but the script is actually keyed off the "questStage" counter, not the tile - the only indexed value you must have is the names of each demon.
 
Last edited:
The thing is, with the doRemoveItem i would have to give each stone an unique id, since there isnt any parameter in doRemoveItem that specifies a location. So is this the only way to do it?

Just realized the function onStepIn doesnt work/exist in the version im using(0.3.6 tfs), any replacement for it? :/
 
Last edited by a moderator:
The thing is, with the doRemoveItem i would have to give each stone an unique id, since there isnt any parameter in doRemoveItem that specifies a location. So is this the only way to do it?
tile1 = {x=32367, y=32181, z=7, stackpos=0} --change tilepos
gettile1 = getThingfromPos(tile1)
doRemoveItem(gettile1.uid,1)


Hope that helped.
 
/\ genius, hope that works. on the other subject, not sure if the function is not working or something else, neither of them are giving any sign of working, thats what i have:

Throne Function?
Code:
function onStepIn(cid, item, position, fromPosition)
   print("working thrones")
   if item.uid == 50008 then
     seal = "Verminor."
   elseif item.uid == 50009 then
     seal = "Infernatil."
   elseif item.uid == 50010 then
     seal = "Tafariel."
   elseif item.uid == 50011 then
     seal = "Apocalypse."
   elseif item.uid == 50012 then
     seal = "Pumin."
   elseif item.uid == 50013 then
     seal = "Bazir."
   elseif item.uid == 50014 then
     seal = "Ashfalor."
   end
   if ((getPlayerStorageValue(cid, 40002) <= -1) then
     setPlayerStorageValue(cid, 40002, 1)
     doTeleportThing(cid, fromPosition)
     doPlayerSendTextMessage(cid, 22, "You absorbed the spirit of" .. seal ..)
   else  
     setPlayerStorageValue(cid, 40002, (getPlayerStorageValue(cid, 40002) + 1))
     doTeleportThing(cid, fromPosition)
     doPlayerSendTextMessage(cid, 22, "You absorbed the spirit of" .. seal ..)
   end
end

Reward Way Function:
Code:
function onStepIn(cid, item, position, fromPosition)
   print("working check")
   if getPlayerStorageValue(cid, 40002) < (item.uid - 50000) then
     doTeleportThing(cid, fromPosition)
     doPlayerSendTextMessage(cid, 22, "Strange forces push you back.")
   end
end

my actions.xml contains
Code:
  <action actionid="60001" event="script" value="quests/poicheck.lua"/>
   <action actionid="60002" event="script" value="quests/poithrones.lua"/>

The prints are only to check in the console if there is any activity from the scripts, and there isnt none
 
@filipus
This is what i got, there is 3 levers to open a way with a rock blocking, and a lever inside in case you get stuck. the script is activated on all of them by a actionid.

Code:
function onUse(cid, item, frompos, item2, topos)
   pos1 = {x=740, y=804, z=11, stackpos=1}
   pos2 = {x=740, y=804, z=11, stackpos=2}
   pos3 = {x=740, y=804, z=11, stackpos=3}
   rock1 = getThingfromPos(pos1)
   rock2 = getThingfromPos(pos2)
   rock3 = getThingfromPos(pos3)
     if item.itemid == 1945 then
     doTransformItem(item.uid,item.itemid+1)
     if item.uid == 50018 then
       doRemoveItem(rock1.uid, 1)
     elseif item.uid == 50019 then
       doRemoveItem(rock2.uid, 1)
     elseif item.uid == 50020
       doRemoveItem(rock3.uid, 1)
     else
       doRemoveItem(rock1.uid, 1)
       doRemoveItem(rock2.uid, 1)
       doRemoveItem(rock3.uid, 1)
     end
   elseif item.itemid == 1946 then
     doTransformItem(item.uid,item.itemid-1)
     doTileAddItemEx(pos1, 1304)
     doTileAddItemEx(pos2, 1304)
     doTileAddItemEx(pos3, 1304)
   end
end

What do you think of it?
 
Well, didnt work that well, i removed the option to put the stones back in place, it was just being a huge headache, thats what i ended up with:
Code:
function onUse(cid, item, frompos, item2, topos)
   pos1 = {x=740, y=804, z=11, stackpos=1}
   pos2 = {x=740, y=804, z=11, stackpos=2}
   pos3 = {x=740, y=804, z=11, stackpos=3}
   rock1 = getThingfromPos(pos1)
   rock2 = getThingfromPos(pos2)
   rock3 = getThingfromPos(pos3)
     if item.itemid == 1945 then
     if item.uid == 50018 then
       doRemoveItem(rock1.uid, 1)
     elseif item.uid == 50019 then
       doRemoveItem(rock1.uid, 1)
     elseif item.uid == 50020 then
       doRemoveItem(rock1.uid, 1)
     else
       doRemoveItem(rock3.uid, 1)
       doRemoveItem(rock2.uid, 1)
       doRemoveItem(rock1.uid, 1)
     end
   end
end
Works prefectly.

On the other issue, I was getting some error for not having a onUse function in the scripts, so i just started and finished them to, having this running:

Code:
function onUse(cidx, itemx, fromposx, item2x, toposx)
   print("onuse working")
end

function onStepIn(cid, item, position, fromPosition)
   print("working thrones")
   if item.uid == 50008 then
     seal = "Verminor."
   elseif item.uid == 50009 then
     seal = "Infernatil."
   elseif item.uid == 50010 then
     seal = "Tafariel."
   elseif item.uid == 50011 then
     seal = "Apocalypse."
   elseif item.uid == 50012 then
     seal = "Pumin."
   elseif item.uid == 50013 then
     seal = "Bazir."
   elseif item.uid == 50014 then
     seal = "Ashfalor."
   end
   if (getPlayerStorageValue(cid, 40002) <= -1) then
     setPlayerStorageValue(cid, 40002, 1)
     doTeleportThing(cid, fromPosition)
     doPlayerSendTextMessage(cid, 22, "You absorbed the spirit of" .. seal)
   else   
     setPlayerStorageValue(cid, 40002, (getPlayerStorageValue(cid, 40002) + 1))
     doTeleportThing(cid, fromPosition)
     doPlayerSendTextMessage(cid, 22, "You absorbed the spirit of" .. seal)
   end
end

Code:
function onUse(cidx, itemx, fromposx, item2x, toposx)
   print("onuse working")
end

function onStepIn(cid, item, position, fromPosition)
   print("working check")
   if getPlayerStorageValue(cid, 40002) < (item.uid - 50000) then
     doTeleportThing(cid, fromPosition)
     doPlayerSendTextMessage(cid, 22, "Strange forces push you back.")
   end
end

It is not working for some reason, i think the onStepIn function is not running, because the only thing i get on the console is: onuse working, for both of the scripts.
 
I don't know man, what you could try is to use a door and then use the onUse().
I know that is not what you want but I have no idea what else you could do :/
 
StepIn
Did you define the tile in movements.xml? Like this:
<movevent event="StepIn" itemid="1387" script="citizen.lua"/>

Removing an item:
There are a number of options for removing items. The "best" choice depends on which objects you already have references to.

The OO API includes methods like these:
tile:getItems()
tile:getItemByType(itemType)

and a few other like them.

So if you have a "hook" to an item from e.g. using it (onUse gives you the unique id) you can remove it in onUse() via the unique id. This is what I've seem the most examples of, but sometimes in places I'd do it differently myself :)

If you know the item is on a specific tile, you can use the tile-centric methods to get the item's unique id.
If you know a player has the item you can use player:removeItem(itemId, count[, subType = -1[, ignoreEquipped = false]]) etc.
([]'s are optional, defaults shown)

BTW there are old-style functions for most of the methods, some via compat.lua, some perhaps done the other way around (the method is a facade, with the capability still implemented in an old-style function).
 
Last edited:
Back
Top