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

Solved Making a script more compact.

  • Thread starter Thread starter Xikini
  • Start date Start date
X

Xikini

Guest
TFS 0.3.7

Generally the script below was asked to be created in private.
It's not a very hard script by any means, however I was wondering if anyone has an idea to make the script shorter / more compact.
It's pretty much the same stuff over and over.. but checking and accessing the table slightly differently each time.
If a server has 16 vocations, this would become a knightmare. (oh yes. I did.)

Script checks for item being used, (in this case a statue), If you are the correct vocation, it will 'convert' 1 item into another.
Nice and simple.. yet I feel it's way too long for such a simple script.
Is there a way to shorten it?

Cheers,

Xikini
Code:
local config = {
   sorcerer =   { itemRequired = 1111, itemRequiredAmount = 1, itemGiven = 1111, itemGivenAmount = 1, statueID = 8834},
   druid =      { itemRequired = 1111, itemRequiredAmount = 1, itemGiven = 1111, itemGivenAmount = 1, statueID = 8422},
   knight =     { itemRequired = 1111, itemRequiredAmount = 1, itemGiven = 1111, itemGivenAmount = 1, statueID = 8836},
   paladin =    { itemRequired = 1111, itemRequiredAmount = 1, itemGiven = 1111, itemGivenAmount = 1, statueID = 3739}
}

function onUse(cid, item, fromPosition, itemEx, toPosition)
   -- Sorcerers
   if item.itemid == config.sorcerer.statueID then
     if getPlayerVocationName(cid):lower() == "sorcerer" or getPlayerVocationName(cid):lower() == "master sorcerer" then
       if getPlayerItemCount(cid, config.sorcerer.itemRequired) >= config.sorcerer.itemRequiredAmount then
         doPlayerRemoveItem(cid, config.sorcerer.itemRequired, config.sorcerer.itemRequiredAmount)
         doPlayerAddItem(cid, config.sorcerer.itemGiven, config.sorcerer.itemGivenAmount, true)
         doCreatureSay(cid, "Removed ".. config.sorcerer.itemRequiredAmount .." ".. getItemNameById(config.sorcerer.itemRequired) ..". You received ".. config.sorcerer.itemGivenAmount .." ".. getItemNameById(config.sorcerer.itemGiven) ..".", TALKTYPE_ORANGE_1)
       else
         return doPlayerSendCancel(cid, "You require ".. config.sorcerer.itemRequiredAmount .." ".. getItemNameById(config.sorcerer.itemRequired) .." to receive ".. config.sorcerer.itemGivenAmount .." ".. getItemNameById(config.sorcerer.itemGiven) ..".")
       end
     else
       return doPlayerSendCancel(cid, "Only sorcerers may use this statue.")
     end
   -- Druids
   elseif item.itemid == config.druid.statueID then
     if getPlayerVocationName(cid):lower() == "druid" or getPlayerVocationName(cid):lower() == "elder druid" then
       if getPlayerItemCount(cid, config.druid.itemRequired) >= config.druid.itemRequiredAmount then
         doPlayerRemoveItem(cid, config.druid.itemRequired, config.druid.itemRequiredAmount)
         doPlayerAddItem(cid, config.druid.itemGiven, config.druid.itemGivenAmount, true)
         doCreatureSay(cid, "Removed ".. config.druid.itemRequiredAmount .." ".. getItemNameById(config.druid.itemRequired) ..". You received ".. config.druid.itemGivenAmount .." ".. getItemNameById(config.druid.itemGiven) ..".", TALKTYPE_ORANGE_1)
       else
         return doPlayerSendCancel(cid, "You require ".. config.druid.itemRequiredAmount .." ".. getItemNameById(config.druid.itemRequired) .." to receive ".. config.druid.itemGivenAmount .." ".. getItemNameById(config.druid.itemGiven) ..".")
       end
     else
       return doPlayerSendCancel(cid, "Only druids may use this statue.")
     end
   -- Knights
   elseif item.itemid == config.knight.statueID then
     if getPlayerVocationName(cid):lower() == "knight" or getPlayerVocationName(cid):lower() == "elite knight" then
       if getPlayerItemCount(cid, config.knight.itemRequired) >= config.knight.itemRequiredAmount then
         doPlayerRemoveItem(cid, config.knight.itemRequired, config.knight.itemRequiredAmount)
         doPlayerAddItem(cid, config.knight.itemGiven, config.knight.itemGivenAmount, true)
         doCreatureSay(cid, "Removed ".. config.knight.itemRequiredAmount .." ".. getItemNameById(config.knight.itemRequired) ..". You received ".. config.knight.itemGivenAmount .." ".. getItemNameById(config.knight.itemGiven) ..".", TALKTYPE_ORANGE_1)
       else
         return doPlayerSendCancel(cid, "You require ".. config.knight.itemRequiredAmount .." ".. getItemNameById(config.knight.itemRequired) .." to receive ".. config.knight.itemGivenAmount .." ".. getItemNameById(config.knight.itemGiven) ..".")
       end
     else
       return doPlayerSendCancel(cid, "Only knights may use this statue.")
     end
   -- Paladins
   elseif item.itemid == config.paladin.statueID then
     if getPlayerVocationName(cid):lower() == "paladin" or getPlayerVocationName(cid):lower() == "royal paladin" then
       if getPlayerItemCount(cid, config.paladin.itemRequired) >= config.paladin.itemRequiredAmount then
         doPlayerRemoveItem(cid, config.paladin.itemRequired, config.paladin.itemRequiredAmount)
         doPlayerAddItem(cid, config.paladin.itemGiven, config.paladin.itemGivenAmount, true)
         doCreatureSay(cid, "Removed ".. config.paladin.itemRequiredAmount .." ".. getItemNameById(config.paladin.itemRequired) ..". You received ".. config.paladin.itemGivenAmount .." ".. getItemNameById(config.paladin.itemGiven) ..".", TALKTYPE_ORANGE_1)
       else
         return doPlayerSendCancel(cid, "You require ".. config.paladin.itemRequiredAmount .." ".. getItemNameById(config.paladin.itemRequired) .." to receive ".. config.paladin.itemGivenAmount .." ".. getItemNameById(config.paladin.itemGiven) ..".")
       end
     else
       return doPlayerSendCancel(cid, "Only paladins may use this statue.")
     end
   else
     return doPlayerSendCancel(cid, "ERROR: itemID used is incorrect. Contact Administration that script is not functioning as intended.")
     -- If you receive this error then the itemID is incorrect. Check the statues being used.
   end
   return true
