• 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 3 onDeath scripts.

T

tejdi

Guest
I need scripts that:

1. When the player dies, resets all skills and magic levels to values predefined in the database.
(each player has its own values).

SQL:
player -> maglevel_base / skill_club_base / skill_dist_base / skill_shielding_base

1641207458817.png

2. When the player dies, equipment resets to predefined in the database[?] - I am not sure if I should add tables to the player with basic equipment IDs or there is a better way to do that.

3. Removes body after the player dies.
(there shouldn't be a body on the ground or just a body without loot, whatever is simpler)
Post automatically merged:


--

Ad. 1.
I was able to solve it. For anyone who would like to have it:

login.lua (above return true):
Lua:
    -- Skills
    local shieldingBase = db.storeQuery("SELECT `skill_shielding_base` FROM  `players` WHERE `name` = '" .. player:getName() .. "';")
    local distanceBase = db.storeQuery("SELECT `skill_dist_base` FROM  `players` WHERE `name` = '" .. player:getName() .. "';")
    local meleeBase = db.storeQuery("SELECT `skill_club_base` FROM  `players` WHERE `name` = '" .. player:getName() .. "';")
    local magicBase = db.storeQuery("SELECT `maglevel_base` FROM  `players` WHERE `name` = '" .. player:getName() .. "';")
    -- Shielding
    if player:getSkillLevel(5) < shieldingBase then
        player:addSkillTries(5, player:getVocation():getRequiredSkillTries(5, player:getSkillLevel(5) + 1) - player:getSkillTries(5))
    end
    -- Distance
    if player:getSkillLevel(4) < distanceBase then
        player:addSkillTries(4, player:getVocation():getRequiredSkillTries(4, player:getSkillLevel(4) + 1) - player:getSkillTries(4))
    end
    -- Melee
    if player:getSkillLevel(1) < meleeBase then
        player:addSkillTries(1, player:getVocation():getRequiredSkillTries(1, player:getSkillLevel(1) + 1) - player:getSkillTries(1))
    end
    -- Magic
    if player:getSkillLevel(1) < magicBase then
        player:addManaSpent(player:getVocation():getRequiredManaSpent(player:getBaseMagicLevel() + 1) - player:getManaSpent())
    end

Remember to add skill_shielding_base, skill_dist_base, skill_club_base, maglevel_base to your database before.

--

Ad. 3.
I was also able to solve this one. If you also need it:
Add to playerdeath.lua above
Lua:
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are dead.")

This:
Lua:
    -- all slots to look for
    local slots = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    -- cycle through the slots table and store the slot id in slot
    for _, slot in pairs(slots) do
        -- get the player's slot item and store it in item
        local item = player:getSlotItem(slot)
        -- if the item exists meaning its not nil then continue
        if item then
            -- if it exists then remove the item
            item:remove()
        end
    end
 
Last edited by a moderator:
I need scripts that:

1. When the player dies, resets all skills and magic levels to values predefined in the database.
(each player has its own values).

SQL:
player -> maglevel_base / skill_club_base / skill_dist_base / skill_shielding_base

View attachment 64394

2. When the player dies, equipment resets to predefined in the database[?] - I am not sure if I should add tables to the player with basic equipment IDs or there is a better way to do that.

3. Removes body after the player dies.
(there shouldn't be a body on the ground or just a body without loot, whatever is simpler)
Post automatically merged:


--

Ad. 1.
I was able to solve it. For anyone who would like to have it:

login.lua (above return true):
Lua:
    -- Skills
    local shieldingBase = db.storeQuery("SELECT `skill_shielding_base` FROM  `players` WHERE `name` = '" .. player:getName() .. "';")
    local distanceBase = db.storeQuery("SELECT `skill_dist_base` FROM  `players` WHERE `name` = '" .. player:getName() .. "';")
    local meleeBase = db.storeQuery("SELECT `skill_club_base` FROM  `players` WHERE `name` = '" .. player:getName() .. "';")
    local magicBase = db.storeQuery("SELECT `maglevel_base` FROM  `players` WHERE `name` = '" .. player:getName() .. "';")
    -- Shielding
    if player:getSkillLevel(5) < shieldingBase then
        player:addSkillTries(5, player:getVocation():getRequiredSkillTries(5, player:getSkillLevel(5) + 1) - player:getSkillTries(5))
    end
    -- Distance
    if player:getSkillLevel(4) < distanceBase then
        player:addSkillTries(4, player:getVocation():getRequiredSkillTries(4, player:getSkillLevel(4) + 1) - player:getSkillTries(4))
    end
    -- Melee
    if player:getSkillLevel(1) < meleeBase then
        player:addSkillTries(1, player:getVocation():getRequiredSkillTries(1, player:getSkillLevel(1) + 1) - player:getSkillTries(1))
    end
    -- Magic
    if player:getSkillLevel(1) < magicBase then
        player:addManaSpent(player:getVocation():getRequiredManaSpent(player:getBaseMagicLevel() + 1) - player:getManaSpent())
    end

Remember to add skill_shielding_base, skill_dist_base, skill_club_base, maglevel_base to your database before.

--

Ad. 3.
I was also able to solve this one. If you also need it:
Add to playerdeath.lua above
Lua:
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are dead.")

This:
Lua:
    -- all slots to look for
    local slots = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    -- cycle through the slots table and store the slot id in slot
    for _, slot in pairs(slots) do
        -- get the player's slot item and store it in item
        local item = player:getSlotItem(slot)
        -- if the item exists meaning its not nil then continue
        if item then
            -- if it exists then remove the item
            item:remove()
        end
    end
You don't need multiple storeQuerys like that, you can do it all within one like this:
Lua:
local resultId = db.storeQuery("SELECT `skill_shielding_base`, `skill_dist_base`, `skill_club_base`, `maglevel_base` FROM `players` WHERE `name` = " .. db.escapeString(player:getName()))
if resultId ~= false then
    local shieldingBase = result.getNumber(resultId, "skill_shielding_base")
    if shieldingBase and player:getSkillLevel(5) < shieldingBase then
        player:addSkillTries(5, player:getVocation():getRequiredSkillTries(5, player:getSkillLevel(5) + 1) - player:getSkillTries(5))
    end

    -- etc, etc

    result.free(resultId)
end

However, I don't think it's necessary to have a database entry for these base stats at all, you can much more easily use storage values instead of pulling from database every death.

With the equipment reset, are these items going to be specific to the individual player or do all players get the same equipment again after death? Because if they are all the same you can just create a simple table within the script. And if not, again, storage values are your way to go; I would have one storage key reserved for players base helmet item id, and one for base armor item id, etc.

Then removing the corpse should be as simple as:

Lua:
if corpse then
    corpse:remove()
end
 
methods for doing all of this except for removing the corpse which should be trivial are contained in this datapack I released years ago:
 
You don't need multiple storeQuerys like that, you can do it all within one like this:
Lua:
local resultId = db.storeQuery("SELECT `skill_shielding_base`, `skill_dist_base`, `skill_club_base`, `maglevel_base` FROM `players` WHERE `name` = " .. db.escapeString(player:getName()))
if resultId ~= false then
    local shieldingBase = result.getNumber(resultId, "skill_shielding_base")
    if shieldingBase and player:getSkillLevel(5) < shieldingBase then
        player:addSkillTries(5, player:getVocation():getRequiredSkillTries(5, player:getSkillLevel(5) + 1) - player:getSkillTries(5))
    end

    -- etc, etc

    result.free(resultId)
end

However, I don't think it's necessary to have a database entry for these base stats at all, you can much more easily use storage values instead of pulling from database every death.

With the equipment reset, are these items going to be specific to the individual player or do all players get the same equipment again after death? Because if they are all the same you can just create a simple table within the script. And if not, again, storage values are your way to go; I would have one storage key reserved for players base helmet item id, and one for base armor item id, etc.

Then removing the corpse should be as simple as:

Lua:
if corpse then
    corpse:remove()
end

That's great, thanks!
The only thing that I don't know how to fix here is that I need 4 relogs in order to have all skills leveled up.

Code:
Lua:
    --Skills
    local resultId = db.storeQuery("SELECT `skill_shielding_base`, `skill_dist_base`, `skill_club_base`, `maglevel_base` FROM `players` WHERE `name` = " .. db.escapeString(player:getName()))
    if resultId ~= false then
    
    --Dodawanie
    local shieldingBase = result.getNumber(resultId, "skill_shielding_base")
    while shieldingBase and player:getSkillLevel(5) < shieldingBase do
        player:addSkillTries(5, player:getVocation():getRequiredSkillTries(5, player:getSkillLevel(5) + 1) - player:getSkillTries(5))
        print(""..player:getName().."")
        print(""..shieldingBase.."")
    end
    
    local distanceBase = result.getNumber(resultId, "skill_dist_base")
    while distanceBase and player:getSkillLevel(4) < distanceBase do
        player:addSkillTries(4, player:getVocation():getRequiredSkillTries(4, player:getSkillLevel(4) + 1) - player:getSkillTries(4))
        print(""..player:getName().."")
        print(""..distanceBase.."")
    end
    
    local meleeBase = result.getNumber(resultId, "skill_club_base")
    while meleeBase and player:getSkillLevel(1) < meleeBase do
            player:addSkillTries(1, player:getVocation():getRequiredSkillTries(1, player:getSkillLevel(1) + 1) - player:getSkillTries(1))
            print(""..player:getName().."")
            print(""..meleeBase.."")
    end
    
    local magicBase = result.getNumber(resultId, "maglevel_base")
    while magicBase and player:getSkillLevel(5) < magicBase do
        player:addManaSpent(player:getVocation():getRequiredManaSpent(player:getBaseMagicLevel() + 1) - player:getManaSpent())
    end

    result.free(resultId)
    end

Also, the magic level seems not to work for some reason.


For the equipment. It should work the same way as skills, so players can upgrade their baseHelmet = id with time.
(Every player has his own values and they can be updated per player)
 
Last edited by a moderator:
That's great, thanks!
The only thing that I don't know how to fix here is that I need 4 relogs in order to have all skills leveled up.

Code:
Lua:
    --Skills
    local resultId = db.storeQuery("SELECT `skill_shielding_base`, `skill_dist_base`, `skill_club_base`, `maglevel_base` FROM `players` WHERE `name` = " .. db.escapeString(player:getName()))
    if resultId ~= false then
   
    --Dodawanie
    local shieldingBase = result.getNumber(resultId, "skill_shielding_base")
    while shieldingBase and player:getSkillLevel(5) < shieldingBase do
        player:addSkillTries(5, player:getVocation():getRequiredSkillTries(5, player:getSkillLevel(5) + 1) - player:getSkillTries(5))
        print(""..player:getName().."")
        print(""..shieldingBase.."")
    end
   
    local distanceBase = result.getNumber(resultId, "skill_dist_base")
    while distanceBase and player:getSkillLevel(4) < distanceBase do
        player:addSkillTries(4, player:getVocation():getRequiredSkillTries(4, player:getSkillLevel(4) + 1) - player:getSkillTries(4))
        print(""..player:getName().."")
        print(""..distanceBase.."")
    end
   
    local meleeBase = result.getNumber(resultId, "skill_club_base")
    while meleeBase and player:getSkillLevel(1) < meleeBase do
            player:addSkillTries(1, player:getVocation():getRequiredSkillTries(1, player:getSkillLevel(1) + 1) - player:getSkillTries(1))
            print(""..player:getName().."")
            print(""..meleeBase.."")
    end
   
    local magicBase = result.getNumber(resultId, "maglevel_base")
    while magicBase and player:getSkillLevel(5) < magicBase do
        player:addManaSpent(player:getVocation():getRequiredManaSpent(player:getBaseMagicLevel() + 1) - player:getManaSpent())
    end

    result.free(resultId)
    end

Also, the magic level seems not to work for some reason.


For the equipment. It should work the same way as skills, so players can upgrade their baseHelmet = id with time.
(Every player has his own values and they can be updated per player)
This is how I would approach a storage based system for this. First part you can put within lib/core/player.lua (you can change the storages to whatever you need them to be).

Lua:
local baseSkillStorages = {
    [SKILL_FIST] = 90100,
    [SKILL_CLUB] = 90101,
    [SKILL_SWORD] = 90102,
    [SKILL_AXE] = 90103,
    [SKILL_DISTANCE] = 90104,
    [SKILL_SHIELD] = 901005,
    [SKILL_FISHING] = 90106,
    [SKILL_MAGLEVEL] = 90107,
}

function Player.setBaseSkillLevel(self, skillType, skillLevel)
    local storageKey = baseSkillStorages[skillType]
    if not storageKey then
        return false
    end

    return skillLevel and self:setStorageValue(storageKey, skillLevel)
end

function Player.getBaseSkillLevel(self, skillType)
    local storageKey = baseSkillStorages[skillType]
    if not storageKey then
        return false
    end

    local baseSkillLevel = self:getStorageValue(storageKey)
    return baseSkillLevel > 10 and baseSkillLevel or (skillType == SKILL_MAGLEVEL and 0 or 10)
end

local baseSlotStorages = {
    [CONST_SLOT_HEAD] = 90108,
    [CONST_SLOT_NECKLACE] = 90109,
    [CONST_SLOT_BACKPACK] = 90110,
    [CONST_SLOT_ARMOR] = 90111,
    [CONST_SLOT_RIGHT] = 90112,
    [CONST_SLOT_LEFT] = 90113,
    [CONST_SLOT_LEGS] = 90114,
    [CONST_SLOT_FEET] = 90115,
    [CONST_SLOT_RING] = 90116,
    [CONST_SLOT_AMMO] = 90117,
}

function Player.setBaseSlotItemId(self, slot, itemid)
    local storageKey = baseSlotStorages[slot]
    if not storageKey then
        return false
    end

    return itemid and self:setStorageValue(storageKey, itemid)
end

function Player.getBaseSlotItemId(self, slot)
    local storageKey = baseSlotStorages[slot]
    if not storageKey then
        return false
    end

    local baseSlotItemId = self:getStorageValue(storageKey)
    return baseSlotItemId > 0 and baseSlotItemId or false
end

The next bits should be within the onDeath script.

Reverting skills (at least in my testing, using a gm didn't work right, make sure you test with a non gm char)
Lua:
player:addSkillLevel(SKILL_SHIELD, player:getBaseSkillLevel(SKILL_SHIELD) - player:getSkillLevel(SKILL_SHIELD))
player:addSkillLevel(SKILL_DISTANCE, player:getBaseSkillLevel(SKILL_DISTANCE) - player:getSkillLevel(SKILL_DISTANCE))
player:addSkillLevel(SKILL_CLUB, player:getBaseSkillLevel(SKILL_CLUB) - player:getSkillLevel(SKILL_CLUB))
player:addMagicLevel(player:getBaseSkillLevel(SKILL_MAGLEVEL) - player:getMagicLevel())

Reverting equipment, ofc within first login script you should set the initial values then however else you want to manage base slot items but it wont return the base item until you set it first.
Lua:
for slot = CONST_SLOT_HEAD, CONST_SLOT_AMMO do
    local slotItem = player:getSlotItem(slot)
    if slotItem then
        slotItem:remove()
    end

    local baseSlotItemId = player:getBaseSlotItemId(slot)
    if baseSlotItemId then
        player:addItem(baseSlotItemId, 1, false, 1, slot)
    end
end

Lastly the corpse should still work the same. If it doesn't then you may have to use an addEvent to search for the corpse after 100 ms.

Lua:
if corpse then
    corpse:remove()
end
 
This is how I would approach a storage based system for this. First part you can put within lib/core/player.lua (you can change the storages to whatever you need them to be).

Thanks!
Removing corpse works without adding addEvent.

I have a question regarding skills and items. In order to make it work, I have to add "storageKeys" to these "StorageValues" on the first login, which are equal to starting skill/item id, right?

How would you approach editing existing the following "firstitems.lua"?

Lua:
local config = {
    [1] = {
        --SORCERER equipment spellbook, wand of vortex, magician's robe, mage hat, studded legs, leather boots, scarf
        items = {{2460, 1}, {2465, 1}, {2478, 1}, {2643, 1}, {2511, 1}, {2190, 1}},
        --container
        container = {{2120, 1}, {2554, 1}, {7620, 1}}
    },
    [2] = {
        --equipment spellbook, snakebite rod, magician's robe, mage hat, studded legs, leather boots scarf
        items = {{2460, 1}, {2465, 1}, {2478, 1}, {2643, 1}, {2511, 1}, {2182, 1}},
        --container
        container = {{2120, 1}, {2554, 1}, {7620, 1}}
    },
    [3] = {
        --equipment dwrven shield, 5 spear, ranger's cloak, ranger legs scarf, legion helmet
        items = {{2460, 1}, {2465, 1}, {2478, 1}, {2643, 1}, {2456, 1}, {2544, 1}},
        --container
        container = {{2120, 1}, {2554, 1}, {7618, 1}}
    },
    [4] = {
        --equipment dwarven shield, steel axe, brass armor, brass helmet, brass legs scarf
        items = {{2460, 1}, {2465, 1}, {2478, 1}, {2643, 1}, {2511, 1}, {2383, 1}},
        --container
        container = {{2120, 1}, {2554, 1}, {7618, 1}}
    }
}

function onLogin(player)
    local targetVocation = config[player:getVocation():getId()]
    if not targetVocation then
        return true
    end

    if player:getStorageValue(10000) ~= 1 then
    player:setStorageValue(10000, 1)
    player:say('Your equipment has been reset!')
    for i = 1, #targetVocation.items do
        player:addItem(targetVocation.items[i][1], targetVocation.items[i][2])
    end
    
    local backpack = player:addItem(1988)
    if not backpack then
        return true
    end

    for i = 1, #targetVocation.container do
        backpack:addItem(targetVocation.container[i][1], targetVocation.container[i][2])
    end
        return true
    end
    return true
end
 
Back
Top