• 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 Transform multiples items without id

Banyato

New Member
Joined
Feb 5, 2021
Messages
11
Reaction score
3
Yo everyone

Im using TFS 1.3 and i am stuck on a stupid thing,
I was looking on the server something like "getItemId" like item:getId() , but maybe im lost

As action, if item target itemX then item transform(itemX)
But without item ID i wish it detects automatically the type of item is the target, of course, only equip items
I tried something weird, just idk how the script can know what item I'm targeting then transform this item to the same,

This is because i got an item it sets a custom attribute, but can't be erased, i wish to transform this item to a newer one(same Id) so it will remove this custom attribute.

Lua:
function onUse(player, item, target, fromPosition, itemEx, toPosition)
  if player then
    local item = item:getId()
    if item and target.itemid == item then
      target:transform(item.itemid, item)
    end
  end
end
 
This is because i got an item it sets a custom attribute, but can't be erased
How can attribute be settable, but not removable? What sets this attribute?
i wish to transform this item to a newer one(same Id)
Isn't item transform function to KEEP attributes? Ex. transform ring on equip/de-equip keeps 'duration left'.

To detect, if both items are same ID and call transform on target item:
Lua:
function onUse(player, item, target, fromPosition, itemEx, toPosition)
-- player is for sure set, you don't have to check it
-- Item(target) will check if target is Item (it can be monster/npc/player or item)
  if Item(target) then

    if item:getId() == target:getId() then
-- transforming to same ID does nothing! there is 'if' in engine that block any action
      target:transform(target:getId())
    end
  end
end
Code in engine that blocks any action, when you call item:transform with same ID as current item ID:
 
How can attribute be settable, but not removable? What sets this attribute?
I Forget mention , can't be erased by me, since i dont know how create the function remove.
Lua:
function onUse(player, item, target, fromPosition, itemEx, toPosition)
-- player is for sure set, you don't have to check it
-- Item(target) will check if target is Item (it can be monster/npc/player or item)
  if Item(target) then

    if item:getId() == target:getId() then
-- transforming to same ID does nothing! there is 'if' in engine that block any action
      target:transform(target:getId())
    end
  end
end
Code in engine that blocks any action, when you call item:transform with same ID as current item ID:
Yeah i try something like:
if target:isItem() then
but i think it doesn't detect and says 'getId nil value on if item:getId() == target:getId() then
I am using a book, on sword ( custom attribute added ), trying to transform it with this book again to this sword without attributes.

Emm idk who post this script i dont remember, it's here on otland and there are no credits, it is a slot system,
Using this script you can replace the last slot , but not the 2 firsts ( 3 Slots , on my case ), so maybe if you add magicLevel on first slot and Sword on second slot on a bow it's looks like bad

Lua:
local addSlotItems = { 27246 }
local slotAction = Action()
local creatureEvent = CreatureEvent()
local Attr = {}
Attr.__index = Attr
Attr.init = function(slot)
 local attr = {}
 setmetatable(attr, Attr)
 attr.name = slot.name
 attr.value = slot.value
 attr.percent = slot.percent
 return attr
