• 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 Random Vocation NPC

vision26

New Member
Joined
Feb 27, 2021
Messages
8
Reaction score
1
Hi,

I need an Orcale like NPC that promote players to a random vocation from a list(possibly with a check prerequested item) thanks in advance.

tfs1.3
 
Untested.

XML:
<npc name="The Oracle" script="The Oracle.lua" walkinterval="0" speechbubble="3">
	<look typeex="1448" />
	<parameters>
		<parameter key="message_greet" value="|PLAYERNAME|, ARE YOU PREPARED TO FACE YOUR DESTINY?" />
		<parameter key="message_walkaway" value="COME BACK WHEN YOU ARE PREPARED TO FACE YOUR DESTINY!" />
		<parameter key="message_farewell" value="COME BACK WHEN YOU ARE PREPARED TO FACE YOUR DESTINY!" />
	</parameters>
</npc>
Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

local town = {}
local towns = {
	["thais"]  = {townId = 1, position = Position(100, 100, 7)},
	["carlin"] = {townId = 2, position = Position(100, 100, 7)},
}
local vocations = {1, 2, 3, 4}

function onCreatureAppear(cid)              npcHandler:onCreatureAppear(cid)            end
function onCreatureDisappear(cid)           npcHandler:onCreatureDisappear(cid)         end
function onCreatureSay(cid, type, msg)      npcHandler:onCreatureSay(cid, type, msg)    end
function onThink()                          npcHandler:onThink()                        end

local function greetCallback(cid)
	local player = Player(cid)
	local level = player:getLevel()
	if level < 8 then
		npcHandler:say("CHILD! COME BACK WHEN YOU HAVE GROWN UP!", cid)
		return false
	elseif level > 9 then
		npcHandler:say(player:getName() .. ", I CAN'T LET YOU LEAVE - YOU ARE TOO STRONG ALREADY! YOU CAN ONLY LEAVE WITH LEVEL 9 OR LOWER.", cid)
		return false
	end
	npcHandler.topic[cid] = 0
	return true
end

local function creatureSayCallback(cid, type, msg)
	if not npcHandler:isFocused(cid) then
		return false
	end
	
	local player = Player(cid)

	-- player answering if they wish to leave
	if msgcontains(msg, "yes") and npcHandler.topic[cid] == 0 then
		local townOptions = ""
		for v, k in pairs(towns) do
			if townOptions ~= "" then
				townOptions = townOptions .. ", "
			end
			townOptions = townOptions .. "{" .. (v:lower():gsub("(%l)(%w*)", function(a,b) return string.upper(a)..b end)) .. "}"
		end
		npcHandler:say("IN WHICH TOWN DO YOU WANT TO LIVE: " .. townOptions .. "?", cid)
		npcHandler.topic[cid] = 1
		return true
		
	-- player choosing their town
	elseif npcHandler.topic[cid] == 1 then
		local choice = msg:lower()
		for v, k in pairs(towns) do
			if v:lower() == choice then
				npcHandler:say("YOU HAVE CHOSEN " .. (choice:upper()) .. "! YOUR VOCATION WILL BE RANDOMISED! ARE YOU SURE YOU WISH TO LEAVE FOR THE MAINLAND? THIS DECISION IS IRREVERSIBLE!", cid)
				town[cid] = choice
				npcHandler.topic[cid] = 2
				return true
			end
		end
		local townOptions = ""
		for v, k in pairs(towns) do
			if townOptions ~= "" then
				townOptions = townOptions .. ", "
			end
			townOptions = townOptions .. "{" .. (v:lower():gsub("(%l)(%w*)", function(a,b) return string.upper(a)..b end)) .. "}"
		end
		npcHandler:say("THAT TOWN IS NOT KNOWN! IN WHICH TOWN DO YOU WANT TO LIVE: " .. townOptions .. "?", cid)
		return true
		
	-- player confirming they want to leave forever
	elseif npcHandler.topic[cid] == 2 then
		if not msgcontains(msg, "yes") then
			npcHandler:say("COME BACK WHEN YOU ARE PREPARED TO FACE YOUR DESTINY!", cid)
			npcHandler.topic[cid] = 0
			npcHandler:releaseFocus(cid)
			return true
		end
		npcHandler:say("SO BE IT!", cid)
		local vocation = vocations[math.random(#vocations)]
		player:setVocation(vocation)
		player:setTown(towns[town[cid]].townId)

		local destination = towns[town[cid]].position
		npcHandler:releaseFocus(cid)
		player:teleportTo(destination)
		player:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
		destination:sendMagicEffect(CONST_ME_TELEPORT)
		return true
		
	end
	return true
end

local function onAddFocus(cid)
	town[cid] = 0
end

local function onReleaseFocus(cid)
	town[cid] = nil
end

npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus)
npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus)

