• 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 [1.4.2] Talkaction with 2 parms and config.

OTcreator

Active Member
Joined
Feb 14, 2022
Messages
425
Solutions
1
Reaction score
44
Hello!
I tried to perform talkaction for server 1.4.2.

It was supposed to work in the way that there is a category store.
The command would look like this, for example: !shop 1.4.
Number 1 is category (parm1) number 4 is item/mount/outfit).

I wanted to make a config, but something is not working for me.

I started to do it like this:

Lua:
function talkAction.onSay(player, words, param, type)
    local split = param:splitTrimmed(",")
    local Id = split[1]
    local categoryId = split[2]
    if not Id and categoryId then
        player:sendCancelMessage("Shop mudule action is wrong.")
        return false
    end
    
    local extra {
     [1] = 22254


    if Id > 0 and categoryId < 4 then
        if categoryId == "1" then
            player:addItem(,)
        elseif categoryID == "2" then
            player:addMount()
        
    
    
        return false
    end
    return false
end

I have a big problem creating a config for this.
I know it would have to work that way:

Code:
local config = {}
    {1 = 2160, -- item
     2 = 14, -- mount
     3 = 128 -- outfit
     }

if Id > 0 and categoryId < 4 then
        if categoryId == "1" then -- check category to send good item/mount/outfit
            player:addItem(CONFIG_PARM2, 1)
        elseif categoryID == "2" then
            player:addMount(CONFIG_PARM2)
        elseif categoryID == "3" then
            player:addOutfit(CONFIG_PARM2, 3)
        end

I don't completely grasp these configs and talkactions....
 
Good attempt for a beginner!

you can organise your config however you like, but i would do something like this:
Lua:
local config = {
    --category 1
    {
        {
            id = 32,
            type = "outfit"
        },
        {
            id = 33,
            type = "outfit"
        },
    },
 
    --category 2
    {
        {
            id = 35,
            type = "mount"
        },
        {
            id = 37,
            type = "mount"
        },
    },
}

then in your code you can just add a guard clause like this:
Lua:
local split = param:splitTrimmed(",")
local category = tonumber(split[1])
local subcategory = tonumber(split[2])

if not category
or not subcategory
or not config[category]
or not config[category][subcategory] then
    --send cancel message, return early
end

local categoryData = config[category][subcategory]
--add mount/outfit or whatever
--you can access the data using categoryData.id for example to get the id, or categoryData.type to get the type
 
Last edited:
Something like that?

Code:
storeProducts = {
    -- EXTRA SERVICES --
    {
        name = "Crystal Coin",
        id = 1,
        reward = 2160
    },
    -- MOUNTS --
    {
        name = "Widow Queen",
        id = 2,
        reward = 14
    },
   -- OUTFIT --
    {
        name = "Citizen",
        id = 3,
        reward = 128
    },

}

function talkAction.onSay(player, words, param, type)
local split = param:splitTrimmed(",")
local category = tonumber(split[1])
local subcategory = tonumber(split[2])

if not category
or not subcategory
or not config[category]
or not config[category][subcategory] then
    player:sendCancelMessage("Shop mudule action is wrong.")
end

local categoryData = config[category][subcategory]

    if subcategory == storeProducts.id then
        if category == tonumber(1) then
            player:addItem(storeProducts.reward, 1)
        elseif category == tonumber(2) then
            player:addMount(storeProducts.reward)
        elseif category == tonumber(3) then
            player:addOutfit(storeProducts.reward, 3)
        end
        return false
    end
end
 
You need to study arrays, both singlular and multi-dimensional, this can then translate similarly to lua tables.

All you did was turn it into a singular table and rename it, without updating the variable name in the code...
 
Last edited:
You need to study arrays, both singlular and multi-dimensional, this can then translate similarly to lua tables...
You could do it for me , please.

Otclient sends such a talkaction.

!shop 1,6

Where 1 is the category 6 is the offer ID.
Now there must be some config to let talkaction know that 6 is some item,if it has category 1 and if it has category 2 then mount. Itd.
 
I have already provided you the code...

you just need to understand how multi-dimensional arrays work...

Lua:
local table = {
    [1] = {
        [1] = {
            id = "a",
        },
        [2] = {
            id = "b",
        }
    },
    [2] = {
        [1] = {
            id = "c",
        },
        [2] = {
            id = "d",
        }
    }
}

--both tables are identical due to ordered indexes being default if not explicitly set--

local table = {
    {
        {id = "a"},
        {id = "b"}
    },
    {
        {id = "c"},
        {id = "d"}
    }
}

This is multidimensional, so you have two parent indexes 1 and 2 (which in your case, would be the categories).
Each index contains two child indexes (subcategories in your case), each which as an "id" property.

So therefore table[1][2] would be "b"
and table[2][1] would be "c"

So your config can be split up into categories, and subcategories using the above simple structure.
 
Last edited:
I understand that you want to use commands to buy items and mounts at the store. I'll give you just one example for you to understand... There are two systems, Gesior and Znote.

magic sword example. (Gesior)
Lua:
local StoreCustom = TalkAction("!shopteste")

function StoreCustom.onSay(player, words, param)
    local pointsToDeduct = 10 ---these points you will spend

    removePoints(player, pointsToDeduct)

    local newItemID = 2400 -- Replace with the ID of the item the player will receive
    local newItemCount = 1 -- Quantity of the new item to be added to the player's inventory
    player:addItem(newItemID, newItemCount)
  
    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have successfully purchased a new item in exchange for" .. pointsToDeduct .. " premium points.")
  
    return false
end

function removePoints(player, amount)
    local accountId = player:getAccountId()
    local query = "UPDATE `accounts` SET `premium_points` = `premium_points` - " .. amount .. " WHERE `id` = " .. accountId
    db.query(query)
end


StoreCustom:separator(" ")
StoreCustom:register()

Znote- Magic sword.
Lua:
local StoreCustom = TalkAction("!shopteste")

function StoreCustom.onSay(player, words, param)
    local pointsToDeduct = 10 -- Replace with the number of points to be deducted

    removePoints(player, pointsToDeduct)

    local newItemID = 2400 -- Replace with the ID of the item the player will receive
    local newItemCount = 1 -- Quantity of the new item to be added to the player's inventory
    player:addItem(newItemID, newItemCount)
  
    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have successfully purchased a new item in exchange for " .. pointsToDeduct .. " premium points.")
  
    return false
end

function removePoints(player, amount)
    local accountId = player:getAccountId()
    local query = "UPDATE `znote_accounts` SET `points` = `points` - " .. amount .. " WHERE `id` = " .. accountId
    db.query(query)
end

StoreCustom:separator(" ")
StoreCustom:register()

To buy outfits or addons. ( Gesior)
Lua:
local outfitsCustom = TalkAction("!shopMage", "!shopCitizen", "!shopHunter", "!shopKnight", "!shopNoblewoman", "!shopNobleman", "!shopSummoner", "!shopWarrior", "!shopBarbarian", "!shopDruid", "!shopWizard", "!shopOriental", "!shopPirate", "!shopAssassin", "!shopBeggar", "!shopShaman", "!shopNorsewoman", "!shopNorseman", "!shopNightmare", "!shopJester", "!shopBrotherhood", "!shopDemon Hunter", "!shopYalaharian", "!shopNewly Wed", "!shopWarmaster", "!shopWayfarer", "!shopRetro Warrior", "!shopRetro Citizen", "!shopRetro Hunter", "!shopRetro Knight", "!shopRetro Mage", "!shopRetro Noblewoman", "!shopRetro Nobleman", "!shopRetro Summoner")

function outfitsCustom.onSay(player, words, param)
    if words == "/shop" then
        return false
    end
  
  
    if words == "!shopMage" then
        local outfitId = (player:getSex() == PLAYERSEX_FEMALE) and 138 or 130 -- Mage outfit ID
        local outfitCost = 50 -- Cost in premium_points to acquire the outfit
        if not player:hasOutfit(outfitId) or not player:hasOutfit(outfitId, 3) then
            db.query("UPDATE accounts SET premium_points = premium_points - " .. outfitCost .. " WHERE account_id = " .. player:getAccountId())
            player:addOutfitAddon(outfitId, 3) -- Add outfit / addons
            player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN)
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Mage outfit addons for " .. outfitCost .. " premium_points!")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Mage outfit!")
        end
        ----------------
    elseif words == "!shopCitizen" then
        local outfitId = (player:getSex() == PLAYERSEX_FEMALE) and 136 or 128 -- Citizen outfit ID
        local outfitCost = 50 -- Cost in premium_points to acquire the outfit
        if not player:hasOutfit(outfitId) or not player:hasOutfit(outfitId, 3) then
            db.query("UPDATE accounts SET premium_points = premium_points - " .. outfitCost .. " WHERE account_id = " .. player:getAccountId())
            player:addOutfitAddon(outfitId, 3) -- Add Citizen outfit / addons
            player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Citizen outfit addons for " .. outfitCost .. " premium_points!")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Citizen outfit!")
        end
        ----------------
    elseif words == "!shopHunter" then
        local outfitId = (player:getSex() == PLAYERSEX_FEMALE) and 137 or 129 -- Hunter outfit ID
        local outfitCost = 50 -- Cost in premium_points to acquire the outfit
        if not player:hasOutfit(outfitId) or not player:hasOutfit(outfitId, 3) then
            db.query("UPDATE accounts SET premium_points = premium_points - " .. outfitCost .. " WHERE account_id = " .. player:getAccountId())
            player:addOutfitAddon(outfitId, 3) -- Add Hunter outfit / addons
            player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE)
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Hunter outfit addons for " .. outfitCost .. " premium_points!")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Hunter outfit!")
        end
        ----------------
    elseif words == "!shopKnight" then
        local outfitId = (player:getSex() == PLAYERSEX_FEMALE) and 139 or 131 -- Knight outfit ID
        local outfitCost = 50 -- Cost in premium_points to acquire the outfit
        if not player:hasOutfit(outfitId) or not player:hasOutfit(outfitId, 3) then
            db.query("UPDATE accounts SET premium_points = premium_points - " .. outfitCost .. " WHERE account_id = " .. player:getAccountId())
            player:addOutfitAddon(outfitId, 3) -- Add Knight outfit / addons
            player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE)
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Knight outfit addons for " .. outfitCost .. " premium_points!")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Knight outfit!")
        end
  
    -- Add more commands and messages as necessary
    end

    return false
