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

Simulate Cipsoft NPC System

Ezzz

Developer of Nostalrius and The Violet Project
Joined
Feb 26, 2010
Messages
1,889
Solutions
3
Reaction score
795
Location
Spain, Europe
I'm wondering if you guys find this code system, hard to do;

Lua:
local Behavior = {
{key = "name|job", text = "You are %N."},
{Bool = not msgcontains(msg, "healing") and not msgcontains(msg, "support") and Knight(cid), key = "spell", text = "I can teach you healing spells and support spells. What kind of spell do you wish to learn? You can also tell me for which level you would like to learn a spell, if you prefer that.", SetTopic = 1},
{key = "spell", text = "Sorry, only for knights."},


{key = "key", text = "Do you want to buy the key for %P gold?", Price = 0, Amount = 1, Type = 2086, Action = 100, SetTopic = 5},
{Bool = isTopic(config, 5) and CountMoney(cid)>=config.Price, key = "yes", text = "Here you are.", Create = config.Type},
{Bool = isTopic(config, 5), key = "yes", text = "You have no money."},
{Bool = isTopic(config, 5), key = msg, text = "Other day."},


{Bool = Count(msg)>1 and notSell(msg), key = "apple", Price = 2*Count(msg), Type = 2376, Amount = Count(msg), text = "Do you want to buy %A red apples for %P gold?", SetTopic = 2},
{Bool = Count(msg)>1, key = "apple", Price = 1*Count(msg), Type = 2376, Amount = Count(msg), text = "Do you want to sell %A red apples for %P gold?", SetTopic = 4},


{Bool = notSell(msg), key = "apple", Price = 2, Type = 2376, Amount = 1, text = "Do you want to buy a red apple for %P gold?", SetTopic = 2},
{key = "apple", Price = 1, Type = 2376, Amount = 1, text = "Do you want to sell a red apple for %P gold?", SetTopic = 4},


{Bool = Knight(cid), key = "light", text = "Do you want to buy the spell 'Light' for %P gold?", Price = 100, Spell = "light", SetTopic = 3},


{Bool = Knight(cid), key = "healing spell", text = "In this category I have 'Light Healing' and 'Antidote'."},
{Bool = Knight(cid), key = "support spell", text = "In this category I have 'Light', 'Find Person' and 'Great Light'."},
{Bool = Knight(cid) and isTopic(config, 1), key = "8", text = "For level 8 I have 'Find Person' and 'Light'.", SetTopic = 1},
{Bool = Knight(cid) and isTopic(config, 1), key = "9", text = "For level 9 I have 'Light Healing'.", SetTopic = 1},
{Bool = Knight(cid) and isTopic(config, 1), key = "10", text = "For level 10 I have 'Antidote'.", SetTopic = 1},
{Bool = Knight(cid) and isTopic(config, 1), key = "13", text = "For level 13 I have 'Great Light'.", SetTopic = 1},
{Bool = Knight(cid) and isTopic(config, 1), key = msg .. "$", text = "Sorry, I have only spells for level 8, 9, 10 and 13.", SetTopic = 1},


{Bool = isTopic(config, 3) and SpellKnown(cid, config.Spell)==1, key = "yes", text = "You have already learned this spell."},
{Bool = isTopic(config, 3) and Level(cid)<SpellLevel(cid, config.Spell), key = "yes", text = "You have to be level %A, %N.", Amount = SpellLevel(cid, config.Spell)},
{Bool = isTopic(config, 3) and SpellKnown(cid, config.Spell)==0 and CountMoney(cid)>=config.Price, key = "yes", text = "Here you are.", DeleteMoney = config.Price, LearnSpell = config.Spell, EffectOpp=13},
{Bool = isTopic(config, 3) and CountMoney(cid)<config.Price, key = "yes", text = "You have not enough money."},
{Bool = isTopic(config, 3), key = msg, text = "Maybe other time."},


{Bool = isTopic(config, 2) and CountMoney(cid)>=config.Price, key = "yes", text = "Thank you!", Create = config.Type, DeleteMoney = config.Price},
{Bool = isTopic(config, 2), key = "yes", text = "Atleast someone is poorer than me!"},
{Bool = isTopic(config, 2), key = msg, text = "Other day then."},


{Bool = isTopic(config, 4) and ItemCount(cid, config.Type)>=config.Amount, key = "yes", text = "Thank you!", Delete = config.Type, CreateMoney = config.Price},
{Bool = isTopic(config, 4), key = "yes", text = "Atleast someone is poorer than me!"},
{Bool = isTopic(config, 4), key = msg, text = "Other day then."}
}
 
