The hairycles dynamic trade list and greet:Could you post an example of an NPC you have had in use? Would be nice to see in a educational purpose.
local function getTable(cid)
local player = Player(cid)
local itemsList = {
{name="Banana", id=2676, buy=2},
}
local statues = {
{name="Monkey Statue (No Seeing)", id=5086, buy=65},
{name="Monkey Statue (No Hearing)", id=5087, buy=65},
{name="Monkey Statue (No Speaking)", id=5088, buy=65}
}
if player:getStorageValue(Storage.TheApeCity.Questline) >= 23 then
for i = 1, #statues do
table.insert(itemsList, statues[i])
end
end
return itemsList
end
local function onTradeRequest(cid)
return (Player(cid):getStorageValue(Storage.TheApeCity.Mission06) >= 3)
end
local function greetCallback(cid)
local player = Player(cid)
if player:getStorageValue(Storage.TheApeCity.Questline) <= 14 then
npcHandler:setMessage(MESSAGE_GREET, "Oh! Hello! Hello! Did not notice!")
elseif player:getStorageValue(Storage.TheApeCity.Questline) >= 15 then
npcHandler:setMessage(MESSAGE_GREET, "Be greeted, friend of the ape people. If you want to trade, just ask for my offers. If you are injured, ask for healing.")
end
return true
end
npc:setCallback(CALLBACK_GETTRADEITEMLIST, getTable)
npc:setCallback(CALLBACK_ONTRADEREQUEST, onTradeRequest)
npc:setCallback(CALLBACK_GREET, greetCallback)
local npc = NPC({
name = "King Tibianus",
city = "Thais",
look = {
id = 332,
head = 0,
body = 0,
legs = 0,
feet = 0,
addons = 0
},
phrases = {
greetings = {
{'hail', 'king'},
{'hello', 'king'},
{'salutations', 'king'},
}
},
messages = {
greet = "I greet thee, my loyal {subject} |PLAYERNAME|.",
farewell = "Good bye, |PLAYERNAME|!",
walkaway = "How rude!"
},
promotion = 20000,
roles = {
"promotion",
},
quests = {
"the isle of evil quest",
"the new frontier quest"
},
actor = "King Tibianus"
})
function onThink()
npc:onThink()
end
function onCreatureSay(creature, type, msg)
npc:onSpeak(creature, type, msg)
end
function onCreatureDisappear(creature)
npc:onDisappear(creature)
end
function onPlayerCloseChannel(creature)
npc:onCloseChannel(creature)
end
local plugin = {}
plugin.name = "Promotion"
plugin.events = {}
function plugin.events.onPromotion(state, event, from, to)
local player = state.player
local npc = state.npc
local msg = state.lastMessage
if from == 'none' then
npc:talk("Do you want to be promoted in your vocation for 20000 gold?", player)
return true
elseif from == 'confirm' then
if not msg:contains("yes") then
npc:talk("Ok, then not.", player)
return true
end
if player:getLevel() < 20 then
npc:talk("You need to be at least level 20 in order to be promoted.", player)
return true
end
local promotion = player:getVocation():getPromotion()
if not promotion then
npc:talk("You are already promoted.", player)
return true
end
if not player:removeMoney(20000) then
npc:talk("You do not have enough money.", player)
return true
end
player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE)
npc:talk("Congratulations! You are now promoted. Visit the sage Eremo for new spells.", player)
player:setVocation(promotion)
return true
end
return false
end
plugin.states = {
{name = 'promotion', from = 'none', to = 'confirm'},
{name = 'promotion', from = 'confirm', to = 'none'},
}
return plugin
thanks for sharing but apparently there are some design flaws in your example as well. If I'm already promoted why the npc would ask if I want to get promoted and wait for me to confirm before saying I can't do that? Imagine for longer and deeper dialogs, will I have to treat each case? Also this states you created are very confusing and easy to lost the flow.If there's interest in a new system I can see about open-sourcing OX's NPC system.
It looks like it's what inspired this thread.
Example NPC:
Lua:local npc = NPC({ name = "King Tibianus", city = "Thais", look = { id = 332, head = 0, body = 0, legs = 0, feet = 0, addons = 0 }, phrases = { greetings = { {'hail', 'king'}, {'hello', 'king'}, {'salutations', 'king'}, } }, messages = { greet = "I greet thee, my loyal {subject} |PLAYERNAME|.", farewell = "Good bye, |PLAYERNAME|!", walkaway = "How rude!" }, promotion = 20000, roles = { "promotion", }, quests = { "the isle of evil quest", "the new frontier quest" }, actor = "King Tibianus" }) function onThink() npc:onThink() end function onCreatureSay(creature, type, msg) npc:onSpeak(creature, type, msg) end function onCreatureDisappear(creature) npc:onDisappear(creature) end function onPlayerCloseChannel(creature) npc:onCloseChannel(creature) end
Example role:
Lua:local plugin = {} plugin.name = "Promotion" plugin.events = {} function plugin.events.onPromotion(state, event, from, to) local player = state.player local npc = state.npc local msg = state.lastMessage if from == 'none' then npc:talk("Do you want to be promoted in your vocation for 20000 gold?", player) return true elseif from == 'confirm' then if not msg:contains("yes") then npc:talk("Ok, then not.", player) return true end if player:getLevel() < 20 then npc:talk("You need to be at least level 20 in order to be promoted.", player) return true end local promotion = player:getVocation():getPromotion() if not promotion then npc:talk("You are already promoted.", player) return true end if not player:removeMoney(20000) then npc:talk("You do not have enough money.", player) return true end player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) npc:talk("Congratulations! You are now promoted. Visit the sage Eremo for new spells.", player) player:setVocation(promotion) return true end return false end plugin.states = { {name = 'promotion', from = 'none', to = 'confirm'}, {name = 'promotion', from = 'confirm', to = 'none'}, } return plugin
thanks for sharing but apparently there are some design flaws in your example as well. If I'm already promoted why the npc would ask if I want to get promoted and wait for me to confirm before saying I can't do that? Imagine for longer and deeper dialogs, will I have to treat each case? Also this states you created are very confusing and easy to lost the flow.
real tibia also sucks. Cipsoft is just a regular company with very below-average developers. Also the game is a huge legacy project dated over 20 years? Everytime I see a 201X developer trying to use something like the leaked files "because it seems better" I die a little on the inside.
Your design was not friendly made, you may also not see it because you've spent many hours adapting to it. Dealing with "from" and "to" is unnecessary since you could just use numbers in the events and use the order in one single parameter as showed in [Lua] local npc = new NPC("Chondur") -- Loads default, passes name ---- internally, - Pastebin.com (https://pastebin.com/WHjdCY8v). This would also make it easier to adapt the conditions for multiple events using isInArray.
In my honest opinion, the sooner we start to move TFS to the next level (drop the anchor that is this dumb compatibility), the best it will be for this community. We need new designs, new architectures and new thinking. Explore more scripting languages and making changes way more dynamical than it is now. This would also make TFS WAAAAAY more stable as scripts usually don't crash the server, specially with well treated.
heyy, thats pretty cool, would you release it? I remember when Jiddo posted the new lua npc system on otfans, that was so cool and I was so young to understand, yours might be 10x times better.If there's interest in a new system I can see about open-sourcing OX's NPC system.
It looks like it's what inspired this thread.
Example NPC:
Lua:local npc = NPC({ name = "King Tibianus", city = "Thais", look = { id = 332, head = 0, body = 0, legs = 0, feet = 0, addons = 0 }, phrases = { greetings = { {'hail', 'king'}, {'hello', 'king'}, {'salutations', 'king'}, } }, messages = { greet = "I greet thee, my loyal {subject} |PLAYERNAME|.", farewell = "Good bye, |PLAYERNAME|!", walkaway = "How rude!" }, promotion = 20000, roles = { "promotion", }, quests = { "the isle of evil quest", "the new frontier quest" }, actor = "King Tibianus" }) function onThink() npc:onThink() end function onCreatureSay(creature, type, msg) npc:onSpeak(creature, type, msg) end function onCreatureDisappear(creature) npc:onDisappear(creature) end function onPlayerCloseChannel(creature) npc:onCloseChannel(creature) end
Example role:
Lua:local plugin = {} plugin.name = "Promotion" plugin.events = {} function plugin.events.onPromotion(state, event, from, to) local player = state.player local npc = state.npc local msg = state.lastMessage if from == 'none' then npc:talk("Do you want to be promoted in your vocation for 20000 gold?", player) return true elseif from == 'confirm' then if not msg:contains("yes") then npc:talk("Ok, then not.", player) return true end if player:getLevel() < 20 then npc:talk("You need to be at least level 20 in order to be promoted.", player) return true end local promotion = player:getVocation():getPromotion() if not promotion then npc:talk("You are already promoted.", player) return true end if not player:removeMoney(20000) then npc:talk("You do not have enough money.", player) return true end player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) npc:talk("Congratulations! You are now promoted. Visit the sage Eremo for new spells.", player) player:setVocation(promotion) return true end return false end plugin.states = { {name = 'promotion', from = 'none', to = 'confirm'}, {name = 'promotion', from = 'confirm', to = 'none'}, } return plugin
heyy, thats pretty cool, would you release it? I remember when Jiddo posted the new lua npc system on otfans, that was so cool and I was so young to understand, yours might be 10x times better.
How old are you?I don't know @Night Wolf said mine isn't that good, so I'm going to let him develop one.
He's got a great vision for the community.
How old are you?
I guess that does not matters but ofc its your system so you decide if its posted or nay, thanks anyways ^^I don't know @Night Wolf said mine isn't that good, so I'm going to let him develop one.
He's got a great vision for the community.
I guess that does not matters but ofc its your system so you decide if its posted or nay, thanks anyways ^^
You're in a forum dedicated to Open Tibia, based off of CipSoft's game, so I would be a bit more respectful.
I understood what you meant with the file from your server but I'm saying even if you shared the whole system and did a PR to the official repo, it would still be as limited as it is today, all you did was put the limitations from XML to Lua.I didn't write this example for this thread, I simply pasted it from our REAL TIBIA SERVER.
My problem with tibia is that the community is very small and greedy. This make highly technical people like me be frustrated because others usually don't care about concepts like complexity, secure programming and architecture design and those are things you have to use in the very beginning phase of development, otherwise things tend to go very wrong. Also the people who could help in these topics usually only develops for private servers, and they didn't even share their work when the project dies. Again, it's nothing personal with you, you're just like many others here in community. Speaking of that, Isn't OTX that server that was banned for spoofing otserverlist and that was ruined because developers couldn't fix the crashes? oh.You would be better of going to a forum dedicated to general game development if you don't like Tibia.
Again, the system does support what you were asking, but you seem to know what you're doing, so I'll let you develop whatever it is you're trying to do. Good luck.
Optimizations have nothing to do with what the game is. Check this analogy:If you start optimizing everything then where do we draw the line for calling the game Tibia still?
function Sum100(x) return x + 100 end
function Sum100(x)
for i = 1, 100 do x = x + 1 end
return x
end