end

outfitsCustom:separator(" ")
outfitsCustom:register()
To buy a mount. ( Gesior)
Lua:
local shopsCustom = TalkAction("!shopMidnight Panther", "!shopWidow Queen", "!shopRacing Bird", "!shopWar Bear", "!shopBlack Sheep", "!shopDraptor", "!shopTitanica", "!shopTin Lizzard", "!shopBlazebringer", "!shopRapid Boar", "!shopStampor", "!shopUndead Cavebear", "!shopDonkey", "!shopTiger Slug", "!shopUniwheel", "!shopCrystal Wolf", "!shopWar Horse", "!shopKingly Deer", "!shopTamed Panda", "!shopDromedary", "!shopScorpion King", "!shopDarkbrown Rented Horse", "!shopArmoured War Horse", "!shopShadow Draptor", "!shopGrey Rented Horse", "!shopBrown Rented Horse", "!shopLady Bug", "!shopManta Ray", "!shopIronblight", "!shopMagma Crawler", "!shopDragonling", "!shopGnarlhound", "!shopCrimson Ray", "!shopSteelbeak", "!shopWater Buffalo", "!shopTombstinger", "!shopPlatesaurian", "!shopUrsagrodon", "!shopThe Hellgrip", "!shopNoble Lion", "!shopDesert King", "!shopShock Head", "!shopWalker", "!shopAzudocus", "!shopCarpacosaurus", "!shopDeath Crawler", "!shopFlamesteed", "!shopJade Lion", "!shopJade Pincer", "!shopNethersteed", "!shopTempest", "!shopWinter King", "!shopDoombringer", "!shopWoodland Prince", "!shopHailstorm Fury", "!shopSiegebreaker", "!shopPoisonbane", "!shopBlackpelt", "!shopGolden Dragonfly", "!shopSteel Bee", "!shopCopper Fly", "!shopTundra Rambler", "!shopHighland Yak", "!shopGlacier Vagabond", "!shopShadow Hart", "!shopBlack Stag", "!shopEmperor Deer", "!shopFlying Divan", "!shopMagic Carpet", "!shopFloating Kashmir", "!shopRingtail Waccoon", "!shopNight Waccoon", "!shopEmerald Waccoon", "!shopFlitterkatzen", "!shopVenompaw", "!shopBatcat", "!shopSea Devil", "!shopCoralripper", "!shopPlumfish", "!shopGorongra", "!shopNoctungra", "!shopSilverneck", "!shopSlagsnare", "!shopNightstinger", "!shopRazorcreep", "!shopRift Runner", "!shopNightdweller", "!shopFrostflare", "!shopCinderhoof", "!shopMouldpincer", "!shopBloodcurl", "!shopLeafscuttler", "!shopSparkion", "!shopSwamp Snapper", "!shopMould Shell", "!shopReed Lurker", "!shopNeon Sparkid", "!shopVortexion", "!shopIvory Fang", "!shopShadow Claw", "!shopSnow Pelt", "!shopJackalope", "!shopDreadhare", "!shopWolpertinger", "!shopStone Rhino", "!shopGold Sphinx", "!shopEmerald Sphinx", "!shopShadow Sphinx", "!shopJungle Saurian", "!shopEmber Saurian", "!shopLagoon Saurian", "!shopBlazing Unicorn", "!shopArctic Unicorn", "!shopPrismatic unicorn", "!shopCranium Spider", "!shopCave Tarantula", "!shopGloom Widow", "!shopMole", "!shopMarsh Toad", "!shopSanguine Frog", "!shopToxic Toad", "!shopEbony Tiger", "!shopFeral Tiger", "!shopJungle Tiger", "!shopFleeting Knowledge", "!shopTawny Owl", "!shopSnowy Owl", "!shopBoreal Owl", "!shopLacewing Moth", "!shopHibernal Moth", "!shopCold Percht Sleigh", "!shopBright Percht Sleigh", "!shopDark Percht Sleigh", "!shopFestive Snowman", "!shopMuffled Snowman", "!shopCaped Snowman", "!shopRabbit Rickshaw", "!shopBunny Dray", "!shopCony Cart", "!shopRiver Crocovile", "!shopSwamp Crocovile", "!shopNightmarish Crocovile", "!shopGryphon", "!shopJousting Eagle", "!shopCerberus Champion", "!shopCold Percht Sleigh Variant", "!shopBright Percht Sleigh Variant", "!shopDark Percht Sleigh Variant", "!shopCold Percht Sleigh Final", "!shopBright Percht Sleigh Final", "!shopDark Percht Sleigh Final", "!shopBattle Badger", "!shopEther Badger", "!shopZaoan Badger", "!shopBlue Rolling Barrel", "!shopRed Rolling Barrel", "!shopGreen Rolling Barrel", "!shopFloating Sage", "!shopFloating Scholar", "!shopFloating Augur", "!shopHaze", "!shopAntelope", "!shopSnow Strider", "!shopDusk Pryer", "!shopDawn Strayer", "!shopSpectral Horse", "!shopSavanna Ostrich", "!shopCoral Rhea", "!shopEventide Nandu", "!shopVoracious Hyaena", "!shopCunning Hyaena", "!shopScruffy Hyaena", "!shopWhite Lion", "!shopKrakoloss", "!shopMerry Mammoth", "!shopHoliday Mammoth", "!shopFestive Mammoth", "!shopVoid Watcher", "!shopRune Watcher", "!shopRift Watcher", "!shopPhant", "!shopShellodon", "!shopSingeing Steed", "!shopHyacinth", "!shopPeony", "!shopDandelion", "!shopRustwurm", "!shopBogwurm", "!shopGloomwurm", "!shopEmerald Raven", "!shopMystic Raven", "!shopRadiant Raven", "!shopGloothomotive", "!shopTopaz Shrine", "!shopJade Shrine", "!shopObsidian Shrine", "!shopPoppy Ibex", "!shopMint Ibex", "!shopCinnamon Ibex")