Code:
Bool = isTopic(config, 4) and ItemCount(cid, config.Type)>=config.Amount

Will this work though? Won't Bool be evaluated during creation?
 
Pretty interesting, I'm sure someone might find it useful.
I've seen CipSoft's NPC system before, I've always thought it was the simplest piece of code for NPCs I've ever seen.
 
Code:
Bool = isTopic(config, 4) and ItemCount(cid, config.Type)>=config.Amount

Will this work though? Won't Bool be evaluated during creation?
Behavior is being created only when the script is called. In this case onCreatureSay.

Also it's being interpreted by another LUA function.
 
Oh, I see. A little bit wasteful to create it every time, but probably makes the actual NPC code cleaner.
 
Yes it can be a little messy, but only because of the interpreter capabilities.

Here is how it looks;

Lua:
local config = {Topic = 0, Price = -1, Spell = "light", Amount = -1, Type = -1, Action = -1, SubType = -1}
local onDiss = "Be careful on your journeys."
local onAway = "Be careful on your journeys."


function getNext() nextPlayer = getQueuedPlayer() if (nextPlayer ~= nil) then if (getDistanceToCreature(nextPlayer) <= 3) then updateNpcIdle() setNpcFocus(nextPlayer) greet(nextPlayer) return else getNext() end end setNpcFocus(0) resetNpcIdle() end
function _selfSay(message) selfSay(message, 1000) updateNpcIdle() end
function onCreatureMove(cid, oldPos, newPos) if (getNpcFocus() == cid) then faceCreature(cid) end end
function onCreatureDisappear(cid) if (getNpcFocus() == cid) then _selfSay(onDiss) getNext() else unqueuePlayer(cid) end end
function onThink() if (getNpcFocus() ~= 0) then if (isNpcIdle() or getDistanceToCreature(getNpcFocus()) > 3) then _selfSay(onAway) getNext() end end end