end
 
Last edited by a moderator:
There ya go nice and small :)
Code:
local config = {
    [1] = { itemRequired = 1111, itemRequiredAmount = 1, itemGiven = 1111, itemGivenAmount = 1, statueID = 8834, nopromo = "sorcerer", promo = "master sorcerer"},
    [2] = { itemRequired = 1111, itemRequiredAmount = 1, itemGiven = 1111, itemGivenAmount = 1, statueID = 8422, nopromo = "druid", promo = "elder druid"},
    [3] = { itemRequired = 1111, itemRequiredAmount = 1, itemGiven = 1111, itemGivenAmount = 1, statueID = 8836, nopromo = "paladin", promo = "royal paladin"},
    [4] = { itemRequired = 1111, itemRequiredAmount = 1, itemGiven = 1111, itemGivenAmount = 1, statueID = 3739, nopromo = "knight", promo = "elite knight"}
}

function onUse(cid, item, fromPosition, itemEx, toPosition)
    local vocType = getPlayerVocationName(cid):lower()
    for vocation, data in ipairs(config) do
        if (vocType == config[vocation].nopromo or vocType == config[vocation].promo) and item.itemid == config[vocation].statueID then
            if getPlayerItemCount(cid, config[vocation].itemRequired) >= config[vocation].itemRequiredAmount then
                doPlayerRemoveItem(cid, config[vocation].itemRequired, config[vocation].itemRequiredAmount)
                doPlayerAddItem(cid, config[vocation].itemGiven, config[vocation].itemGivenAmount, true)
                doCreatureSay(cid, "Removed ".. config[vocation].itemRequiredAmount .." ".. getItemNameById(config[vocation].itemRequired) ..". You received ".. config[vocation].itemGivenAmount .." ".. getItemNameById(config[vocation].itemGiven) ..".", TALKTYPE_ORANGE_1)
            else
                return doPlayerSendCancel(cid, "You require ".. config[vocation].itemRequiredAmount .." ".. getItemNameById(config[vocation].itemRequired) .." to receive ".. config[vocation].itemGivenAmount .." ".. getItemNameById(config[vocation].itemGiven) ..".")
            end
        else
            return doPlayerSendCancel(cid, "Only "..(config[vocation].nopromo).." may use this statue.")
        end
    end
    return true