function shopsCustom.onSay(player, words, param)
    if words == "/shop" then
        return false
    end
  
    if words == "!shopMidnight Panther" then
        local shopId = 1 -- Mount ID
        local shopCost = 20 -- Cost in premium_points to acquire the shop
        if not player:hasMount(shopId) then
            db.query("UPDATE accounts SET premium_points = premium_points - " .. shopCost .. " WHERE account_id = " .. player:getAccountId())
            player:addMount(shopId) --
            player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN)
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Midnight Panther for " .. shopCost .. " premium_points!")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Midnight Panther!")
        end
    elseif words == "!shopWidow Queen" then
        local shopId = 2 -- Mount ID
        local shopCost = 20 -- Cost in premium_points to acquire the shop
        if not player:hasMount(shopId) then
            db.query("UPDATE accounts SET premium_points = premium_points - " .. shopCost .. " WHERE account_id = " .. player:getAccountId())
            player:addMount(shopId) --
            player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN)
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Widow Queen for " .. shopCost .. " premium_points!")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Widow Queen!")
        end
    elseif words == "!shopRacing Bird" then
        local shopId = 3 -- Mount ID
        local shopCost = 20 -- Cost in premium_points to acquire the shop
        if not player:hasMount(shopId) then
            db.query("UPDATE accounts SET premium_points = premium_points - " .. shopCost .. " WHERE account_id = " .. player:getAccountId())
            player:addMount(shopId) --
            player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN)
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Racing Bird for " .. shopCost .. " premium_points!")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Racing Bird!")
        end
    elseif words == "!shopWar Bear" then
        local shopId = 4 -- Mount ID
        local shopCost = 20 -- Cost in premium_points to acquire the shop
        if not player:hasMount(shopId) then
            db.query("UPDATE accounts SET premium_points = premium_points - " .. shopCost .. " WHERE account_id = " .. player:getAccountId())
            player:addMount(shopId) --
            player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN)
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the War Bear for " .. shopCost .. " premium_points!")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the War Bear!")
        end
 
    end
