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

Action Alive Skinning - Simple TFS 1.2 Script

Oneda

Aspiring Spriter
Joined
Dec 3, 2013
Messages
159
Solutions
2
Reaction score
104
Location
Brazil
Hey guys! I've been developing my lua skills and I just finished a script which allows you to use your obsidian knife on alive creatures (which you can config. which creatures you would like to be skinnable when alive)

This version is still pretty simple, but could be used as a base for something more complex, I plan on adding the function of different creatures giving different products when skinned.

Lua:
local wool = {"Sheep", "Black Sheep"} -- Creatures configuration for the first table which gives wool when skinned
local leather = {"Deer", "Bear", "Rat"} -- Creatures configuration for the second table which gives minotaur leather when skinned (Should probably rename the item to leather by the way)
local dleather = {"Dragon", "Wyvern"} -- Creatures configuration for the third table which gives green dragon leather when skinned (Could also change this to green leather or something)

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if isCreature(target) and isInArray(wool, getCreatureName(target)) then
        local tPos = getCreaturePosition(target)
        doSendMagicEffect(tPos, 1) -- The magic effect that will be shown @ target's position when skinned.
        player:addItem(11236, 3) -- Item which will be added when the mobs at "creature" table are skinned and its amount.
        doCreatureAddHealth(target, -10)
    elseif isCreature(target) and isInArray(leather, getCreatureName(target)) then
        local tPos = getCreaturePosition(target)
        doSendMagicEffect(tPos, 1) -- The magic effect that will be shown @ target's position when skinned.
        player:addItem(5878, 3) -- Item which will be added when the mobs at "creature" table are skinned and its amount.
        doCreatureAddHealth(target, -10)
    elseif isCreature(target) and isInArray(dleather, getCreatureName(target)) then
        local tPos = getCreaturePosition(target)
        doSendMagicEffect(tPos, 1) -- The magic effect that will be shown @ target's position when skinned.
        player:addItem(5877, 3) -- Item which will be added when the mobs at "creature" table are skinned and its amount.
        doCreatureAddHealth(target, -10)
    elseif isCreature(target) == false then
        player:sendTextMessage(MESSAGE_STATUS_WARNING, "You can only skin creatures.") -- The error message it will give if the player is trying to skin something that isn't a creature.
    else
        player:sendTextMessage(MESSAGE_STATUS_WARNING, "You cannot skin this creature.") -- The error message it will give if t he player is trying to skin a creature which isn't added in the configuration above.
    return true
    end
end
 
Last edited by a moderator:
PS: I actually forgot to remove something from the script, and as I can't edit the topic, I'll just tell you guys what to do here:

1- Remove every "local tPos = getCreaturePosition(target)" from the script.
2- add "local tPos = getCreaturePosition(target)" just under local dleather....
 
I'm no expert but you could probably change it to something like this...
Not even sure if ti works but I'm trying to learn also :)
[lua]
local skiningConfig = {
wool = {
monster = {"Sheep", "Black Sheep"},
reward = 11236,
damage = -10
},
leather = {
monster = {"Deer", "Bear", "Rat"},
reward = 11236,
damage = -10
},
dleather = {
monster = {"Dragon", "Wyvern"},
reward = 11236,
damage = -10
}
}

local test = skiningConfig.monster(target)
if not test then
return true
end
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
if isCreature(target) and isInArray(test, getCreatureName(target)) then
local tPos = getCreaturePosition(target)
doSendMagicEffect(tPos, 1) -- The magic effect that will be shown @ target's position when skinned.
player:addItem(test.skiningConfig.reward, 3) -- Item which will be added when the mobs at "creature" table are skinned and its amount.
doCreatureAddHealth(target, test.skiningConfig.damage)
elseif isCreature(target) == false then
player:sendTextMessage(MESSAGE_STATUS_WARNING, "You can only skin creatures.") -- The error message it will give if the player is trying to skin something that isn't a creature.
else
player:sendTextMessage(MESSAGE_STATUS_WARNING, "You cannot skin this creature.") -- The error message it will give if t he player is trying to skin a creature which isn't added in the configuration above.
return true
end
end

[/lua]
 
Nice, but please stop using old deprecated functions.
isCreature(target) = target:isCreature

doSendMagicEffect = position:sendMagicEffect(effect)

doCreatureAddHealth = creature:addHealth() (target:addHealth() here)
 
