• 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!
  • New resources must be posted under Resources tab. A discussion thread will be created automatically, you can't open threads manually anymore.

NPC Noobish one.

EvulMastah

๏̯͡๏﴿
Premium User
Joined
Aug 19, 2007
Messages
4,941
Solutions
11
Reaction score
352
I've made it on request of chanukah at **fans, guess its not very needed but I'll post it here too.

If you didnt enable NPCs to cast commands then it wont work.

1st:
You will need this thingy at global.lua (which wasnt made by me)

PHP:
WEAPONTYPE_CLUB = 1
WEAPONTYPE_SWORD = 2
WEAPONTYPE_AXE = 3
WEAPONTYPE_DISTANCE = 4
WEAPONTYPE_WAND = 5
WEAPONTYPE_ROD = 6

WEAPON_CLUB = {
           2321, 2382, 2391, 2394, 2398, 2401, 2416, 2417, 2421, 2422, 2423, 2424, 2433, 2434, 2436, 2437, 2439, 2444, 2445, 2448, 2449, 2452, 2453, 3961, 3966, 4846, 7379, 7381, 7387, 7392, 7410, 7414, 7415, 7424, 7425, 7426, 7427, 7429, 7430, 7431, 7432, 7437, 7451, 7452
          }
WEAPON_SWORD = {
            2376, 2377, 2379, 2383, 2384, 2385, 2390, 2392, 2393, 2395, 2396, 2397, 2400, 2402, 2403, 2404, 2406, 2407, 2408, 2409, 2411, 2412, 2413, 2419, 2420, 2438, 2442, 2446, 2450, 2451, 3963, 6101, 6528, 7382, 7383, 7384, 7385, 7386, 7390, 7402, 7404, 7405, 7406, 7407, 7408, 7416, 7449
           }
WEAPON_AXE = {
          2378, 2380, 2381, 2386, 2387, 2388, 2405, 2414, 2415, 2418, 2425, 2426, 2427, 2428, 2429, 2430, 2431, 2432, 2435, 2440, 2441, 2443, 2447, 2454, 2550, 2559, 3962, 3964, 6553, 7380, 7388, 7389, 7412, 7413, 7419, 7434
         }
WEAPON_WAND = {
           2187, 2188, 2189, 2190, 2191
          }
WEAPON_ROD = {
          2181, 2182, 2183, 2185, 2186
         }

WEAPON_DISTANCE = {
                   1294, 2111, 2389, 2399, 2410, 2455, 2456, 3965, 5803, 7366, 7367, 7368, 7378, 7438
                   }

function isWeapon(itemId)
    if(getWeaponType(itemId) ~= FALSE) then
		return TRUE
	else
		return FALSE
	end
end

function getWeaponType(itemId)
	if isInArray(WEAPON_CLUB, itemId) then
		return WEAPONTYPE_CLUB
	elseif isInArray(WEAPON_AXE, itemId) then
		return WEAPONTYPE_AXE
	elseif isInArray(WEAPON_SWORD, itemId) then
		return WEAPONTYPE_SWORD
	elseif isInArray(WEAPON_WAND, itemId) then
		return WEAPONTYPE_WAND
	elseif isInArray(WEAPON_ROD, itemId) then
		return WEAPONTYPE_ROD
	elseif isInArray(WEAPON_DISTANCE, itemId) then
		return WEAPONTYPE_DISTANCE
	else
		return FALSE
	end
end

2nd:
The *.xml part
PHP:
<npc name="the Old Pervert" script="data/npc/scripts/theoldpervert.lua" autowalk="25" floorchange="0" access="5" level="1" maglevel="1">
	<health now="150" max="150"/>
	<look type="129" head="60" body="113" legs="95" feet="115" addons="0"/>
	<parameters>
		<parameter key="message_greet" value="Hello |PLAYERNAME|. What brings you here?" />
		<parameter key="message_farewell" value="May the fish fin powah be with you."/>
		<parameter key="message_walkaway" value="How rude!"/>
		<parameter key="message_placedinqueue" value="I'm already talking with someone else, wait for your turn."/>
		<parameter key="message_idletimeout" value="Time over, peace!"/>
		<parameter key="message_alreadyfocused" value="We are already talking, |PLAYERNAME|."/>

		<parameter key="module_keywords" value="1"/>
		<parameter key="keywords" value="job;help;town;ferumbras;devon six;heal"/>
		<parameter key="keyword_reply1" value="I am the oldest citizen in this city."/>
		<parameter key="keyword_reply2" value="You want my help? Tell me what You need."/>
		<parameter key="keyword_reply3" value="There are many quests in This World. Ask citizens about it, maybe someone of them have one for You."/>
		<parameter key="keyword_reply4" value="I've read about him in one of the books. There was written that he was an evil mage, who have lost the war for earth. We are lucky, because he is dead already."/>
		<parameter key="keyword_reply5" value="He is our King! Dont You remember?!"/>
		<parameter key="keyword_reply6" value="Sorry but I can not do that."/>
	</parameters>
</npc>

3rd:
NPC *.lua part

PHP:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

-- OTServ event handling functions start
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
-- OTServ event handling functions end