end
 
Last edited:
There ya go nice and small :)
Code:
local config = {
    [1] = { itemRequired = 1111, itemRequiredAmount = 1, itemGiven = 1111, itemGivenAmount = 1, statueID = 8834, nopromo = "sorcerer", promo = "master sorcerer"},
    [2] = { itemRequired = 1111, itemRequiredAmount = 1, itemGiven = 1111, itemGivenAmount = 1, statueID = 8422, nopromo = "druid", promo = "elder druid"},
    [3] = { itemRequired = 1111, itemRequiredAmount = 1, itemGiven = 1111, itemGivenAmount = 1, statueID = 8836, nopromo = "paladin", promo = "royal paladin"},
    [4] = { itemRequired = 1111, itemRequiredAmount = 1, itemGiven = 1111, itemGivenAmount = 1, statueID = 3739, nopromo = "knight", promo = "elite knight"}
}

function onUse(cid, item, fromPosition, itemEx, toPosition)
    local vocType = getPlayerVocationName(cid):lower()
    for vocation, data in ipairs(config) do
        if (vocType == config[vocation].nopromo or vocType == config[vocation].promo) and item.itemid == config[vocation].statueID then
            if getPlayerItemCount(cid, config[vocation].itemRequired) >= config[vocation].itemRequiredAmount then
                doPlayerRemoveItem(cid, config[vocation].itemRequired, config[vocation].itemRequiredAmount)
                doPlayerAddItem(cid, config[vocation].itemGiven, config[vocation].itemGivenAmount, true)
                doCreatureSay(cid, "Removed ".. config[vocation].itemRequiredAmount .." ".. getItemNameById(config[vocation].itemRequired) ..". You received ".. config[vocation].itemGivenAmount .." ".. getItemNameById(config[vocation].itemGiven) ..".", TALKTYPE_ORANGE_1)
            else
                return doPlayerSendCancel(cid, "You require ".. config[vocation].itemRequiredAmount .." ".. getItemNameById(config[vocation].itemRequired) .." to receive ".. config[vocation].itemGivenAmount .." ".. getItemNameById(config[vocation].itemGiven) ..".")
            end
        else
            return doPlayerSendCancel(cid, "Only "..(config[vocation].nopromo).." may use this statue.")
        end
    end
    return true
end
My initial thoughts after looking through the code, makes me think it's not going to work. :(
It looks like if the player is the wrong vocation, it will return on the first loop, and not continue, no matter if the item used is correct or not.
This is the crux of my problem as well. How do you check if the item being used, is correct for that vocation, and only return doPlayerSendCancel... I think I figured it out.

Now that it works. (pretty sure anyways)

What does this part do?

Code:
for vocation, data in ipairs(config) do
for = start of loop
vocation = name of loop?.. could replace with anything or standard 'i' I'm assuming
data = no idea.
ipairs = I've researched this one before, however I haven't been able to grasp the concept yet. From what I understand it allows you to check two variables against each other in a loop? But it doesn't make sense to me. :p
do = 'continue'.. it's pretty much 'then' but for loops? :oops:

Anyways here's the edited code. Please check it over! <3

Cheers,


Xikini