I'm no expert but you could probably change it to something like this...
Not even sure if ti works but I'm trying to learn also :)
Yeah! It probably would, I just started studying tables and other things @Codex's tutorial, thanks for the tip by the way!


Nice, but please stop using old deprecated functions.
isCreature(target) = target:isCreature

doSendMagicEffect = position:sendMagicEffect(effect)

doCreatureAddHealth = creature:addHealth() (target:addHealth() here)
Right? Just didnt realized there were new functions for those, kinda getting into TFS 1.2 for basically the first time, thanks for the tip!
 
Better version of the same script posted above, following both tips.

Lua:
local mEffect = 1
local creatures = {pack1 = {"Sheep", "Black Sheep"}, pack2 = {"Deer", "Bear", "Rat"}, pack3 = {"Dragon", "Wyvern"}}
local rewards = {pack1 = 11236, pack2 = 5878, pack3 = 5877}
local amounts = {pack1 = 5, pack2 = 2, pack3 = 1}
local damages = {pack1 = -5, pack2 = -15, pack3 = -50}

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if target:isCreature(target) and isInArray(creatures.pack1, getCreatureName(target)) then
        toPosition:sendMagicEffect(mEffect)
        player:addItem(rewards.pack1, amounts.pack1)
        target:addHealth(damages.pack1)
    elseif isCreature(target) and isInArray(creatures.pack2, getCreatureName(target)) then
        toPosition:sendMagicEffect(mEffect)
        player:addItem(rewards.pack2, amounts.pack2)
        target:addHealth(damages.pack2)
    elseif isCreature(target) and isInArray(creatures.pack3, getCreatureName(target)) then
        toPosition:sendMagicEffect(mEffect)
        player:addItem(rewards.pack3, amounts.pack3)
        target:addHealth(damages.pack3)
    elseif target:isCreature(target) == false then
        player:sendTextMessage(MESSAGE_STATUS_WARNING, "You can only skin creatures.") -- The error message it will give if the player is trying to skin something that isn't a creature.
    else player:sendTextMessage(MESSAGE_STATUS_WARNING, "You cannot skin this creature.") -- The error message it will give if t he player is trying to skin a creature which isn't added in the configuration above.
        return true
    end
end
 
Lua:
local effect = 1 -- Default effect for all groups
local skinning =
{
    -- Group 1
    [1] =
    {
        creatures = { "Sheep", "Black Sheep" },
        reward    = { itemid = 11236, count = 5 },
        damage    = -5,
        effect    = effect
    },

    -- Group 2
    [2] =
    {
        creatures = { "Deer", "Beat", "Rat" },
        reward    = { itemid = 5878, count = 2 },
        damage    = -15,
        effect    = effect
    },

    -- Group 3
    [3] =
    {
        -- The commented parts here means what is optional
        creatures = { "Dragon", "Wyvern" },
        reward    = { itemid = 5877 --[[, count = 1]] },
        --damage    = -50,
        --effect    = effect
    }
}

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if not target:isCreature() then
        player:sendTextMessage(MESSAGE_STATUS_WARNING, "You can only skin creatures.")
        return false -- Cancel the item usage
    end

    local foundGroupId -- (nil, but local var, instead global)
    -- If not found, foundGroupId will keep the initial nil value
    for groupId, groupData in ipairs(skinning) do -- ipairs because we want it progressive beggining from key 1 to more
        for _, creatureName in pairs(groupData.creatures) do -- pairs because we don't need a progressive loop (it could check Dragon before Wyvern or Wyvern before Dragon)
            if creatureName == target:getName() then -- Yay, we found the creature!
                -- Now we need to save the group id on foundGroupId
                foundGroupId = groupId
                -- We have the group id, so we don't want to continue the looping, let's break
                break
            end
        end

        -- Here, we don't know if we found a group id yet, but if that is the case, we don't want to continue the looping, so let's break
        if foundGroupId then -- This is the same as foundGroupId ~= nil. This is true, because now foundGroupId is a number (we found the group id, remember?).
            break
        end
    end

    -- If all the search finished and we didn't found the group id, this means you cannot skin on that creature
    if not foundGroupId then
        player:sendTextMessage(MESSAGE_STATUS_WARNING, "You cannot skin this creature.")
        return false -- Cancel the item usage
    end

    -- As having the group id, we can get it's data
    local group = skinning[foundGroupId]

    toPosition:sendMagicEffect(group.effect or effect) -- Group effect of default effect (making effect an optional param)
    player:addItem(group.reward.itemid, group.reward.count or 1) -- Group item id, Group item count or 1 (making count an optional param)
    target:addHealth(group.damage or 0) -- Group damage or 0 (making damage an optional param)
    return true