function creatureSayCallback(cid, type, msg)
	-- Place all your code in here. Remember that hi, bye and all that stuff is already handled by the npcsystem, so you do not have to take care of that yourself.
	if(npcHandler.focus ~= cid) then
		return false
	end

	if msgcontains(msg, 'quest') then
	        selfSay('I need 100 fish fins. Do you have them?')
		talkState = 1
 	elseif msgcontains(msg, 'no') and talkState == 1 then
		selfSay('Go get them bastard!')
        	talkState = 0
	elseif msgcontains(msg, 'yes') and talkState == 1 then
	        if doPlayerTakeItem(cid, 5895, 100) == FALSE then
	                if isInArray({1,2,5,6}, getPlayerVocation(cid)) == TRUE then
	                selfSay('/addskill '..getCreatureName(cid)..', magic')
	                elseif isInArray({3,7}, getPlayerVocation(cid)) == TRUE then
	                selfSay('/addskill '..getCreatureName(cid)..', distance')
	                elseif isInArray({4,8}, getPlayerVocation(cid)) == TRUE then
	                        if isInArray(WEAPON_AXE, getPlayerSlotItem(cid, CONST_SLOT_LEFT).itemid) == TRUE or isInArray(WEAPON_AXE, getPlayerSlotItem(cid, CONST_SLOT_RIGHT).itemid) == TRUE then
	                        selfSay('/addskill '..getCreatureName(cid)..', axe')
	                        elseif isInArray(WEAPON_SWORD, getPlayerSlotItem(cid, CONST_SLOT_LEFT).itemid) == TRUE or isInArray(WEAPON_SWORD, getPlayerSlotItem(cid, CONST_SLOT_RIGHT).itemid) == TRUE then
	                        selfSay('/addskill '..getCreatureName(cid)..', sword')
	                        elseif isInArray(WEAPON_CLUB, getPlayerSlotItem(cid, CONST_SLOT_LEFT).itemid) == TRUE or isInArray(WEAPON_CLUB, getPlayerSlotItem(cid, CONST_SLOT_RIGHT).itemid) == TRUE then
	                        selfSay('/addskill '..getCreatureName(cid)..', club')
				else
				selfSay('/addskill '..getCreatureName(cid)..', shield')
				end
		end
		        addEvent(say, 1000, getNpcCid())
		        addEvent(shutTheFuckUp, 3000, getNpcCid())
		        doSendMagicEffect(getPlayerPosition(cid), CONST_ME_MAGIC_GREEN)
  			talkState = 0
		else
		selfSay('You do not have tasty fins liar.')
		doCreatureAddHealth(cid, - 30)
                talkState = 0
		end
 end
return 1
end

function say()
	selfSay('Thank you very much omgzors, take this as a reward.')
end

function shutTheFuckUp()
	stopEvent(say)
	stopEvent(shutTheFuckUp)
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())

How does it work?
Actually its made to take 100 fish fins and can be done infinite amount of times.
It checks if you are mage/pally/knight and then gives you skill depending on the voc.
Mage - + 1mlvl
Pally - + 1dist
Kina - Checks right and left slot for weapon type and gives the weaponType skill up
 
haha nice shutTheFuckUp lool :D

Nice script, keep it up! I myself don't like making NPCs :p:p
 
Hope you don't mind, added 2 functions to make the NPC code shorter:
PHP:
function getSkillByWeapon(cid)
    local weaponTypes, {
        {WEAPON_AXE, "axe"},
        {WEAPON_SWORD, "sword"},
        {WEAPON_CLUB, "club"}
    }
    for _, WEAPON in pairs(weaponTypes) do
        if (isInArray(WEAPON[1], getPlayerSlotItem(cid, CONST_SLOT_LEFT).itemid) == TRUE or isInArray(WEAPON[1], getPlayerSlotItem(cid, CONST_SLOT_RIGHT).itemid) == TRUE)
            return WEAPON[2]
        end
    end
    return "shield"
end

function getSkillTypeByVocation(cid)
    local skillTypes = {
        {1, 2, 5, 6} = "magic",
        {3, 7} = "distance",
        {4, 8} = getSkillByWeapon(cid)
    }
    for SKILL_VOCS, SKILL_NAME in pairs(skillTypes) do
        if (isInArray(SKILL_VOCS, getPlayerVocation(cid)) == TRUE) then
            return SKILL_NAME
        end
    end
    return 0
end

And your NPC:
PHP:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

-- OTServ event handling functions start
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
-- OTServ event handling functions end

function creatureSayCallback(cid, type, msg)
    if(npcHandler.focus ~= cid) then
        return false
    end

    if msgcontains(msg, 'quest') then
        selfSay('I need 100 fish fins. Do you have them?')
        talkState = 1
    elseif msgcontains(msg, 'no') and talkState == 1 then
        selfSay('Go get them bastard!')
        talkState = 0
    elseif msgcontains(msg, 'yes') and talkState == 1 then
        if doPlayerTakeItem(cid, 5895, 100) == FALSE then
            if (getSkillTypeByVocation(cid) ~= 0) then
                selfSay('/addskill ' .. getCreatureName(cid) .. ', ' .. getSkillTypeByVocation(cid))
            end
            addEvent(say, 1000, getNpcCid())
            addEvent(shutTheFuckUp, 3000, getNpcCid())
            doSendMagicEffect(getPlayerPosition(cid), CONST_ME_MAGIC_GREEN)
        else
            selfSay('You do not have tasty fins liar.')
            doCreatureAddHealth(cid, -30)
        end
        talkState = 0
    end
    return 1
end

function say()
    selfSay('Thank you very much omgzors, take this as a reward.')
end

function shutTheFuckUp()
    stopEvent(say)
    stopEvent(shutTheFuckUp)
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())

Would be great if you could test it :)
 
Last edited:
Nice, thanks :blink:

Added those functions to global.lua and got error saying cannot load global.lua :)
Same with lib/npc.lua :)
 
Last edited:
Didnt even searh for global.lua error, because it started to print every script error :)
 
Back
Top