end
setmetatable(Attr, {
 __call = function(_, ...) return Attr.init(...) end,
 __eq = function(a, b) return a.name == b.name and a.value == b.value and a.percent == b.percent end
})
local slotLib = {}
slotLib.maxSlots = 3 
slotLib.baseSubids = 90
slotLib.cache = {}
slotLib.attributes = {
 { name = "Club", values = { 1, 2, 3 }, percent = false },
 { name = "Sword", values = { 1, 2, 3 }, percent = false },
 { name = "Axe", values = { 1, 2, 3 }, percent = false },
 { name = "Distance", values = { 1, 2, 3 }, percent = false },
 { name = "Shield", values = { 1, 2, 3 }, percent = false },
 { name = "Fishing", values = { 1, 2, 3 }, percent = false },
 { name = "MagicLevel", values = { 1, 2, 3 }, percent = false },
 { name = "LifeLeechChance", values = { 3, 6, 9 }, percent = false },
 { name = "LifeLeechAmount", values = { 3, 6, 9 }, percent = false },
 { name = "ManaLeechChance", values = { 3, 6, 9 }, percent = false },
 { name = "ManaLeechAmount", values = { 3, 6, 9 }, percent = false },
 { name = "Speed", values = { 10, 20, 30 }, percent = false },
 { name = "HealthGain", values = { 1, 2, 3 }, percent = false },
 { name = "ManaGain", values = { 1, 2,  3}, percent = false }
}
slotLib.conditions = {
 ["Club"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_CLUB },
 ["Sword"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_SWORD },
 ["Axe"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_AXE },
 ["Distance"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_DISTANCE },
 ["Shield"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_SHIELD },
 ["Fishing"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_FISHING },
 ["MagicLevel"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_STAT_MAGICPOINTS },
 ["LifeLeechChance"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_LIFE_LEECH_CHANCE },
 ["LifeLeechAmount"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_LIFE_LEECH_AMOUNT },
 ["ManaLeechChance"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_MANA_LEECH_CHANCE },
 ["ManaLeechAmount"] = { Type = CONDITION_ATTRIBUTES, Attr = CONDITION_PARAM_SKILL_MANA_LEECH_AMOUNT },
 ["Speed"] = { Type = CONDITION_HASTE, Attr = CONDITION_PARAM_SPEED },
 ["HealthGain"] = { Type = CONDITION_REGENERATION, Attr = CONDITION_PARAM_HEALTHGAIN },
 ["ManaGain"] = { Type = CONDITION_REGENERATION, Attr = CONDITION_PARAM_MANAGAIN }
}
slotLib.addItemSlot = function(item)
 local slots = slotLib.getItemSlots(item)
 local replace = #slots >= slotLib.maxSlots
 local slot = slotLib.attributes[math.random(1, #slotLib.attributes)]
 if slot then
 local slotIndex = not replace and #slots + 1 or math.random(1, slotLib.maxSlots)
 local newvalue = slot.values[math.random(1, #slot.values)]
 local oldvalue = replace and slots[slotIndex].value or newvalue
 slots[slotIndex] = {
 name = slot.name,
 value = not slot.percent and newvalue,
 valuePercent = slot.percent and newvalue
 }
 slotLib.setItemSlots(item, slots)
 return newvalue >= oldvalue
 end
end
slotLib.getItemSlots = function(item)
 local slots = {}
 for slot in string.gmatch(Item.getDescription(item), "(%[.-%])") do
 local name = string.match(slot, "%[(%a+)%p")
     local value = tonumber(string.match(slot, "%p(%d+)%]"))
     local valuePercent = tonumber(string.match(slot, "%p(%d+)%%+%]"))
     slots[#slots + 1] = {
     name = name,
     value = value,
     valuePercent = valuePercent
     }
 end
 return slots
end
slotLib.setItemSlots = function(item, slots)
 local description = ItemType.getDescription(ItemType(Item.getId(item))).."\n" or ""
 for _, slot in pairs(slots) do
 description = string.format("%s[%s+%u%s]%s", description , slot.name, slot.value or slot.valuePercent, slot.valuePercent and "%" or "", _ == #slots and "" or "\n")
 end
 return Item.setAttribute(item, ITEM_ATTRIBUTE_DESCRIPTION, description)
end
slotLib.autoDetection = function(playerId)
 local player = Player(playerId)
 if player then
 if not slotLib.cache[playerId] then
 slotLib.cache[playerId] = {}
 end
 for slot = CONST_SLOT_HEAD, CONST_SLOT_AMMO do
 local item = player:getSlotItem(slot)
 if item then
 local slots = slotLib.getItemSlots(item)
 slotLib.onSlotEquip(player, slots, slot)
 if #slots < slotLib.maxSlots then
 for index = #slots+1, slotLib.maxSlots do
 local subid = slotLib.baseSubids + slot + (CONST_SLOT_AMMO * index)
 player:removeCondition(CONDITION_ATTRIBUTES, CONDITIONID_DEFAULT, subid, true)
 player:removeCondition(CONDITION_HASTE, CONDITIONID_DEFAULT, subid, true)
 player:removeCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, subid, true)
 end
 end
 else
 for index = 1, slotLib.maxSlots do
 local subid = slotLib.baseSubids + slot + (CONST_SLOT_AMMO * index)
 player:removeCondition(CONDITION_ATTRIBUTES, CONDITIONID_DEFAULT, subid, true)
 player:removeCondition(CONDITION_HASTE, CONDITIONID_DEFAULT, subid, true)
 player:removeCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, subid, true)
 end
 end
 end
 addEvent(slotLib.autoDetection, 100, playerId)
 else
 slotLib.cache[playerId] = nil
 end
end
slotLib.onSlotEquip = function(player, slots, slotIndex)
 for index, slot in pairs(slots) do
 local attr = Attr(slot)
 local subid = slotLib.baseSubids + slotIndex + (CONST_SLOT_AMMO * index)
 if not slotLib.cache[player.uid][subid] or slotLib.cache[player.uid][subid] ~= attr then
 if slotLib.cache[player.uid][subid] and slotLib.cache[player.uid][subid] ~= attr then
 player:removeCondition(CONDITION_ATTRIBUTES, CONDITIONID_DEFAULT, subid, true)
 player:removeCondition(CONDITION_HASTE, CONDITIONID_DEFAULT, subid, true)
 player:removeCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT, subid, true)
 end
 local info = slotLib.conditions[attr.name]
 if info then
 local condition = Condition(info.Type, CONDITIONID_DEFAULT)
 if condition then
 condition:setParameter(info.Attr, attr.value)
 condition:setParameter(CONDITION_PARAM_TICKS, -1)
 condition:setParameter(CONDITION_PARAM_SUBID, subid)
 player:addCondition(condition)
 slotLib.cache[player.uid][subid] = attr
 end
 end
 end
 end
end
slotLib.isUpgradeable = function(item)
    local it = ItemType(item.itemid)
    return it:getWeaponType() ~= WEAPON_NONE or it:getSpeed() or it:getArmor() > 0 or it:getDefense() > 0 or it:getExtraDefense() > 0 or it:getAttack() > 0
   end
function slotAction.onUse(player, item, fromPos, target, toPos, isHotkey)
 if not target or not target:isItem() then
 return player:sendCancelMessage("Sorry not possible, only work on items.")
 end
 if not slotLib.isUpgradeable(target) then
 return player:sendCancelMessage("Sorry not possible, this item cannot update slots.")
 end
 local greatz = slotLib.addItemSlot(target)
 target:getPosition():sendMagicEffect(greatz and CONST_ME_FIREWORK_RED or CONST_ME_FIREWORK_BLUE)
 player:say(greatz and "Slot Stats Added!" or "Bad Roll!")
 item:remove(1)
 return true
end
  
slotAction:id(addSlotItems[1])
slotAction:register()
function creatureEvent.onLogin(player)
 slotLib.autoDetection(player.uid)
 return true
end
creatureEvent:register()
 
I am using a book, on sword ( custom attribute added ), trying to transform it with this book again to this sword without attributes.
Double transform may work. Something like - now with list of item IDs, but it can also check, if item is equipped in 'item slot' (player slot):
Lua:
local replaceIds =
{
    [2400] = 2400,
    [1337] = 1337,
}

function onUse(player, item, target, fromPosition, itemEx, toPosition)
-- player is for sure set, you don't have to check it
-- Item(target) will check if target is Item (it can be monster/npc/player or item)
-- if it's not Item, it will return `nil` = false
  if Item(target) then
-- now we cannot check any random ID [book ID won't be Item ID], we must get list of 'replace IDs'
-- only items listed as `key` in `replaceIds` will be replaced
    if replaceIds[target:getId()] then
      print('trying to replace', target:getId(), 'using (book)', item:getId())
      local targetId = target:getId()
      target:transform(item:getId()) -- transform to book
      target:transform(targetId) -- transform back to real ID, it MAY reset stats and create 'new item'
    else
      print('NOT trying to replace', target:getId(), 'using (book)', item:getId())
    end
  end
end
You will get in server console messages trying to replace OR NOT trying to replace, if you try to replace items not listed in replaceIds
 
Double transform may work. Something like - now with list of item IDs, but it can also check, if item is equipped in 'item slot' (player slot):
Lua:
local replaceIds =
{
    [2400] = 2400,
    [1337] = 1337,
}

function onUse(player, item, target, fromPosition, itemEx, toPosition)
-- player is for sure set, you don't have to check it
-- Item(target) will check if target is Item (it can be monster/npc/player or item)
-- if it's not Item, it will return `nil` = false
  if Item(target) then
-- now we cannot check any random ID [book ID won't be Item ID], we must get list of 'replace IDs'
-- only items listed as `key` in `replaceIds` will be replaced
    if replaceIds[target:getId()] then
      print('trying to replace', target:getId(), 'using (book)', item:getId())
      local targetId = target:getId()
      target:transform(item:getId()) -- transform to book
      target:transform(targetId) -- transform back to real ID, it MAY reset stats and create 'new item'
    else
      print('NOT trying to replace', target:getId(), 'using (book)', item:getId())
    end
  end
end
You will get in server console messages trying to replace OR NOT trying to replace, if you try to replace items not listed in replaceIds
Of course now i understand better, thanks to explain !
 
Back
Top