end

shopsCustom:separator(" ")
shopsCustom:register()

outfits or addons.( Znote)
Lua:
local outfitsCustom = TalkAction("!shopMage", "!shopCitizen", "!shopHunter", "!shopKnight", "!shopNoblewoman", "!shopNobleman", "!shopSummoner", "!shopWarrior", "!shopBarbarian", "!shopDruid", "!shopWizard", "!shopOriental", "!shopPirate", "!shopAssassin", "!shopBeggar", "!shopShaman", "!shopNorsewoman", "!shopNorseman", "!shopNightmare", "!shopJester", "!shopBrotherhood", "!shopDemon Hunter", "!shopYalaharian", "!shopNewly Wed", "!shopWarmaster", "!shopWayfarer", "!shopRetro Warrior", "!shopRetro Citizen", "!shopRetro Hunter", "!shopRetro Knight", "!shopRetro Mage", "!shopRetro Noblewoman", "!shopRetro Nobleman", "!shopRetro Summoner")

function outfitsCustom.onSay(player, words, param)
    if words == "/shop" then
        return false
    end
  
  
    if words == "!shopMage" then
        local outfitId = (player:getSex() == PLAYERSEX_FEMALE) and 138 or 130 -- Mage outfit ID
        local outfitCost = 50 -- Cost in points to acquire the outfit
        if not player:hasOutfit(outfitId) or not player:hasOutfit(outfitId, 3) then
            db.query("UPDATE znote_accounts SET points = points - " .. outfitCost .. " WHERE account_id = " .. player:getAccountId())
            player:addOutfitAddon(outfitId, 3) -- Add outfit / addons
            player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN)
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Mage outfit addons for " .. outfitCost .. " points!")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Mage outfit!")
        end
        ----------------
    elseif words == "!shopCitizen" then
        local outfitId = (player:getSex() == PLAYERSEX_FEMALE) and 136 or 128 -- Citizen outfit ID
        local outfitCost = 50 -- Cost in points to acquire the outfit
        if not player:hasOutfit(outfitId) or not player:hasOutfit(outfitId, 3) then
            db.query("UPDATE znote_accounts SET points = points - " .. outfitCost .. " WHERE account_id = " .. player:getAccountId())
            player:addOutfitAddon(outfitId, 3) -- Add Citizen outfit / addons
            player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Citizen outfit addons for " .. outfitCost .. " points!")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Citizen outfit!")
        end
        ----------------
    elseif words == "!shopHunter" then
        local outfitId = (player:getSex() == PLAYERSEX_FEMALE) and 137 or 129 -- Hunter outfit ID
        local outfitCost = 50 -- Cost in points to acquire the outfit
        if not player:hasOutfit(outfitId) or not player:hasOutfit(outfitId, 3) then
            db.query("UPDATE znote_accounts SET points = points - " .. outfitCost .. " WHERE account_id = " .. player:getAccountId())
            player:addOutfitAddon(outfitId, 3) -- Add Hunter outfit / addons
            player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE)
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Hunter outfit addons for " .. outfitCost .. " points!")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Hunter outfit!")
        end
        ----------------
    elseif words == "!shopKnight" then
        local outfitId = (player:getSex() == PLAYERSEX_FEMALE) and 139 or 131 -- Knight outfit ID
        local outfitCost = 50 -- Cost in points to acquire the outfit
        if not player:hasOutfit(outfitId) or not player:hasOutfit(outfitId, 3) then
            db.query("UPDATE znote_accounts SET points = points - " .. outfitCost .. " WHERE account_id = " .. player:getAccountId())
            player:addOutfitAddon(outfitId, 3) -- Add Knight outfit / addons
            player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE)
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Knight outfit addons for " .. outfitCost .. " points!")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Knight outfit!")
        end
        ----------------
        elseif words == "!shopNoblewoman" then
        local outfitId = (player:getSex() == PLAYERSEX_FEMALE) and 140 or 132 --  outfit ID
        local outfitCost = 50 -- Cost in points to acquire the outfit
        if not player:hasOutfit(outfitId) or not player:hasOutfit(outfitId, 3) then
            db.query("UPDATE znote_accounts SET points = points - " .. outfitCost .. " WHERE account_id = " .. player:getAccountId())
            player:addOutfitAddon(outfitId, 3) -- Add outfit / addons
            player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE)
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Noblewoman outfit addons for " .. outfitCost .. " points!")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Noblewoman outfit!")
        end
  
    -- Add more commands and messages as necessary
    end

    return false
