• 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 [TFS 0.X] Script who change NPC looktype

potinho

Advanced OT User
Joined
Oct 11, 2009
Messages
1,403
Solutions
17
Reaction score
151
Location
Brazil
Hello, I would like help with a script that changes the looktype of an NPC every "x" seconds. The looktype numbers I'll set (approximately 30) and the colors don't need to change. can you help me?
 
Solution
just put it in the npc onThink function.
Lua:
function onThink()
    npcHandler:onThink()
end

Change the outfit like you would any normal character.
Lua:
local outfits = {111, 222, 333}
local outfit = getCreatureOutfit(cid)
local new_outfit = {
    lookType = ????,
    lookHead = outfit.lookHead,
    lookAddons = outfit.lookAddons,
    lookLegs = outfit.lookLegs,
    lookBody = outfit.lookBody,
    lookFeet = outfit.lookFeet
}
doSetCreatureOutfit(cid, new_outfit, -1)

Since cid doesn't exist in this context, remember to grab the npc's id
Lua:
getNpcId()

onThink in 0.4 npc's go every 500 ms, I beleive..
So keep that in mind when creating a counter.
Lua:
local counter = 0
local counterTarget = 120 -- 1 minute (60 * 2)

if...
just put it in the npc onThink function.
Lua:
function onThink()
    npcHandler:onThink()
end

Change the outfit like you would any normal character.
Lua:
local outfits = {111, 222, 333}
local outfit = getCreatureOutfit(cid)
local new_outfit = {
    lookType = ????,
    lookHead = outfit.lookHead,
    lookAddons = outfit.lookAddons,
    lookLegs = outfit.lookLegs,
    lookBody = outfit.lookBody,
    lookFeet = outfit.lookFeet
}
doSetCreatureOutfit(cid, new_outfit, -1)

Since cid doesn't exist in this context, remember to grab the npc's id
Lua:
getNpcId()

onThink in 0.4 npc's go every 500 ms, I beleive..
So keep that in mind when creating a counter.
Lua:
local counter = 0
local counterTarget = 120 -- 1 minute (60 * 2)

if counter >= counterTarget then
    -- do stuff
    counter = -1
end
counter = counter + 1

and here is what that would look like altogether.
Lua:
local outfits = {111, 222, 333}
local counter = 0
local counterTarget = 120 -- 1 minute (60 * 2)