end

Note: I did NOT test it.
 
Lua:
local effect = 1 -- Default effect for all groups
local skinning =
{
    -- Group 1
    [1] =
    {
        creatures = { "Sheep", "Black Sheep" },
        reward    = { itemid = 11236, count = 5 },
        damage    = -5,
        effect    = effect
    },

    -- Group 2
    [2] =
    {
        creatures = { "Deer", "Beat", "Rat" },
        reward    = { itemid = 5878, count = 2 },
        damage    = -15,
        effect    = effect
    },

    -- Group 3
    [3] =
    {
        -- The commented parts here means what is optional
        creatures = { "Dragon", "Wyvern" },
        reward    = { itemid = 5877 --[[, count = 1]] },
        --damage    = -50,
        --effect    = effect
    }
}

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if not target:isCreature() then
        player:sendTextMessage(MESSAGE_STATUS_WARNING, "You can only skin creatures.")
        return false -- Cancel the item usage
    end

    local foundGroupId -- (nil, but local var, instead global)
    -- If not found, foundGroupId will keep the initial nil value
    for groupId, groupData in ipairs(skinning) do -- ipairs because we want it progressive beggining from key 1 to more
        for _, creatureName in pairs(groupData.creatures) do -- pairs because we don't need a progressive loop (it could check Dragon before Wyvern or Wyvern before Dragon)
            if creatureName == target:getName() then -- Yay, we found the creature!
                -- Now we need to save the group id on foundGroupId
                foundGroupId = groupId
                -- We have the group id, so we don't want to continue the looping, let's break
                break
            end
        end

        -- Here, we don't know if we found a group id yet, but if that is the case, we don't want to continue the looping, so let's break
        if foundGroupId then -- This is the same as foundGroupId ~= nil. This is true, because now foundGroupId is a number (we found the group id, remember?).
            break
        end
    end

    -- If all the search finished and we didn't found the group id, this means you cannot skin on that creature
    if not foundGroupId then
        player:sendTextMessage(MESSAGE_STATUS_WARNING, "You cannot skin this creature.")
        return false -- Cancel the item usage
    end

    -- As having the group id, we can get it's data
    local group = skinning[foundGroupId]

    toPosition:sendMagicEffect(group.effect or effect) -- Group effect of default effect (making effect an optional param)
    player:addItem(group.reward.itemid, group.reward.count or 1) -- Group item id, Group item count or 1 (making count an optional param)
    target:addHealth(group.damage or 0) -- Group damage or 0 (making damage an optional param)
    return true
end

Note: I did NOT test it.

Those two loops are very excessive, why not use isInArray()? Code bloat is never a good thing.
Lua:
local effect = 1 -- Default effect for all groups
local skinning =
{
    -- Group 1
    [1] =
    {
        creatures = { "Sheep", "Black Sheep" },
        reward    = { itemid = 11236, count = 5 },
        damage    = -5,
        effect    = effect
    },

    -- Group 2
    [2] =
    {
        creatures = { "Deer", "Beat", "Rat" },
        reward    = { itemid = 5878, count = 2 },
        damage    = -15,
        effect    = effect
    },

    -- Group 3
    [3] =
    {
        -- The commented parts here means what is optional
        creatures = { "Dragon", "Wyvern" },
        reward    = { itemid = 5877 --[[, count = 1]] },
        --damage    = -50,
        --effect    = effect
    }
}

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if not target:isCreature() then
        player:sendTextMessage(MESSAGE_STATUS_WARNING, "You can only skin creatures.")
        return false -- Cancel the item usage
    end

    local foundGroupId -- (nil, but local var, instead global)
    -- If not found, foundGroupId will keep the initial nil value
    for groupId, groupData in ipairs(skinning) do -- ipairs because we want it progressive beggining from key 1 to more
        for _, creatureName in pairs(groupData.creatures) do -- pairs because we don't need a progressive loop (it could check Dragon before Wyvern or Wyvern before Dragon)
            if creatureName == target:getName() then -- Yay, we found the creature!
                -- Now we need to save the group id on foundGroupId
                foundGroupId = groupId
                -- We have the group id, so we don't want to continue the looping, let's break
                break
            end
        end

        -- Here, we don't know if we found a group id yet, but if that is the case, we don't want to continue the looping, so let's break
        if foundGroupId then -- This is the same as foundGroupId ~= nil. This is true, because now foundGroupId is a number (we found the group id, remember?).
            break
        end
    end

    -- If all the search finished and we didn't found the group id, this means you cannot skin on that creature
    if not foundGroupId then
        player:sendTextMessage(MESSAGE_STATUS_WARNING, "You cannot skin this creature.")
        return false -- Cancel the item usage
    end

    -- As having the group id, we can get it's data
    local group = skinning[foundGroupId]

    toPosition:sendMagicEffect(group.effect or effect) -- Group effect of default effect (making effect an optional param)
    player:addItem(group.reward.itemid, group.reward.count or 1) -- Group item id, Group item count or 1 (making count an optional param)
    target:addHealth(group.damage or 0) -- Group damage or 0 (making damage an optional param)
    return true
