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

Action [TFS 1.1] HomeStone (Based on WoW Hearthstone) - teleport home rock for RPG servers!

Fresh

Quack!
Joined
Oct 21, 2009
Messages
1,838
Solutions
18
Reaction score
616
Location
Poland
HomeStone script for TFS 1.1
(Idea from Ruthless Chaos OT)
bRLlhanAg.png

* How it looks? *
L6I69eBZ0.gif

About
HomeStone is an item which brings us to our home place (actual character Temple).
Script is easy and fully configurable for newbies scripters on TFS 1.1 (like me :p)
I wrote it with mind of RPG servers, after I saw that item on server called Ruthless Chaos. It's pretty nice idea :)

How it works?
It teleports player (when you wait specific period of time after use it) to his temple, after done few requirements.

My requirements (you can change them in script):
  • Player can use HomeStone when his level is UNDER 50;
  • Player need to wait 5 seconds to get teleported (countdown);
  • Player need to wait 10 seconds to use HomeStone again (cooldown/exhaust);
  • Player cant be during a fight to use HomeStone;
  • Player cant move when using HomeStone (in script);
  • Feature - when you Look on HomeStone it shows your actual temple by name and max level to use from script;
Bring it On!

First of all, you need to create exhaust.lua and allowmovement.lua in data folder

exhaust.lua - this is function that responsible for checking the exhaust
(not exist in TFS 1.1 i guess, thats why you need to add it):
Code:
function exhaust(cid, storevalue, exhausttime)
-- Returns 1 if not exhausted and 0 if exhausted  
    newExhaust = os.time()
    oldExhaust = getPlayerStorageValue(cid, storevalue)
    if (oldExhaust == nil or oldExhaust < 0) then
        oldExhaust = 0
    end
    if (exhausttime == nil or exhausttime < 0) then
        exhausttime = 1
    end
    diffTime = os.difftime(newExhaust, oldExhaust)
    if (diffTime >= exhausttime or diffTime < 0) then
        setPlayerStorageValue(cid, storevalue, newExhaust)
        return 1
    else
        return 0
    end
end
allowmovement.lua - this is function responsible for set no move to player
(player cant move to different sqm):
Code:
local function allowMovementEvent(cid, allow, oldPosition)
    local creature = Creature(cid)
    if not creature then
        return false
    end

    if allow then
        return stopEvent(event)
    else
        stopEvent(event)
    end

    creature:teleportTo(oldPosition, true)
    creature:sendCancelMessage('You cannot move.')
  
    event = addEvent(allowMovementEvent, 100, cid, allow, oldPosition)
end

function Creature.allowMovement(self, allow)
    allowMovementEvent(self:getId(), allow, self:getPosition())
end
Next declare it to your global.lua (add this code at the top of document):
Code:
dofile('data/exhaust.lua')
dofile('data/allowmovement.lua')

Finally it's time for homestone. Create in actions/scripts file named homestone.lua :
Code:
local config = {
waittime = 10, -- time in seconds to use homestone again.
storage = 2301, -- storage for `waittime`
level = 50, -- after this level you CANT use homestone.
cooldown = 5 -- how many seconds character must wait after use stone until get teleported.
}

function onUse(cid, item, fromPosition, target, toPosition, isHotkey)

local player = Player(cid)
local pos = player:getPosition()

if (player:getLevel() >= config.level) then
            player:sendCancelMessage('Only players under ' .. config.level .. ' can use homestone!')
            pos:sendMagicEffect(3)
else
if player:getCondition(CONDITION_INFIGHT, CONDITIONID_DEFAULT) then
            player:say('I cant do that in fight!', TALKTYPE_MONSTER_SAY)
            player:sendCancelMessage('You cannot use homestone while you during a fight!')
            pos:sendMagicEffect(3)
