• 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 [TFS 1.1] - Slot system

Status
Not open for further replies.
Nice! I'm going to test that soon.
Any chances for extra element protection/damage and attackspeed?
 
I am working on trying to figure out how to add more attributes to that function, however for element protection and damage protection there is onHealthChange function already, and I requested for exactly that on Evil Hero's repo. Idk if they are going to try to implement it or not, I am trying to figure out how to make it for creature, a function like creature:absorbPercent("fire", 10) or creature:reflectPercent("drown", 10), ect. As for attackspeed im also trying to figure out how to go about that....
 
@Codinablack
1. element protection should be done by item attributes because it won't ruin item description.
2. onHealthChange works for monsters also
registering creature event which changes received damage should work fine
3. any chances to merge that commit(item attributes) with official tfs repo?
 
Last edited:
@Codinablack
1. element protection should be done by item attributes because it won't ruin item description.
2. onHealthChange works for monsters also
registering creature event which changes received damage should work fine
3. any chances to merge that commit(item attributes) with official tfs repo?

3. @Mark will tell us :p maybe it is only tfs 1.1 milestone I guess tho :/
 
If Evil Hero's example works, I'll try to edit sources myself to add element damage, element protection, field absorb%, extra ml and skill.
 
If Evil Hero's example works, I'll try to edit sources myself to add element damage, element protection, field absorb%, extra ml and skill.

100% Confirmation his example works! I added it into my own edited version of 1.0, as long as you follow the first commit first then go through and follow the second commit. It works.

12:32 You see a rare (Atk:100, Def:100 +100).
It can only be wielded properly by players of level 25 or higher.
It weighs 59.00 oz.
ItemID: [2430].
Position: [X: 304] [Y: 605] [Z: 4].

Hey if you get it working with the elements and the rest will you please post the link to the commit(s) or share here on otland?
 
Codinablack said:
Hey if you get it working with the elements and the rest will you please post the link to the commit(s) or share here on otland?
If I get it working, I'll post link to my forked repo.
 
I checked these commits with newest tfs trunk and it looks good so far.

With Evil Hero's method every attribute from items.cpp can be passed, but these numbers in enums.h (enum itemAttrTypes) are getting very large. Is there another rule to number them than last value ^2?
 
Last edited:
I have no idea, however, it may be a good thing to just show some patience at this point. Mark did just recently announce the release of 1.0 and also updated everyone on the plans for 1.1 which is already under development, and the item attributes are in that list. You could always use latest source and create a pull request if you get it all, they are planning on adding it anyways....

Although getting it passed the basic attributes from evil hero's commit, that is gonna be more tricky...
 
I've waited one year for that. It's time for me to do something already.
I got number attributes to work. Today I'll test edited weapons in combat and try to make string attributes working. Skills and element protecion will be easy to make. I'm confused with attributes order and id only.

Edit: attribute range is visible, but doesn't work(crossbow still uses default range)
 
Last edited:
Yes I noticed that! That's awesome that it wasn't just me that was having that problem.... Which commit are you working from?
 
Did you do it exactly like evil hero's? Currently I am using clean source from latest commit for 1.1 for a test environment, I have the other version compiled and the source backed up on another pc so I can't check mine right this second... but if yours is like his and it isn't working, you should report it as a bug to his github please... if so I can check mine tomorrow and if mine is same way, maybe we can get him in on helping with this....
 
Did you do it exactly like evil hero's? Currently I am using clean source from latest commit for 1.1 for a test environment, I have the other version compiled and the source backed up on another pc so I can't check mine right this second... but if yours is like his and it isn't working, you should report it as a bug to his github please... if so I can check mine tomorrow and if mine is same way, maybe we can get him in on helping with this....

I used otland/forgottenserver sources and applied these commits manually.
I'll try to write that again later. Currently I'm working on another thing.
 
It would be awesome to have the modifiers applied to loot from monsters, not sure how hard it would be to convert.
 
I've been trying to update this to work with 1.1 but I'm failing horribly, there are no errors in the console but I've surely made one or many mistakes, any help is appreciated!

The action script is working fine, but nothing is happening to the players stats so I'm sure I've made a mistake in converting the creaturescript.