npcHandler:setCallback(CALLBACK_GREET, greetCallback)
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
bit more optimized code
Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

local town = {}
local towns = {
	["thais"]  = {townId = 1, position = Position(100, 100, 7)},
	["carlin"] = {townId = 2, position = Position(100, 100, 7)},
}
local vocations = {1, 2, 3, 4}

local function getTownList()
	local townOptions = ""
	for v, k in pairs(towns) do
		if townOptions ~= "" then
			townOptions = townOptions .. ", "
		end
		townOptions = townOptions .. "{" .. (v:lower():gsub("(%l)(%w*)", function(a,b) return string.upper(a)..b end)) .. "}"
	end
	return townOptions
end

function onCreatureAppear(cid)              npcHandler:onCreatureAppear(cid)            end
function onCreatureDisappear(cid)           npcHandler:onCreatureDisappear(cid)         end
function onCreatureSay(cid, type, msg)      npcHandler:onCreatureSay(cid, type, msg)    end
function onThink()                          npcHandler:onThink()                        end

local function greetCallback(cid)
	local player = Player(cid)
	local level = player:getLevel()
	if level < 8 then
		npcHandler:say("CHILD! COME BACK WHEN YOU HAVE GROWN UP!", cid)
		return false
	elseif level > 9 then
		npcHandler:say(player:getName() .. ", I CAN'T LET YOU LEAVE - YOU ARE TOO STRONG ALREADY! YOU CAN ONLY LEAVE WITH LEVEL 9 OR LOWER.", cid)
		return false
	end
	npcHandler.topic[cid] = 0
	return true
end

local function creatureSayCallback(cid, type, msg)
	if not npcHandler:isFocused(cid) then
		return false
	end
	
	local player = Player(cid)

	-- player answering if they wish to leave
	if msgcontains(msg, "yes") and npcHandler.topic[cid] == 0 then
		npcHandler:say("IN WHICH TOWN DO YOU WANT TO LIVE: " .. getTownList() .. "?", cid)
		npcHandler.topic[cid] = 1
		return true
		
	-- player choosing their town
	elseif npcHandler.topic[cid] == 1 then
		local choice = msg:lower()
		if not towns[choice] then
			npcHandler:say("THAT TOWN IS NOT KNOWN! IN WHICH TOWN DO YOU WANT TO LIVE: " .. getTownList() .. "?", cid)
			return true
		end
		npcHandler:say("YOU HAVE CHOSEN " .. (choice:upper()) .. "! YOUR VOCATION WILL BE RANDOMISED! ARE YOU SURE YOU WISH TO LEAVE FOR THE MAINLAND? THIS DECISION IS IRREVERSIBLE!", cid)
		town[cid] = choice
		npcHandler.topic[cid] = 2
		return true
		
	-- player confirming they want to leave forever
	elseif npcHandler.topic[cid] == 2 then
		if not msgcontains(msg, "yes") then
			npcHandler:say("COME BACK WHEN YOU ARE PREPARED TO FACE YOUR DESTINY!", cid)
			npcHandler.topic[cid] = 0
			npcHandler:releaseFocus(cid)
			return true
		end
		npcHandler:say("SO BE IT!", cid)
		local vocation = vocations[math.random(#vocations)]
		player:setVocation(vocation)
		player:setTown(towns[town[cid]].townId)

		local destination = towns[town[cid]].position
		npcHandler:releaseFocus(cid)
		player:teleportTo(destination)
		player:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
		destination:sendMagicEffect(CONST_ME_TELEPORT)
		return true
		
	end
	return true
end

local function onAddFocus(cid)
	town[cid] = 0
end

local function onReleaseFocus(cid)
	town[cid] = nil
end

npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus)
npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus)

npcHandler:setCallback(CALLBACK_GREET, greetCallback)
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
Back
Top