else
      
  
        if(exhaust(cid, config.storage, config.waittime) == 0) then
      
        local time = ((os.difftime(oldExhaust, newExhaust))-(50))
        local hours, minutes, seconds = math.floor (time / 3600), math.floor ((time - ((math.floor (time / 3600)) * 3600))/ 60), time - ((math.floor (time/60)) * 60)
        if time >= 3600 then
        text = hours.." "..(hours > 1 and "hours" or "hour")..", "..minutes.." "..(minutes > 1 and "minutes" or "minute").." and "..seconds.." "..(seconds > 1 and "seconds" or "second")
        elseif time >= 120 then
        text = minutes.." "..(minutes > 1 and "minutes" or "minute").." and "..seconds.." "..(seconds > 1 and "seconds" or "second")
        else
        text = seconds.." "..(seconds > 1 and "seconds" or "second")
        end
      
            player:sendCancelMessage('You need to wait ' .. text .. ' before you can use homestone again.')
            pos:sendMagicEffect(3)
        else

    function tped(cid)
        local player = Player(cid)
        local destination = player:getTown():getTemplePosition()
        local homeid = (getPlayerTown(player))
        local pos = player:getPosition()
            if not player then
                return false
            end
        item:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, "This stone can teleport player (under " .. config.level .. " level) to his home. \n Current home: "..getTownName(homeid)..".")
        pos:sendMagicEffect(40)
        player:teleportTo(destination)
        destination:sendMagicEffect(40)
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You have succesfully teleported to ' .. getTownName(homeid) .. '.')
        exhaust(cid, config.storage, config.waittime)
        setPlayerStorageValue(cid, 2302, 0)
        player:allowMovement(true)
    return true
    end
  
        addEvent(tped, (config.cooldown * 1000), cid)
        pos:sendMagicEffect(40)
        setPlayerStorageValue(cid, 2302, 1)
        player:allowMovement(false)
  
        end -- end re-use
  
end -- end pzlock
end -- end levelcap

    return true
end -- end function
Declare it in actions.xml :
Code:
    <action itemid="YOUR ITEMID" script="homestone.lua"/>

If you want magiceffect per second after using homestone until character get teleported, you need to create homestonefx.lua in creaturescripts.
homestonefx.lua :
Code:
function onThink(cid)
local player = Player(cid)
if (getPlayerStorageValue(cid, 2302) == 1)  then
player:getPosition():sendMagicEffect(40)
end
return true
end

Declare it in creaturescripts.xml :
Code:
<event type="think" name="Homestonefx" script="homestonefx.lua"/>

And register event in login.lua :
Code:
player:registerEvent("Homestonefx")

Thats all, have a nice use! :D:D:D
 
Movement prevention is an weird idea. It's better to allow player to move, but cancel teleporting sequence.
Here is a script I used in my evo datapack converted to 1.1(yeah it could be more efficient now and optimised, but it's from 28 jan 2014 and I'm too lazy to rewrite it)

Code:
-- <talkaction words="!home;/home;!spawn;/spawn" event="script" value="home.lua"/>
local level = 1 -- level to use this command
local loadingTime = 5 -- in seconds -- How long you have to wait until teleported
local storage = 58478
local exhaust = 60 -- Time until you can cast this command again

local exhaustion =
{
	check = function (cid, storage)
		if(Player(cid):getGroup():getAccess()) then
			return false
		end

		return getPlayerStorageValue(cid, storage) >= os.time()
	end,

	get = function (cid, storage)
		if(Player(cid):getGroup():getAccess()) then
			return false
		end

		local exhaust = getPlayerStorageValue(cid, storage)
		if(exhaust > 0) then
			local left = exhaust - os.time()
			if(left >= 0) then
				return left
			end
		end

		return false
	end,

	set = function (cid, storage, time)
		setPlayerStorageValue(cid, storage, os.time() + time)
	end,

	make = function (cid, storage, time)
		local exhaust = exhaustion.get(cid, storage)
		if(not exhaust) then
			exhaustion.set(cid, storage, time)
			return true
		end

		return false
	end
}