Code:
local config = {
   [1] = { itemRequired = 1111, itemRequiredAmount = 1, itemGiven = 1111, itemGivenAmount = 1, statueID = 8834, nopromo = "sorcerer", promo = "master sorcerer"},
   [2] = { itemRequired = 1111, itemRequiredAmount = 1, itemGiven = 1111, itemGivenAmount = 1, statueID = 8422, nopromo = "druid", promo = "elder druid"},
   [3] = { itemRequired = 1111, itemRequiredAmount = 1, itemGiven = 1111, itemGivenAmount = 1, statueID = 8836, nopromo = "paladin", promo = "royal paladin"},
   [4] = { itemRequired = 1111, itemRequiredAmount = 1, itemGiven = 1111, itemGivenAmount = 1, statueID = 3739, nopromo = "knight", promo = "elite knight"}
}

function onUse(cid, item, fromPosition, itemEx, toPosition)
   local vocType = getPlayerVocationName(cid):lower()
   for vocation, data in ipairs(config) do
     if item.itemid == config[vocation].statueID then
       if (vocType == config[vocation].nopromo or vocType == config[vocation].promo) then
         if getPlayerItemCount(cid, config[vocation].itemRequired) >= config[vocation].itemRequiredAmount then
           doPlayerRemoveItem(cid, config[vocation].itemRequired, config[vocation].itemRequiredAmount)
           doPlayerAddItem(cid, config[vocation].itemGiven, config[vocation].itemGivenAmount, true)
           doCreatureSay(cid, "Removed ".. config[vocation].itemRequiredAmount .." ".. getItemNameById(config[vocation].itemRequired) ..". You received ".. config[vocation].itemGivenAmount .." ".. getItemNameById(config[vocation].itemGiven) ..".", TALKTYPE_ORANGE_1)
           return true
         else
           return doPlayerSendCancel(cid, "You require ".. config[vocation].itemRequiredAmount .." ".. getItemNameById(config[vocation].itemRequired) .." to receive ".. config[vocation].itemGivenAmount .." ".. getItemNameById(config[vocation].itemGiven) ..".")
         end
       else
         return doPlayerSendCancel(cid, "Only "..(config[vocation].nopromo).."s may use this statue.")
       end
     end
   end
   return doPlayerSendCancel(cid, "ERROR: itemID used is incorrect. Contact Administration that script is not functioning as intended.")
   -- If you receive this error then the itemID is incorrect. Check the statues being used.
   return true -- this return true will never be used, but I like keeping the habit. :P
end
 
Last edited by a moderator:
What does this part do?
Code:
for vocation, data in ipairs(config) do
for = start of loop
vocation = name of loop?.. could replace with anything or standard 'i' I'm assuming
data = no idea.
ipairs = I've researched this one before, however I haven't been able to grasp the concept yet. From what I understand it allows you to check two variables against each other in a loop? But it doesn't make sense to me. :p
do = 'continue'.. it's pretty much 'then' but for loops? :oops:
https://otland.net/threads/lua-broken-down.235555/#post-2273171
Scroll to the bottom of that post, I explain the generic for loop using both pairs and ipairs.
 
This is incorrect, I didn't review the rest of the script
Code:
return doPlayerSendCancel(cid, "ERROR: itemID used is incorrect. Contact Administration that script is not functioning as intended.")
-- If you receive this error then the itemID is incorrect. Check the statues being used.
return true -- this return true will never be used, but I like keeping the habit. :P
Once the interface / function encounters a return keyword it returns the value & control back to whatever called it

So
Code:
return true
is never executed
 
This is incorrect, I didn't review the rest of the script
Code:
return doPlayerSendCancel(cid, "ERROR: itemID used is incorrect. Contact Administration that script is not functioning as intended.")
-- If you receive this error then the itemID is incorrect. Check the statues being used.
return true -- this return true will never be used, but I like keeping the habit. :P
Once the interface / function encounters a return keyword it returns the value & control back to whatever called it

So
Code:
return true
is never executed
Code:
return true -- this return true will never be used, but I like keeping the habit. :P
I figured that out I think. :P

But thanks for the input <3
 
Back
Top