function onCreatureSay(cid, type, msg)
local Behavior = {
{key = "name|job", text = "You are %N."},
{Bool = not msgcontains(msg, "healing") and not msgcontains(msg, "support") and Knight(cid), key = "spell", text = "I can teach you healing spells and support spells. What kind of spell do you wish to learn? You can also tell me for which level you would like to learn a spell, if you prefer that.", SetTopic = 1},
{key = "spell", text = "Sorry, only for knights."},


{key = "key", text = "Do you want to buy the key for %P gold?", Price = 0, Amount = 1, Type = 2086, Action = 100, SetTopic = 5},
{Bool = isTopic(config, 5) and CountMoney(cid)>=config.Price, key = "yes", text = "Here you are.", Create = config.Type},
{Bool = isTopic(config, 5), key = "yes", text = "You have no money."},
{Bool = isTopic(config, 5), key = msg, text = "Other day."},


{Bool = Count(msg)>1 and notSell(msg), key = "apple", Price = 2*Count(msg), Type = 2376, Amount = Count(msg), text = "Do you want to buy %A red apples for %P gold?", SetTopic = 2},
{Bool = Count(msg)>1, key = "apple", Price = 1*Count(msg), Type = 2376, Amount = Count(msg), text = "Do you want to sell %A red apples for %P gold?", SetTopic = 4},


{Bool = notSell(msg), key = "apple", Price = 2, Type = 2376, Amount = 1, text = "Do you want to buy a red apple for %P gold?", SetTopic = 2},
{key = "apple", Price = 1, Type = 2376, Amount = 1, text = "Do you want to sell a red apple for %P gold?", SetTopic = 4},


{Bool = Knight(cid), key = "light", text = "Do you want to buy the spell 'Light' for %P gold?", Price = 100, Spell = "light", SetTopic = 3},


{Bool = Knight(cid), key = "healing spell", text = "In this category I have 'Light Healing' and 'Antidote'."},
{Bool = Knight(cid), key = "support spell", text = "In this category I have 'Light', 'Find Person' and 'Great Light'."},
{Bool = Knight(cid) and isTopic(config, 1), key = "8", text = "For level 8 I have 'Find Person' and 'Light'.", SetTopic = 1},
{Bool = Knight(cid) and isTopic(config, 1), key = "9", text = "For level 9 I have 'Light Healing'.", SetTopic = 1},
{Bool = Knight(cid) and isTopic(config, 1), key = "10", text = "For level 10 I have 'Antidote'.", SetTopic = 1},
{Bool = Knight(cid) and isTopic(config, 1), key = "13", text = "For level 13 I have 'Great Light'.", SetTopic = 1},
{Bool = Knight(cid) and isTopic(config, 1), key = msg .. "$", text = "Sorry, I have only spells for level 8, 9, 10 and 13.", SetTopic = 1},


{Bool = isTopic(config, 3) and SpellKnown(cid, config.Spell)==1, key = "yes", text = "You have already learned this spell."},
{Bool = isTopic(config, 3) and Level(cid)<SpellLevel(cid, config.Spell), key = "yes", text = "You have to be level %A, %N.", Amount = SpellLevel(cid, config.Spell)},
{Bool = isTopic(config, 3) and SpellKnown(cid, config.Spell)==0 and CountMoney(cid)>=config.Price, key = "yes", text = "Here you are.", DeleteMoney = config.Price, LearnSpell = config.Spell, EffectOpp=13},
{Bool = isTopic(config, 3) and CountMoney(cid)<config.Price, key = "yes", text = "You have not enough money."},
{Bool = isTopic(config, 3), key = msg, text = "Maybe other time."},


{Bool = isTopic(config, 2) and CountMoney(cid)>=config.Price, key = "yes", text = "Thank you!", Create = config.Type, DeleteMoney = config.Price},
{Bool = isTopic(config, 2), key = "yes", text = "Atleast someone is poorer than me!"},
{Bool = isTopic(config, 2), key = msg, text = "Other day then."},


{Bool = isTopic(config, 4) and ItemCount(cid, config.Type)>=config.Amount, key = "yes", text = "Thank you!", Delete = config.Type, CreateMoney = config.Price},
{Bool = isTopic(config, 4), key = "yes", text = "Atleast someone is poorer than me!"},
{Bool = isTopic(config, 4), key = msg, text = "Other day then."}
}


    if (getNpcFocus() == 0) then
        if ((isMsg("hi|hello", msg) and getDistanceToCreature(cid) <= 3)) then
            updateNpcIdle()
            setNpcFocus(cid)
            _selfSay("Hello.")
        end
            
    elseif (getNpcFocus() ~= cid) then
        if ((isMsg("hi|hello", msg) and getDistanceToCreature(cid) <= 3)) then
            _selfSay("...")
            queuePlayer(cid)
        end
            
    else
        if (isMsg("bye|farewell", msg)) then
            _selfSay("Be careful on your journeys.")
            getNext()
            return false
        end


        if ReactAt(cid, getNpcCid(), msg, Behavior, config) then
            updateNpcIdle()
        end
    end
end

Now Gregor Replica (Knight Guildmaster from Thais)