creaturescript:
Code:
local conditionMP,conditionHP,conditionML,conditionCLUB,conditionSHI,conditionDIST,conditionAMP = {},{},{},{},{},{},{}
for i=1,300 do
   conditionHP[i] = createConditionObject(CONDITION_ATTRIBUTES)
   setConditionParam(conditionHP[i], CONDITION_PARAM_SUBID, 50)
   setConditionParam(conditionHP[i], CONDITION_PARAM_BUFF_SPELL, 1)
   setConditionParam(conditionHP[i], CONDITION_PARAM_TICKS, -1)
   setConditionParam(conditionHP[i], CONDITION_PARAM_STAT_MAXHITPOINTSPERCENT, 100+i)

   conditionMP[i] = createConditionObject(CONDITION_ATTRIBUTES)
   setConditionParam(conditionMP[i], CONDITION_PARAM_SUBID, 51)
   setConditionParam(conditionMP[i], CONDITION_PARAM_BUFF_SPELL, 1)
   setConditionParam(conditionMP[i], CONDITION_PARAM_TICKS, -1)
   setConditionParam(conditionMP[i], CONDITION_PARAM_STAT_MAXMANAPOINTSPERCENT, 100+i)

   conditionML[i] = createConditionObject(CONDITION_ATTRIBUTES)
   setConditionParam(conditionML[i], CONDITION_PARAM_SUBID, 52)
   setConditionParam(conditionML[i], CONDITION_PARAM_BUFF_SPELL, 1)
   setConditionParam(conditionML[i], CONDITION_PARAM_TICKS, -1)
   setConditionParam(conditionML[i], CONDITION_PARAM_STAT_MAGICPOINTSPERCENT, 100+i)


   conditionCLUB[i] = createConditionObject(CONDITION_ATTRIBUTES)
   setConditionParam(conditionCLUB[i], CONDITION_PARAM_SUBID, 53)
   setConditionParam(conditionCLUB[i], CONDITION_PARAM_BUFF_SPELL, 1)
   setConditionParam(conditionCLUB[i], CONDITION_PARAM_TICKS, -1)
   setConditionParam(conditionCLUB[i], CONDITION_PARAM_SKILL_MELEEPERCENT, 100+i)


   conditionSHI[i] = createConditionObject(CONDITION_ATTRIBUTES)
   setConditionParam(conditionSHI[i], CONDITION_PARAM_SUBID, 54)
   setConditionParam(conditionSHI[i], CONDITION_PARAM_BUFF_SPELL, 1)
   setConditionParam(conditionSHI[i], CONDITION_PARAM_TICKS, -1)
   setConditionParam(conditionSHI[i], CONDITION_PARAM_SKILL_SHIELDPERCENT, 100+i)

   conditionDIST[i] = createConditionObject(CONDITION_ATTRIBUTES)
   setConditionParam(conditionDIST[i], CONDITION_PARAM_SUBID, 55)
   setConditionParam(conditionDIST[i], CONDITION_PARAM_BUFF_SPELL, 1)
   setConditionParam(conditionDIST[i], CONDITION_PARAM_TICKS, -1)
   setConditionParam(conditionDIST[i], CONDITION_PARAM_SKILL_DISTANCEPERCENT, 100+i)
end

function getSlotType(n)
   if not n then
     return false
   end
   if n:match('%[(.+)%]') then
     n = n:match('%[(.+)%]')
     if n == '?' then
       return 0,n
     else
       return n:match('(.-)%.([+-])(%d+)%%')
     end
   else
     return false
   end
end

local function loadSet(playerID)
local player = Player(playerID)
if not player then
return true
end
   local t = {}
   for slot=1,9 do
     t[slot] = ''
     local s = Item(player:getSlotItem(slot))
     if s then
       t[slot] = s:getName()
     end
   end
   return t
end

function chk(playerID,f)
local player = Player(playerID)
   if not player then return false end
   local t = loadSet(player)
   for i=1,#f do
     if f[i] ~= t[i] then
       equip(player.uid,nil,slot)
       break
     end
   end
   addEvent(chk,2000,player.uid,t)
end

function check_slot(aab, i)
   if i == 5 or i == 6 then
     if isWeapon(aab) or isShield(aab) or isBow(aab) then
       return true
     end
   else
     return true
   end
return false
end