end

Note: I did NOT test it.

Why not use table.contains(table, value) instead of looping it all?
 
My message up, the first part should have been removed as I looked into that and table.contains() is much more inline with TFS 1.x code style.
 
My message up, the first part should have been removed as I looked into that and table.contains() is much more inline with TFS 1.x code style.

There is no more table.contains(table, value) on TFS 1.2+ anymore, I think it were removed because they now use isInArray.
Also, both, table.contains and isInArray, loop all the table. So there is no really difference between looping or checking with isInArray.
I did that thinking in the possibility of people don't have these functions, also for learn how to loop, etc.
But you are right about that, we should follow the TFS code environment.

So, I fixed that with isInArray and some comments:

Lua:
local effect = 1 -- Default effect for all groups
local skinning =
{
    -- Group 1
    [1] =
    {
        creatures = { "Sheep", "Black Sheep" },
        reward    = { itemid = 11236, count = 5 },
        damage    = -5,
        effect    = effect
    },

    -- Group 2
    [2] =
    {
        creatures = { "Deer", "Beat", "Rat" },
        reward    = { itemid = 5878, count = 2 },
        damage    = -15,
        effect    = effect
    },

    -- Group 3
    [3] =
    {
        -- The commented parts here means what is optional
        creatures = { "Dragon", "Wyvern" },
        reward    = { itemid = 5877 --[[, count = 1]] },
        --damage    = -50,
        --effect    = effect
    }
}

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if not target:isCreature() then
        player:sendTextMessage(MESSAGE_STATUS_WARNING, "You can only skin creatures.")
        return false -- Cancel the item usage. So, if this item has other scripts to load, they will [B]NOT[/B] be loaded anymore.
    end

    local foundGroupId -- (nil, but local var, instead global)

    -- If not found, foundGroupId will keep the initial nil value
    for groupId, groupData in ipairs(skinning) do -- ipairs because we want it progressive beggining from key 1 to more
        if isInArray(groupData.creatures, target:getName()) then -- Yay, we found the creature!
            -- Now we need to save the group id on foundGroupId
            foundGroupId = groupId
            -- We have the group id, so we don't want to continue the looping, let's break
            break
        end

        -- Here, we don't know if we found a group id yet, but if that is the case, we don't want to continue the looping, so let's break
        if foundGroupId then -- This is the same as foundGroupId ~= nil. This is true, because now foundGroupId is a number (we found the group id, remember?).
            break
        end
    end

    -- If all the search finished and we didn't found the group id, this means you cannot skin on that creature
    if not foundGroupId then
        player:sendTextMessage(MESSAGE_STATUS_WARNING, "You cannot skin this creature.")
        return false -- Cancel the item usage. So, if this item has other scripts to load, they will [B]NOT[/B] be loaded anymore.
    end

    -- As having the group id, we can get it's data
    local group = skinning[foundGroupId]

    toPosition:sendMagicEffect(group.effect or effect) -- Group effect of default effect (making effect an optional param)
    player:addItem(group.reward.itemid, group.reward.count or 1) -- Group item id, Group item count or 1 (making count an optional param)
    target:addHealth(group.damage or 0) -- Group damage or 0 (making damage an optional param)
    return true -- Let the item usage works. So, if this item has other scripts to load, they will still load.
end

I tried to explain each line for you guys study this better.
Good luck.
 
Back
Top