Lua:
local config = {Topic = 0, Price = -1, Spell = "light", Amount = -1, Type = -1, Action = -1, SubType = -1}
local onDiss = "Be careful on your journeys."
local onAway = "Be careful on your journeys."


function getNext() nextPlayer = getQueuedPlayer() if (nextPlayer ~= nil) then if (getDistanceToCreature(nextPlayer) <= 3) then updateNpcIdle() setNpcFocus(nextPlayer) greet(nextPlayer) return else getNext() end end setNpcFocus(0) resetNpcIdle() end
function _selfSay(message) selfSay(message, 1000) updateNpcIdle() end
function onCreatureMove(cid, oldPos, newPos) if (getNpcFocus() == cid) then faceCreature(cid) end end
function onCreatureDisappear(cid) if (getNpcFocus() == cid) then _selfSay(onDiss) getNext() else unqueuePlayer(cid) end end
function onThink() if (getNpcFocus() ~= 0) then if (isNpcIdle() or getDistanceToCreature(getNpcFocus()) > 3) then _selfSay(onAway) getNext() end end end


function onCreatureSay(cid, type, msg)
local Behavior = {
{key = "job", text = "I am the first knight. I trained some of the greatest heroes of Tibia."},
{key = "name", text = "You are joking, eh? Of course, you know me. I am Gregor, the first knight."},
{key = "time", text = "It is time to join the Knights!"},
{key = "king|tibianus", text = "Hail to our King!"},
{key = "quentin", text = "I will never understand this peaceful monks and priests."},
{key = "lynda", text = "Before she became a priest she won the Miss Tibia contest three times in a row."},
{key = "harkath", text = "One of Tibia's greatest warriors and strategists."},
{key = "army", text = "I teached many of the guards personally."},
{key = "ferumbras", text = "A fine game to hunt. But be careful, he cheats!"},
{key = "general", text = "General Harkath Bloodblade, a rolemodel."},
{key = "sam", text = "He has the muscles, but lacks the guts."},
{key = "gorn", text = "Always concerned with his profit. What a loss! He was adventuring with baxter in the old days."},
{key = "frodo", text = "I and my students often share a cask of beer or wine at Frodo's hut."},
{key = "elane", text = "A bow might be a fine weapon for someone not strong enough to wield a REAL weapon."},
{key = "muriel", text = "Bah, go away with these sorcerer tricks. Only cowards use tricks."},
{key = "gregor", text = "A great name, isn't it?"},
{key = "marvik", text = "Old Marvik saved life and limb of many of my boys and girls."},
{key = "bozo", text = "Some day someone will make something happen to him..."},
{key = "baxter", text = "He was an adventurer once."},
{key = "oswald", text = "What an idiot."},
{key = "donald|sherry|mcronald", text = "Peaceful farmers."},
{key = "lugri", text = "If he would have some guts he would fight for what he's talking about."},
{key = "excalibug", text = "Many brave warriors died on the quest to find that fabled weapon."},
{key = "news", text = "Times of war are at hand."},
{key = "hero", text = "Of course, you heard of them. Knights are the best fighters in Tibia."},
{key = "tibia", text = "Beautiful Tibia. And with our help everyone is safe."},
{key = "knight", text = "Knights are the warriors of Tibia. Without us, no one would be safe. Every brave and strong man or woman can join us."},
{key = "vocation", text = "Your vocation is your profession. There are four vocations in Tibia: Knights, paladins, sorcerers, and druids."},
{key = "spellbook", text = "In a spellbook, your spells are listed. There you will find the pronunciation of each spell. If you want to buy one, visit Muriel, the sorcerer."},


{Bool = Knight(cid), key = "instant spell", text = "I can teach you healing spells and support spells. What kind of spell do you wish to learn?"},
{Bool = Knight(cid), key = "healing spell", text = "In this category I have 'Light Healing' and 'Antidote'."},
{Bool = Knight(cid), key = "support spell", text = "In this category I have 'Light', 'Find Person' and 'Great Light'."},


{Bool = Knight(cid), key = "spell", text = "I can teach you healing spells and support spells. What kind of spell do you wish to learn? You can also tell me for which level you would like to learn a spell, if you prefer that.", SetTopic=2},
{key = "spell", text = "Sorry, I only sell spells to knights."},


{Bool = Knight(cid), key = "light healing", text = "Do you want to buy the spell 'Light Healing' for %P gold?", SetTopic=3, Price=170, Spell="light healing"},
{Bool = Knight(cid), key = "great light", text = "Do you want to buy the spell 'Great Light' for %P gold?", SetTopic=3, Price=500, Spell="great light"},
{Bool = Knight(cid), key = "find person", text = "Do you want to buy the spell 'Find Person' for %P gold?", SetTopic=3, Price=80, Spell="find person"},
{Bool = Knight(cid), key = "light", text = "Do you want to buy the spell 'Light' for %P gold?", SetTopic=3, Price=100, Spell="light"},
{Bool = Knight(cid), key = "antidote", text = "Do you want to buy the spell 'Antidote' for %P gold?", SetTopic=3, Price=150, Spell="antidote"},


{Bool = isTopic(config, 2), key = "8$", text = "For level 8 I have 'Find Person' and 'Light'.", SetTopic=2},
{Bool = isTopic(config, 2), key = "9$", text = "For level 9 I have 'Light Healing'.", SetTopic=2},
{Bool = isTopic(config, 2), key = "10$", text = "For level 10 I have 'Antidote'.", SetTopic=2},
{Bool = isTopic(config, 2), key = "13$", text = "For level 13 I have 'Great Light'.", SetTopic=2},
{Bool = isTopic(config, 2), key = msg, text = "Sorry, I have only spells for level 8, 9, 10 and 13.", SetTopic=2},


{Bool = isTopic(config, 3) and SpellKnown(cid, config.Spell)==1, key = "yes", text = "You already know how to cast this spell."},
{Bool = isTopic(config, 3) and Level(cid)<SpellLevel(cid, config.Spell), key = "yes", text = "You have to be level %A to learn this spell.", Amount=SpellLevel(cid, config.Spell)},
{Bool = isTopic(config, 3) and CountMoney(cid)<config.Price, key = "yes", text = "Return when you have enough gold."},
{Bool = isTopic(config, 3), key = "yes", text = "Here you are. Look in your spellbook for the pronunciation of this spell.", DeleteMoney=config.Price, EffectOpp=13, TeachSpell=config.Spell},
{Bool = isTopic(config, 3), key = msg, text = "Maybe next time."}
}


	if (getNpcFocus() == 0) then
		if ((isMsg("hi|hello", msg) and getDistanceToCreature(cid) <= 3)) then
			updateNpcIdle()
			setNpcFocus(cid)
			if Knight(cid) then
				_selfSay("Welcome home, Knight " .. getName(cid) .. "!")
			else
				_selfSay("Greetings, " .. getName(cid) .. ". What do you wand?")
			end
		end
			
	elseif (getNpcFocus() ~= cid) then
		if ((isMsg("hi|hello", msg) and getDistanceToCreature(cid) <= 3)) then
			_selfSay("Please wait a moment, " .. getName(cid) .. ".")
			queuePlayer(cid)
		end
			
	else
		if (isMsg("bye|farewell", msg)) then
			_selfSay("Be careful on your journeys.")
			getNext()
			return false
		end


		if ReactAt(cid, getNpcCid(), msg, Behavior, config) then
			updateNpcIdle()
		end
	end
end

Remember I did this because I'm recreating Tibia 7.7 including all NPCs and scripts. I've completed 2 cities so far.
 
Last edited:
easier and better to make a parser to convert the scripts than to make a system that reads it. They've probably already rewrote their system a dozen times because the one at that time was way too damn simple. Easy to read, yes, but it lacks in functionality.
 
Back
Top