end

outfitsCustom:separator(" ")
outfitsCustom:register()
Post automatically merged:

Mount (Znote)
Lua:
local shopsCustom = TalkAction("!shopMidnight Panther", "!shopWidow Queen", "!shopRacing Bird", "!shopWar Bear")

function shopsCustom.onSay(player, words, param)
    if words == "/shop" then
        return false
    end
  
    if words == "!shopMidnight Panther" then
        local shopId = 1 -- Mount ID
        local shopCost = 20 -- Cost in points to acquire the shop
        if not player:hasMount(shopId) then
            db.query("UPDATE znote_accounts SET points = points - " .. shopCost .. " WHERE account_id = " .. player:getAccountId())
            player:addMount(shopId) --
            player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN)
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Midnight Panther for " .. shopCost .. " points!")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Midnight Panther!")
        end
    elseif words == "!shopWidow Queen" then
        local shopId = 2 -- Mount ID
        local shopCost = 20 -- Cost in points to acquire the shop
        if not player:hasMount(shopId) then
            db.query("UPDATE znote_accounts SET points = points - " .. shopCost .. " WHERE account_id = " .. player:getAccountId())
            player:addMount(shopId) --
            player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN)
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Widow Queen for " .. shopCost .. " points!")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Widow Queen!")
        end
    elseif words == "!shopRacing Bird" then
        local shopId = 3 -- Mount ID
        local shopCost = 20 -- Cost in points to acquire the shop
        if not player:hasMount(shopId) then
            db.query("UPDATE znote_accounts SET points = points - " .. shopCost .. " WHERE account_id = " .. player:getAccountId())
            player:addMount(shopId) --
            player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN)
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Racing Bird for " .. shopCost .. " points!")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Racing Bird!")
        end
    elseif words == "!shopWar Bear" then
        local shopId = 4 -- Mount ID
        local shopCost = 20 -- Cost in points to acquire the shop
        if not player:hasMount(shopId) then
            db.query("UPDATE znote_accounts SET points = points - " .. shopCost .. " WHERE account_id = " .. player:getAccountId())
            player:addMount(shopId) --
            player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN)
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the War Bear for " .. shopCost .. " points!")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the War Bear!")
        end
 
    end