function countDown(n, cid)
if not isPlayer(cid) then return false end
local temple = Player(cid):getTown():getTemplePosition() -- destination position
	if getPlayerStorageValue(cid, storage) == 1 then
	local pos = getPlayerPosition(cid)
	local playerPos = getThingPos(cid)
	local function boom()
	doSendMagicEffect(pos, CONST_ME_TELEPORT)
	doTeleportThing(cid, temple)
	doSendMagicEffect(temple, CONST_ME_TELEPORT)
	setPlayerStorageValue(cid, storage, 0)
	end

		if getPlayerStorageValue(cid, storage + 1) == playerPos.x and getPlayerStorageValue(cid, storage + 2) == playerPos.y then
			if getCreatureCondition(cid, CONDITION_INFIGHT) and (not getTilePzInfo(getThingPos(cid))) then
				doPlayerSendTextMessage(cid,MESSAGE_STATUS_WARNING,"[Teleportation]: Process cancelled, enemy detected.")
				setPlayerStorageValue(cid, storage, 0)
			else
				if(n > 0) then
					if n == 1 then s = "" else s = "s" end
					doPlayerSendTextMessage(cid,MESSAGE_STATUS_CONSOLE_ORANGE,"[Teleportation]: " .. n .. " second" .. s .. " left.")
					doSendMagicEffect(pos, CONST_ME_TELEPORT)
					addEvent(countDown, 1000, n - 1, cid)
				else
					doPlayerSendTextMessage(cid,MESSAGE_STATUS_CONSOLE_ORANGE,"[Teleportation]: Process finished.")
					doSendMagicEffect(pos, CONST_ME_BIGCLOUDS)
					addEvent(boom, 500)
				end
			end
		else
			doPlayerSendTextMessage(cid,MESSAGE_STATUS_WARNING,"[Teleportation]: Process cancelled, movement detected.")
			setPlayerStorageValue(cid, storage, 0)
		end
	end
 
end
 
function onSay(player, words, param, channel, position)
	local cid = player:getId() -- to make it working on 1.0 remove :getId()
	if exhaustion.get(cid, 101) then
		if exhaustion.get(cid, 101) > 0 then
			if exhaustion.get(cid, 101) == 1 then s = "" else s = "s" end
			doPlayerSendCancel(cid, 'You are exhausted (' .. exhaustion.get(cid, 101) .. ' second' .. s .. ').')
			return false
		end
	end
	if isPlayerPzLocked(cid) then
		doPlayerSendTextMessage(cid, MESSAGE_STATUS_SMALL ,"You can\'t use this command during fight.")
		return false
	end 
	if getCreatureCondition(cid, CONDITION_INFIGHT) and (not getTilePzInfo(getThingPos(cid))) then
		doPlayerSendCancel(cid, 'You can\'t use this command during fight.')
        return false
    end
	if getPlayerLevel(cid) < level then
		doPlayerSendCancel(cid, 'You need level '..level..' to use this command.')
		return false
	end
	exhaustion.set(cid, 101, exhaust)
 
	local pos = getThingPos(cid)
	setPlayerStorageValue(cid, storage + 1, pos.x)
	setPlayerStorageValue(cid, storage + 2, pos.y)
	setPlayerStorageValue(cid, storage, 1)
 
	countDown(loadingTime, cid)
 
	return false
end
 
very good, I tried it on my server, everything works.
but I pull the following error when take to the temple.

TGlHoxQ.png


use TFS 1.1 and I followed the steps one by one

sorry for mi english :D
 
You not followed the steps one by one.
Just create simple allowmovement.lua instead of put it in 003-functions.lua.
Maybe any other function have declared "Storage" in your 003-functions.lua.

I got 0 errors.
Amen.
 
It's not my problem.
They should at least try.

I have other scripts to write.
 
Also stone detects what residence player have to teleport no?
Because if u have little time you can rewrite it to chosse diferents destinations?

All good atm and thnx for share homestone.lua ^^
 
Hello, I followed all the steps and check several times, I get this error on the console, but everything works fine. Could you help me ?.

Lua Script Error: [Action Interface]
data/actions/scripts/homestone.lua:eek:nUse
luaAddEvent(). Argument #3 is unsafe
stack traceback:
[C]: in function 'addEvent'
data/actions/scripts/homestone.lua:59: in function <data/actions/scripts/homestone.lua:8>
 
Hello, I followed all the steps and check several times, I get this error on the console, but everything works fine. Could you help me ?.

It's for the old 1.x.
Since tfs now pushes the userdata insted of the creature id you have to modify it abit.
Create a support thread, would have helped you but the script is too messy xD
 
Hello, I followed all the steps and check several times, I get this error on the console, but everything works fine. Could you help me ?.

In homestone.lua, change:
Code:
addEvent(tped, (config.cooldown * 1000), cid)

To:
Code:
addEvent(tped, (config.cooldown * 1000), cid.uid)

I had this same error at first, and this change made it work 100% :D
Also great script, TY for sharing!:)
 
Back
Top