function equip(playerID,item,slot)
local player = Player(playerID)
if not player then
return true
end
   local t = {}
   if item then
     local mm,sinal,qto = getSlotType(Item(item.uid):getName())
     t[mm] = tonumber(qto)
   end
   for i=1,9 do
     if i ~= slot then
       if player:getSlotItem(i) then
         local aab = Item(player:getSlotItem(i))
         if aab and check_slot(aab,i) then
           for _ in Item(aab):getName():gmatch('(%[.-%])') do
             local mm,sinal,qto2 = getSlotType(_)
             if mm then
               if not t[mm] then
                 t[mm] = 0
               end
               t[mm] = t[mm]+tonumber(qto2)
               t[mm] = t[mm] > 300 and 300 or t[mm]
             end
           end
         end
       end
     end
   end
   local fu = 0
   local ca = {}
   local s = ''
   for sl,n in pairs(t) do
     fu = fu+1
     s = s..''..n..'% more of '..sl..'\n'
     if sl == 'hp' then
       player:addCondition(conditionHP[tonumber(n)])
       ca[50] = 1
       --doSendTutorial(cid,19)
     elseif sl == 'mp' then
       player:addCondition(conditionMP[tonumber(n)])
       ca[51] = 1
      -- doSendTutorial(cid,19)
     elseif sl == 'ml' then
       player:addCondition(conditionML[tonumber(n)])
       ca[52] = 1
     elseif sl == 'melee' then
       player:addCondition(conditionCLUB[tonumber(n)])
       ca[53] = 1
     elseif sl == 'shield' then
       player:addCondition(conditionSHI[tonumber(n)])
       ca[54] = 1
     elseif sl == 'dist' then
       player:addCondition(conditionDIST[tonumber(n)])
       ca[55] = 1
     end
   end
   if fu > 0 then
     for i=50,55 do
       if not ca[i] then
         player:removeCondition(CONDITION_ATTRIBUTES,i)
       end
     end
   else
     for i=50,55 do
       player:removeCondition(CONDITION_ATTRIBUTES,i)
     end
   end
   return true
end

function onLogin(cid)
local player = Player(cid)
if not player then
return true
end
  equip(player.uid,nil,slot)
  addEvent(chk, 2000, player.uid, loadSet(player.uid))
  return true
end


action:
Code:
local conf = {
maxSlotCount=3,
ignoredIds={}
}

function choose(...)
   local arg = {...}
   return arg[math.random(1,#arg)]
end

function onUse(cid, item, fromPosition, itemEx, toPosition)
local player = Player(cid)
   if item.uid == 0 or item.itemid == 0 then return false end
   toPosition.stackpos = 255
  
    print(ItemType(itemEx.itemid):isStackable())
    print(itemEx.itemid)
    print(ItemType(itemEx.itemid):getType())
    print(isArmor(itemEx.uid))
    print(isWeapon(itemEx.uid))
    print(isShield(itemEx.uid))
   
  if isInArray(conf.ignoredIds, itemEx.itemid) or
     ItemType(itemEx.itemid):isStackable() or
     itemEx.itemid == 0 or
     ItemType(itemEx.itemid):getType() > 1 or
     not (isArmor(itemEx.uid) or isWeapon(itemEx.uid) or isShield(itemEx.uid)) then
     player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "This item can not be upgraded.")
  return false
  end
  if not Item(itemEx.uid):isItem() then
  return false
  end
   local nam = Item(itemEx.uid):getName()
   function getper()
     local n = 1
     for i=1,10 do
       n = n+math.random(0,10)
       if n < 8*i then
         break
       end
     end
     return n
   end
   function getSlotCount(nam)
     local c = 0
     for _ in nam:gmatch('%[(.-)%]') do
       c = c+1
     end
     return c
   end
   if getSlotCount(nam) < conf.maxSlotCount then
     local l = choose('ml','melee','shield','dist')
     local p = getper()
     player:getPosition():sendMagicEffect(30)
     nam = nam..' ['..l..'.+'..p..'%]'
     player:sendTextMessage(MESSAGE_INFO_DESCR,l..'.+'..p..'%')
     Item(itemEx.uid):setAttribute('name', nam)
     Item(item.uid):remove(1)
   else
     player:sendTextMessage(MESSAGE_INFO_DESCR,"Slot limit reached.")
   end
   return true
end

global.lua
Code:
  function getItemAttack(uid) return ItemType(Item(uid):getId()):getAttack() end
   function getItemDefense(uid) return ItemType(Item(uid):getId()):getDefense() end
   function getItemArmor(uid) return ItemType(Item(uid):getId()):getArmor() end
   function getItemWeaponType(uid) return ItemType(Item(uid):getId()):getWeaponType() end
   function isArmor(uid) if (getItemArmor(uid) ~= 0 and getItemWeaponType(uid) == 0) then return true else return false end end
   function isWeapon(uid) return (getItemWeaponType(uid) > 0 and getItemWeaponType(uid) ~= 4) end
   function isShield(uid) return getItemWeaponType(uid) == 4 end
   function isBow(uid) return (getItemWeaponType(uid) == 5 and (not ItemType(Item(uid):getId()):isStackable())) end
 
Status
Not open for further replies.
Back
Top