end

shopsCustom:separator(" ")
shopsCustom:register()
If it's MyAcc, it's another thing... It's necessary to alter the database to recognize 'premium_points' or 'Points'... I believe MyAcc is quite similar to Gesior... but I haven't tested it with MyAcc yet. I've only tested Gesior and Znote, and they worked well for me and other colleagues who also tested them.
None of these scripts do a check for existing points. Therefore the balance can go negative, or throw an error if the column is unsigned... Either way, players are getting free items if they cant afford them.

You can also combine all of these into one, using a table of data.
 
@Fjorda Okay, all right... I've made the decision. I'll delete the post you mentioned doesn't work and such, but for me, it's working perfectly, 100%, and there are no errors whatsoever... Thank you for your response.
 
@Fjorda Okay, all right... I've made the decision. I'll delete the post you mentioned doesn't work and such, but for me, it's working perfectly, 100%, and there are no errors whatsoever... Thank you for your response.
No, I don't want to use it for the web store.

It needs a simple script with config.

If you call !shop 1,7

This script is supposed to know that the one is the item category so it will use player:addItem(parm2, 1)
(Parm2 = 7)
(7 im config = 2160).

If you call !shop 2,14

The script is supposed to know that 2 is the mount category so it will use
player:addMount(parm2)
(parm2=14)
(14 in config = 18 (mount ID).
 
This is a good start, but I'm not doing the whole script for you...

Lua:
local config = {
    --category 1 (items)
    {
        type = "items",
        subcategories = {
            {id = 2134, cost = 50, amount = 1},
            {id = 2135, cost = 75, amount = 1},
        }
    },
 
    --category 2 (mounts)
    {
        type = "mounts",
        subcategories = {
            {id = 21, cost = 50},
            {id = 23, cost = 75},
        }
    },
 
    --category 3 (outfits)
    {
        type = "outfits",
        subcategories = {
            {id = 34, cost = 50},
            {id = 35, cost = 75},
        }
    },
}


function talkAction.onSay(player, words, param, type)
    local split = param:splitTrimmed(",")
    local category = tonumber(split[1])
    local subcategory = tonumber(split[2])

    if not category
    or not subcategory
    or not config[category]
    or not config[category].subcategories[subcategory] then
        player:sendCancelMessage("Incorrect shop category or subcategory.")
        return false
    end

    local categoryData = config[category].subcategories[subcategory]
    local categoryType = config[category].type

    if not categoryData.id then
        return false
    end
 
    local cost = categoryData.cost
    --[[
    ADD COST CHECK HERE. IS COST < PLAYERS COIN BALANCE? RETURN EARLY IF CANT AFFORD
    --]]
 
    if categoryType == "items" then
        player:addItem(categoryData.id, categoryData.amount or 1, true)
    elseif categoryType == "mounts" and not player:hasMount(categoryData.id) then
        player:addMount(categoryData.id)
    elseif categoryType == "outfits" and not player:hasOutfit(categoryData.id) then
        player:addOutfit(categoryData.id)
    end
 
    return false
end
 
Last edited:
A perfect time to use enums. Hopefully it's more clear for you.

Lua:
local ITEMS_CATEGORY = 1
local MOUNTS_CATEGORY = 2
local OUTFITS_CATEGORY = 3

local config = {

    [ITEMS_CATEGORY] = {
        [1] = {id = 2134, cost = 50, amount = 1},
        [2] = {id = 2135, cost = 75, amount = 1}
    },
 
    [MOUNTS_CATEGORY] = {
        [1] = {id = 21, cost = 50},
        [2] = {id = 23, cost = 75}
    },
 
    [OUTFITS_CATEGORY] = {
        [1] = {id = 34, cost = 50},
        [2] = {id = 35, cost = 75}
    }
}


function talkAction.onSay(player, words, param, type)

    local split = param:splitTrimmed(",")

    local category = tonumber(split[1])
    local subcategory = tonumber(split[2])

    if not config[category] or not config[category][subcategory] then
        player:sendCancelMessage("Incorrect shop category or subcategory.")
        return false
    end

    local categoryData = config[category][subcategory]
    if not categoryData.id then
        return false
    end
 
    local cost = categoryData.cost
    --[[
    ADD COST CHECK HERE. IS COST < PLAYERS COIN BALANCE? RETURN EARLY IF CANT AFFORD
    --]]
 
    if category == ITEMS_CATEGORY then
        player:addItem(categoryData.id, categoryData.amount or 1, true)
    elseif category == MOUNTS_CATEGORY and not player:hasMount(categoryData.id) then
        player:addMount(categoryData.id)
    elseif category == OUTFITS_CATEGORY and not player:hasOutfit(categoryData.id) then
        player:addOutfit(categoryData.id)
    end
 
    return false
end
 
A perfect time to use enums. Hopefully it's more clear for you.

Lua:
local ITEMS_CATEGORY = 1
local MOUNTS_CATEGORY = 2
local OUTFITS_CATEGORY = 3

local config = {

    [ITEMS_CATEGORY] = {
        [1] = {id = 2134, cost = 50, amount = 1},
        [2] = {id = 2135, cost = 75, amount = 1}
    },
 
    [MOUNTS_CATEGORY] = {
        [1] = {id = 21, cost = 50},
        [2] = {id = 23, cost = 75}
    },
 
    [OUTFITS_CATEGORY] = {
        [1] = {id = 34, cost = 50},
        [2] = {id = 35, cost = 75}
    }
}


function talkAction.onSay(player, words, param, type)

    local split = param:splitTrimmed(",")

    local category = tonumber(split[1])
    local subcategory = tonumber(split[2])

    if not config[category] or not config[category][subcategory] then
        player:sendCancelMessage("Incorrect shop category or subcategory.")
        return false
    end

    local categoryData = config[category][subcategory]
    if not categoryData.id then
        return false
    end
 
    local cost = categoryData.cost
    --[[
    ADD COST CHECK HERE. IS COST < PLAYERS COIN BALANCE? RETURN EARLY IF CANT AFFORD
    --]]
 
    if category == ITEMS_CATEGORY then
        player:addItem(categoryData.id, categoryData.amount or 1, true)
    elseif category == MOUNTS_CATEGORY and not player:hasMount(categoryData.id) then
        player:addMount(categoryData.id)
    elseif category == OUTFITS_CATEGORY and not player:hasOutfit(categoryData.id) then
        player:addOutfit(categoryData.id)
    end
 
    return false
end
Yes , I understand it more now. In earlier posts there was nothing to say that for example the number 1 of parm1 is a category , here it is visible in local.
 
Back
Top