function onThink()
    if counter >= counterTarget then
        local cid = getNpcId()
        local outfit = getCreatureOutfit(cid)
        local new_outfit = {
            lookType = outfits[math.random(#outfits)],
            lookHead = outfit.lookHead,
            lookAddons = outfit.lookAddons,
            lookLegs = outfit.lookLegs,
            lookBody = outfit.lookBody,
            lookFeet = outfit.lookFeet
        }
        doSetCreatureOutfit(cid, new_outfit, -1)
        counter = -1
    end
    counter = counter + 1
    npcHandler:onThink()
end
 
Solution
just put it in the npc onThink function.
Lua:
function onThink()
    npcHandler:onThink()
end

Change the outfit like you would any normal character.
Lua:
local outfits = {111, 222, 333}
local outfit = getCreatureOutfit(cid)
local new_outfit = {
    lookType = ????,
    lookHead = outfit.lookHead,
    lookAddons = outfit.lookAddons,
    lookLegs = outfit.lookLegs,
    lookBody = outfit.lookBody,
    lookFeet = outfit.lookFeet
}
doSetCreatureOutfit(cid, new_outfit, -1)

Since cid doesn't exist in this context, remember to grab the npc's id
Lua:
getNpcId()

onThink in 0.4 npc's go every 500 ms, I beleive..
So keep that in mind when creating a counter.
Lua:
local counter = 0
local counterTarget = 120 -- 1 minute (60 * 2)

if counter >= counterTarget then
    -- do stuff
    counter = -1
end
counter = counter + 1

and here is what that would look like altogether.
Lua:
local outfits = {111, 222, 333}
local counter = 0
local counterTarget = 120 -- 1 minute (60 * 2)

function onThink()
    if counter >= counterTarget then
        local cid = getNpcId()
        local outfit = getCreatureOutfit(cid)
        local new_outfit = {
            lookType = outfits[math.random(#outfits)],
            lookHead = outfit.lookHead,
            lookAddons = outfit.lookAddons,
            lookLegs = outfit.lookLegs,
            lookBody = outfit.lookBody,
            lookFeet = outfit.lookFeet
        }
        doSetCreatureOutfit(cid, new_outfit, -1)
        counter = -1
    end
    counter = counter + 1
    npcHandler:onThink()
end
Thank you Xikini. I just have one question: shouldn't I put in an array the looktypes I want the NPC to have? Here's the NPC script I want you to keep changing lookType:

bravetailor.lua
Lua:
    function getItemsFromList(items)
    local str = ''
    if table.maxn(items) > 0 then
        for i = 1, table.maxn(items) do
            str = str .. items[i][2] .. ' ' .. getItemNameById(items[i][1])
            if i ~= table.maxn(items) then str = str .. ', '
            end
        end
    end
    return str
end
function doRemoveItemsFromList(cid,items)
    local count = 0
    if table.maxn(items) > 0 then
        for i = 1, table.maxn(items) do
            if getPlayerItemCount(cid,items[i][1]) >= items[i][2] then
            count = count + 1 end
        end
    end
    if count == table.maxn(items) then
        for i = 1, table.maxn(items) do doPlayerRemoveItem(cid,items[i][1],items[i][2]) end
    else
        return false
    end
    return true
end   
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}
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
function creatureSayCallback(cid, type, msg)
    if(not npcHandler:isFocused(cid)) then
        return false
    end
    local talkUser,msg = NPCHANDLER_CONVbehavior == CONVERSATION_DEFAULT and 0 or cid, msg:lower()
    local craft = {
                      ["demon outfit doll"] = {reward = {{5220, 1}}, items = {{2520,1},{2495,1},{2494,1}, {2493,1}, {2557,3}, {2160,1000}}},
                      ["filled ectoplasm container"] = {reward = {{4864, 1}}, items = {{4863,1},{5364,10},{5263,20}, {5398,1}, {2557,3}, {5166,10}}},
                      ["ancient dragon scale mail"] = {reward = {{5418, 1}}, items = {{2492,5},{5201,10},{5202,20}, {4864,5}, {2557,3}, {5166,30}}},
                      ["citizen medal"] = {reward = {{5294, 1}}, items = {{2195,1},{2366,10},{2460,1}, {2557,3}, {5166,20}, {2160,10}}},
                      ["billionaire contract outfit"] = {reward = {{5295, 1}}, items = {{5263,300},{5283,200},{2557,10}, {5398,10}, {5166,100}, {2160,10000}}},
                      ["druid outfit jewel"] = {reward = {{5381, 1}}, items = {{5263,100},{2557,10}, {5415,1},{5201,20}, {5166,200}, {2160,500}}},
                      ["golden outfit medal"] = {reward = {{5217, 1}}, items = {{2471,1},{2466,1},{2470,1}, {2646,1}, {2557,6}, {2160,50000}}}
                }
    
    if isInArray({"item","craft","itens","items", "iten", "sew"}, msg) then
        local text = ""
        for i, v in pairs(craft) do
            text = text .. " {"..i.."}, "
        end
        npcHandler:say("I can make " .. text .. " which one do you want?", cid)   
        talkState[talkUser] = 1
    elseif talkState[talkUser] == 1 then
      ret = craft[msg]
        if not ret then
             npcHandler:say("I am not crafting this item, perhaps I can consider your order later.", cid) return true
        end
        npcHandler:say("Oh, " .. msg .. " is a good choice. Let me see... I need " .. getItemsFromList(ret.items) .. ", do you have it?" , cid)       
         talkState[talkUser] = 2
    elseif talkState[talkUser] == 2 and isInArray({"yes","yeah","sim","si"}, msg) then
      if not doRemoveItemsFromList(cid, ret.items) then
               talkState[talkUser] = 0
            npcHandler:say("Sorry, but you don't have the items that I need.", cid) return true
        end
    for _, i_i in ipairs(ret.reward) do
        local item, amount = i_i[1], i_i[2]
        if isItemStackable(item) or amount == 1 then
             doPlayerAddItem(cid, item, amount)
        else
            for i = 1, amount do
                 doPlayerAddItem(cid, item, 1)
            end
        end
    end
        talkState[talkUser] = 0
        doSendMagicEffect(getPlayerPosition(cid), math.random(28,30))
        npcHandler:say("Thank you very much! Here is your item as I promised.", cid) return true                   
    elseif msg == "no" then
        selfSay("Ok... Bye!! Maybe on the next.", cid)
        talkState[talkUser] = 0
        npcHandler:releaseFocus(cid)
    end
    return true
end
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
line 1 of my example is an array of outfits... xD
Sorry, just see now. So, i can test script in this way?

Lua:
  function getItemsFromList(items)
    local str = ''
    if table.maxn(items) > 0 then
        for i = 1, table.maxn(items) do
            str = str .. items[i][2] .. ' ' .. getItemNameById(items[i][1])
            if i ~= table.maxn(items) then str = str .. ', '
            end
        end
    end
    return str
end
function doRemoveItemsFromList(cid,items)
    local count = 0
    if table.maxn(items) > 0 then
        for i = 1, table.maxn(items) do
            if getPlayerItemCount(cid,items[i][1]) >= items[i][2] then
            count = count + 1 end
        end
    end
    if count == table.maxn(items) then
        for i = 1, table.maxn(items) do doPlayerRemoveItem(cid,items[i][1],items[i][2]) end
    else
        return false
    end
    return true
end 
local outfits = {111, 222, 333}
local counter = 0
local counterTarget = 120 -- 1 minute (60 * 2)
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}
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()
    if counter >= counterTarget then
        local cid = getNpcId()
        local outfit = getCreatureOutfit(cid)
        local new_outfit = {
            lookType = outfits[math.random(#outfits)],
            lookHead = outfit.lookHead,
            lookAddons = outfit.lookAddons,
            lookLegs = outfit.lookLegs,
            lookBody = outfit.lookBody,
            lookFeet = outfit.lookFeet
        }
        doSetCreatureOutfit(cid, new_outfit, -1)
        counter = -1
    end
    counter = counter + 1
    npcHandler:onThink()
end
function creatureSayCallback(cid, type, msg)
    if(not npcHandler:isFocused(cid)) then
        return false
    end
    local talkUser,msg = NPCHANDLER_CONVbehavior == CONVERSATION_DEFAULT and 0 or cid, msg:lower()
    local craft = {
                      ["demon outfit doll"] = {reward = {{5220, 1}}, items = {{2520,1},{2495,1},{2494,1}, {2493,1}, {2557,3}, {2160,1000}}},
                      ["filled ectoplasm container"] = {reward = {{4864, 1}}, items = {{4863,1},{5364,10},{5263,20}, {5398,1}, {2557,3}, {5166,10}}},
                      ["ancient dragon scale mail"] = {reward = {{5418, 1}}, items = {{2492,5},{5201,10},{5202,20}, {4864,5}, {2557,3}, {5166,30}}},
                      ["citizen medal"] = {reward = {{5294, 1}}, items = {{2195,1},{2366,10},{2460,1}, {2557,3}, {5166,20}, {2160,10}}},
                      ["billionaire contract outfit"] = {reward = {{5295, 1}}, items = {{5263,300},{5283,200},{2557,10}, {5398,10}, {5166,100}, {2160,10000}}},
                      ["druid outfit jewel"] = {reward = {{5381, 1}}, items = {{5263,100},{2557,10}, {5415,1},{5201,20}, {5166,200}, {2160,500}}},
                      ["golden outfit medal"] = {reward = {{5217, 1}}, items = {{2471,1},{2466,1},{2470,1}, {2646,1}, {2557,6}, {2160,50000}}}
                }
  
    if isInArray({"item","craft","itens","items", "iten", "sew"}, msg) then
        local text = ""
        for i, v in pairs(craft) do
            text = text .. " {"..i.."}, "
        end
        npcHandler:say("I can make " .. text .. " which one do you want?", cid) 
        talkState[talkUser] = 1
    elseif talkState[talkUser] == 1 then
      ret = craft[msg]
        if not ret then
             npcHandler:say("I am not crafting this item, perhaps I can consider your order later.", cid) return true
        end
        npcHandler:say("Oh, " .. msg .. " is a good choice. Let me see... I need " .. getItemsFromList(ret.items) .. ", do you have it?" , cid)     
         talkState[talkUser] = 2
    elseif talkState[talkUser] == 2 and isInArray({"yes","yeah","sim","si"}, msg) then
      if not doRemoveItemsFromList(cid, ret.items) then
               talkState[talkUser] = 0
            npcHandler:say("Sorry, but you don't have the items that I need.", cid) return true
        end
    for _, i_i in ipairs(ret.reward) do
        local item, amount = i_i[1], i_i[2]
        if isItemStackable(item) or amount == 1 then
             doPlayerAddItem(cid, item, amount)
        else
            for i = 1, amount do
                 doPlayerAddItem(cid, item, 1)
            end
        end
    end
        talkState[talkUser] = 0
        doSendMagicEffect(getPlayerPosition(cid), math.random(28,30))
        npcHandler:say("Thank you very much! Here is your item as I promised.", cid) return true                 
    elseif msg == "no" then
        selfSay("Ok... Bye!! Maybe on the next.", cid)
        talkState[talkUser] = 0
        npcHandler:releaseFocus(cid)
    end
    return true
end
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
Sorry, just see now. So, i can test script in this way?

Lua:
  function getItemsFromList(items)
    local str = ''
    if table.maxn(items) > 0 then
        for i = 1, table.maxn(items) do
            str = str .. items[i][2] .. ' ' .. getItemNameById(items[i][1])
            if i ~= table.maxn(items) then str = str .. ', '
            end
        end
    end
    return str
end
function doRemoveItemsFromList(cid,items)
    local count = 0
    if table.maxn(items) > 0 then
        for i = 1, table.maxn(items) do
            if getPlayerItemCount(cid,items[i][1]) >= items[i][2] then
            count = count + 1 end
        end
    end
    if count == table.maxn(items) then
        for i = 1, table.maxn(items) do doPlayerRemoveItem(cid,items[i][1],items[i][2]) end
    else
        return false
    end
    return true
end
local outfits = {111, 222, 333}
local counter = 0
local counterTarget = 120 -- 1 minute (60 * 2)
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}
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()
    if counter >= counterTarget then
        local cid = getNpcId()
        local outfit = getCreatureOutfit(cid)
        local new_outfit = {
            lookType = outfits[math.random(#outfits)],
            lookHead = outfit.lookHead,
            lookAddons = outfit.lookAddons,
            lookLegs = outfit.lookLegs,
            lookBody = outfit.lookBody,
            lookFeet = outfit.lookFeet
        }
        doSetCreatureOutfit(cid, new_outfit, -1)
        counter = -1
    end
    counter = counter + 1
    npcHandler:onThink()
end
function creatureSayCallback(cid, type, msg)
    if(not npcHandler:isFocused(cid)) then
        return false
    end
    local talkUser,msg = NPCHANDLER_CONVbehavior == CONVERSATION_DEFAULT and 0 or cid, msg:lower()
    local craft = {
                      ["demon outfit doll"] = {reward = {{5220, 1}}, items = {{2520,1},{2495,1},{2494,1}, {2493,1}, {2557,3}, {2160,1000}}},
                      ["filled ectoplasm container"] = {reward = {{4864, 1}}, items = {{4863,1},{5364,10},{5263,20}, {5398,1}, {2557,3}, {5166,10}}},
                      ["ancient dragon scale mail"] = {reward = {{5418, 1}}, items = {{2492,5},{5201,10},{5202,20}, {4864,5}, {2557,3}, {5166,30}}},
                      ["citizen medal"] = {reward = {{5294, 1}}, items = {{2195,1},{2366,10},{2460,1}, {2557,3}, {5166,20}, {2160,10}}},
                      ["billionaire contract outfit"] = {reward = {{5295, 1}}, items = {{5263,300},{5283,200},{2557,10}, {5398,10}, {5166,100}, {2160,10000}}},
                      ["druid outfit jewel"] = {reward = {{5381, 1}}, items = {{5263,100},{2557,10}, {5415,1},{5201,20}, {5166,200}, {2160,500}}},
                      ["golden outfit medal"] = {reward = {{5217, 1}}, items = {{2471,1},{2466,1},{2470,1}, {2646,1}, {2557,6}, {2160,50000}}}
                }
 
    if isInArray({"item","craft","itens","items", "iten", "sew"}, msg) then
        local text = ""
        for i, v in pairs(craft) do
            text = text .. " {"..i.."}, "
        end
        npcHandler:say("I can make " .. text .. " which one do you want?", cid)
        talkState[talkUser] = 1
    elseif talkState[talkUser] == 1 then
      ret = craft[msg]
        if not ret then
             npcHandler:say("I am not crafting this item, perhaps I can consider your order later.", cid) return true
        end
        npcHandler:say("Oh, " .. msg .. " is a good choice. Let me see... I need " .. getItemsFromList(ret.items) .. ", do you have it?" , cid)    
         talkState[talkUser] = 2
    elseif talkState[talkUser] == 2 and isInArray({"yes","yeah","sim","si"}, msg) then
      if not doRemoveItemsFromList(cid, ret.items) then
               talkState[talkUser] = 0
            npcHandler:say("Sorry, but you don't have the items that I need.", cid) return true
        end
    for _, i_i in ipairs(ret.reward) do
        local item, amount = i_i[1], i_i[2]
        if isItemStackable(item) or amount == 1 then
             doPlayerAddItem(cid, item, amount)
        else
            for i = 1, amount do
                 doPlayerAddItem(cid, item, 1)
            end
        end
    end
        talkState[talkUser] = 0
        doSendMagicEffect(getPlayerPosition(cid), math.random(28,30))
        npcHandler:say("Thank you very much! Here is your item as I promised.", cid) return true                
    elseif msg == "no" then
        selfSay("Ok... Bye!! Maybe on the next.", cid)
        talkState[talkUser] = 0
        npcHandler:releaseFocus(cid)
    end
    return true
end
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
Yes, as long as you put actual outfit id's instead of 111, 222, 333
 
just put it in the npc onThink function.
Lua:
function onThink()
    npcHandler:onThink()
end

Change the outfit like you would any normal character.
Lua:
local outfits = {111, 222, 333}
local outfit = getCreatureOutfit(cid)
local new_outfit = {
    lookType = ????,
    lookHead = outfit.lookHead,
    lookAddons = outfit.lookAddons,
    lookLegs = outfit.lookLegs,
    lookBody = outfit.lookBody,
    lookFeet = outfit.lookFeet
}
doSetCreatureOutfit(cid, new_outfit, -1)

Since cid doesn't exist in this context, remember to grab the npc's id
Lua:
getNpcId()

onThink in 0.4 npc's go every 500 ms, I beleive..
So keep that in mind when creating a counter.
Lua:
local counter = 0
local counterTarget = 120 -- 1 minute (60 * 2)

if counter >= counterTarget then
    -- do stuff
    counter = -1
end
counter = counter + 1

and here is what that would look like altogether.
Lua:
local outfits = {111, 222, 333}
local counter = 0
local counterTarget = 120 -- 1 minute (60 * 2)

function onThink()
    if counter >= counterTarget then
        local cid = getNpcId()
        local outfit = getCreatureOutfit(cid)
        local new_outfit = {
            lookType = outfits[math.random(#outfits)],
            lookHead = outfit.lookHead,
            lookAddons = outfit.lookAddons,
            lookLegs = outfit.lookLegs,
            lookBody = outfit.lookBody,
            lookFeet = outfit.lookFeet
        }
        doSetCreatureOutfit(cid, new_outfit, -1)
        counter = -1
    end
    counter = counter + 1
    npcHandler:onThink()
end
Works perfectly, thanks again Xiki!
Post automatically merged:

@Xikini One last question: should I worry about performance problems on the server if I put the NPC to change Outfit every 10 seconds?
 
Last edited:
One last question: should I worry about performance problems on the server if I put the NPC to change Outfit every 10 seconds?
A simple counter, and a single function..
No, it won't impact the server's performance
 
Back
Top