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

VIP System [The Forgotten Server 1.0]

In mine is like this, I try to change but just the error, what would be the correct way? Thanks

Lua:
    -- Experience Stage Multiplier
    local expStage = Game.getExperienceStage(self:getLevel())
    exp = exp * expStage
    baseExp = rawExp * expStage
    if Game.getStorageValue(GlobalStorage.XpDisplayMode) > 0 then
        displayRate = expStage
        else
        displayRate = 1
    end
What Strutz said, and which error is being thrown by the console?
 
player.lua

Here you go:

All i did was add 3 lines of code at 757 to 761

Lua:
    -- VIP Bonus
    local vipBonus = 2 -- This is where you add your multip
    if self:isVip() then
        exp = exp * vipBonus
    end
 
script for VIP effect? that display on the character?
Post automatically merged:

script for VIP effect? that display on the character?
 
Last edited:
Here you go:

All i did was add 3 lines of code at 757 to 761

Lua:
    -- VIP Bonus
    local vipBonus = 2 -- This is where you add your multip
    if self:isVip() then
        exp = exp * vipBonus
    end
Greetings strutZ, how to add bonus 10% for loot chance if you are vip? also while killing the monster should tells you loot bonus: 10% activated if it possible
thanks
 
Greetings strutZ, how to add bonus 10% for loot chance if you are vip? also while killing the monster should tells you loot bonus: 10% activated if it possible
thanks
Make a new post in support and tell me what version you are using and I will help.
 
Credits & Stuff
Credits go to @Printer for creating the original system (VIP System TFS [1.1] (http://otland.net/threads/vip-system-tfs-1-1.224758/)) upon which this system is based and which motivated me to work on it. Thanks for that.

This version uses a global variable to look up the current vip days of a player, so there is no need to use a mysql query each time you check if a player has vip status (which I assume is the most used function of the system).
I added support for infinite vip time and a talkaction for staff members.
If you miss any basic feature which might be helpful feel free to request it.
This version is supposed to work on The Forgotten Server 1.0 which you can download at Releases · otland/forgottenserver (https://github.com/otland/forgottenserver/releases).
I think I tested every case of the system if you however find any bugs / issues report them please or I might have messed up some copy & pasting.



System
MySQL queries
- execute those in your database
Code:
ALTER TABLE `accounts`
        ADD COLUMN `viplastday` int(10) NOT NULL DEFAULT 0 AFTER `lastday`,
        ADD COLUMN `vipdays` int(11) NOT NULL DEFAULT 0 AFTER `lastday`;

login.lua
  • this file is located in data/creaturescripts/scripts/ folder
  • add the following code after local player = Player(cid)
Code:
    player:loadVipData()
    player:updateVipTime()

global.lua
  • this file is located in data/ folder
  • add this code below dofile('data/compat.lua')
Code:
dofile('data/vip-system.lua')

vip-system.lua
  • create this file in your data folder
  • !Note: You have to adjust the following lines to your needs:
Code:
    -- true = player will be teleported to this position if Vip runs out
    -- false = player will not be teleported
    useTeleport = true,
    expirationPosition = Position(95, 114, 7),

    -- true = player will received the message you set
    -- false = player will not receive a message
    useMessage = true,
    expirationMessage = 'Your vip days ran out.',
    expirationMessageType = MESSAGE_STATUS_WARNING
- paste the following code in the newly created file
Code:
--[[

# Vip System for The Forgotten Server 1.0
# https://github.com/otland/forgottenserver/releases (1.0)

# Vip System by Summ
## Version v0.2
## Link: http://otland.net/threads/vip-system-the-forgotten-server-1-0.224910/

# Credits to Printer upon whose script this is based
## Link: http://otland.net/threads/vip-system-tfs-1-1.224758/

# MySQL query
    ALTER TABLE `accounts`
        ADD COLUMN `viplastday` int(10) NOT NULL DEFAULT 0 AFTER `lastday`,
        ADD COLUMN `vipdays` int(11) NOT NULL DEFAULT 0 AFTER `lastday`;

]]

local config = {
    -- true = player will be teleported to this position if Vip runs out
    -- false = player will not be teleported
    useTeleport = true,
    expirationPosition = Position(95, 114, 7),

    -- true = player will received the message you set
    -- false = player will not receive a message
    useMessage = true,
    expirationMessage = 'Your vip days ran out.',
    expirationMessageType = MESSAGE_STATUS_WARNING
}

if not VipData then
    VipData = { }
end

function Player.onRemoveVip(self)
    if config.useTeleport then
        self:teleportTo(config.expirationPosition)
        config.expirationPosition:sendMagicEffect(CONST_ME_TELEPORT)
    end

    if config.useMessage then
        self:sendTextMessage(config.expirationMessageType, config.expirationMessage)
    end
end

function Player.getVipDays(self)
    return VipData[self:getId()].days
end

function Player.getLastVipDay(self)
    return VipData[self:getId()].lastDay
end

function Player.isVip(self)
    return self:getVipDays() > 0
end

function Player.addInfiniteVip(self)
    local data = VipData[self:getId()]
    data.days = 0xFFFF
    data.lastDay = 0

    db.query(string.format('UPDATE `accounts` SET `vipdays` = %i, `viplastday` = %i WHERE `id` = %i;', 0xFFFF, 0, self:getAccountId()))
end

function Player.addVipDays(self, amount)
    local data = VipData[self:getId()]
    local amount = math.min(0xFFFE - data.days, amount)
    if amount > 0 then
        if data.days == 0 then
            local time = os.time()
            db.query(string.format('UPDATE `accounts` SET `vipdays` = `vipdays` + %i, `viplastday` = %i WHERE `id` = %i;', amount, time, self:getAccountId()))
            data.lastDay = time
        else
            db.query(string.format('UPDATE `accounts` SET `vipdays` = `vipdays` + %i WHERE `id` = %i;', amount, self:getAccountId()))
        end
        data.days = data.days + amount
    end

    return true
end

function Player.removeVipDays(self, amount)
    local data = VipData[self:getId()]
    if data.days == 0xFFFF then
        return false
    end

    local amount = math.min(data.days, amount)
    if amount > 0 then
        db.query(string.format('UPDATE `accounts` SET `vipdays` = `vipdays` - %i WHERE `id` = %i;', amount, self:getAccountId()))
        data.days = data.days - amount

        if data.days == 0 then
            self:onRemoveVip()
        end
    end

    return true
end

function Player.removeVip(self)
    local data = VipData[self:getId()]
    if data.days == 0 then
        return
    end

    data.days = 0
    data.lastDay = 0

    self:onRemoveVip()

    db.query(string.format('UPDATE `accounts` SET `vipdays` = 0, `viplastday` = 0 WHERE `id` = %i;', self:getAccountId()))
end

function Player.loadVipData(self)
    local resultId = db.storeQuery(string.format('SELECT `vipdays`, `viplastday` FROM `accounts` WHERE `id` = %i;', self:getAccountId()))
    if resultId then
        VipData[self:getId()] = {
            days = result.getDataInt(resultId, 'vipdays'),
            lastDay = result.getDataInt(resultId, 'viplastday')
        }

        result.free(resultId)
        return true
    end

    VipData[self:getId()] = { days = 0, lastDay = 0 }
    return false
end

function Player.updateVipTime(self)
    local save = false

    local data = VipData[self:getId()]
    local days, lastDay = data.days, data.lastDay
    local daysBefore = days
    if days == 0 or days == 0xFFFF then
        if lastDay ~= 0 then
            lastDay = 0
            save = true
        end
    elseif lastDay == 0 then
        lastDay = os.time()
        save = true
    else
        local time = os.time()
        local elapsedDays = math.floor((time - lastDay) / 86400)
        if elapsedDays > 0 then
            if elapsedDays >= days then
                days = 0
                lastDay = 0
            else
                days = days - elapsedDays
                lastDay = time - ((time - lastDay) % 86400)
            end
            save = true
        end
    end

    if save then
        if daysBefore > 0 and days == 0 then
            self:onRemoveVip()
        end

        db.query(string.format('UPDATE `accounts` SET `vipdays` = %i, `viplastday` = %i WHERE `id` = %i;', days, lastDay, self:getAccountId()))
        data.days = days
        data.lastDay = lastDay
    end
end
ites work for tfs 1.2?
 
Have problem CANARY server

[2022-18-04 21:11:20.927] [error] Lua script error:
scriptInterface: [Scripts Interface]
scriptId: [/home/canary/data/scripts/actions/vip/vipdoors.lua:callback]
timerEvent: []
callbackId:[]
function: []
error [data/lib/vip-system.lua:49: attempt to index a nil value
stack traceback:
[C]: in function '__index'
data/lib/vip-system.lua:49: in function 'getVipDays'
data/lib/vip-system.lua:57: in function 'isVip'
/home/canary/data/scripts/actions/vip/vipdoors.lua:29: in function </home/canary/data/scripts/actions/vip/vipdoors.lua:4>]

Lua:
local login = CreatureEvent("PlayerLogin")

function login.onLogin(player)
    player:loadVipData()
        player:updateVipTime()
    local loginStr = "Welcome to " .. configManager.getString(configKeys.SERVER_NAME) .. "!"
    if player:getLastLoginSaved() <= 0 then
        loginStr = loginStr .. " Please choose your outfit."
        player:sendOutfitWindow()
    else
        if loginStr ~= "" then
            player:sendTextMessage(MESSAGE_LOGIN, loginStr)
        end

        player:sendTextMessage(MESSAGE_LOGIN, string.format("Your last visit in ".. SERVER_NAME ..": %s.", os.date("%d. %b %Y %X", player:getLastLoginSaved())))
    end

    -- Stamina
    nextUseStaminaTime[player.uid] = 0

    -- Promotion
    local vocation = player:getVocation()
    local promotion = vocation:getPromotion()
    if player:isPremium() then
        local value = player:getStorageValue(Storage.Promotion)
        if not promotion and value ~= 1 then
            player:setStorageValue(STORAGEVALUE_PROMOTION, 1)
        elseif value == 1 then
            player:setVocation(promotion)
        end
    elseif not promotion then
        player:setVocation(vocation:getDemotion())
    end

    -- Events
    player:registerEvent("PlayerDeath")
    player:registerEvent("DropLoot")

    if onExerciseTraining[player:getId()] then -- onLogin & onLogout
        stopEvent(onExerciseTraining[player:getId()].event)
        onExerciseTraining[player:getId()] = nil
        player:setTraining(false)
    end
    return true
end

login:register()
 
Credits & Stuff
Credits go to @Printer for creating the original system (VIP System TFS [1.1] (http://otland.net/threads/vip-system-tfs-1-1.224758/)) upon which this system is based and which motivated me to work on it. Thanks for that.

This version uses a global variable to look up the current vip days of a player, so there is no need to use a mysql query each time you check if a player has vip status (which I assume is the most used function of the system).
I added support for infinite vip time and a talkaction for staff members.
If you miss any basic feature which might be helpful feel free to request it.
This version is supposed to work on The Forgotten Server 1.0 which you can download at Releases · otland/forgottenserver (https://github.com/otland/forgottenserver/releases).
I think I tested every case of the system if you however find any bugs / issues report them please or I might have messed up some copy & pasting.



System
MySQL queries
- execute those in your database
Code:
ALTER TABLE `accounts`
        ADD COLUMN `viplastday` int(10) NOT NULL DEFAULT 0 AFTER `lastday`,
        ADD COLUMN `vipdays` int(11) NOT NULL DEFAULT 0 AFTER `lastday`;

login.lua
  • this file is located in data/creaturescripts/scripts/ folder
  • add the following code after local player = Player(cid)
Code:
    player:loadVipData()
    player:updateVipTime()

global.lua
  • this file is located in data/ folder
  • add this code below dofile('data/compat.lua')
Code:
dofile('data/vip-system.lua')

vip-system.lua
  • create this file in your data folder
  • !Note: You have to adjust the following lines to your needs:
Code:
    -- true = player will be teleported to this position if Vip runs out
    -- false = player will not be teleported
    useTeleport = true,
    expirationPosition = Position(95, 114, 7),

    -- true = player will received the message you set
    -- false = player will not receive a message
    useMessage = true,
    expirationMessage = 'Your vip days ran out.',
    expirationMessageType = MESSAGE_STATUS_WARNING
- paste the following code in the newly created file
Code:
--[[

# Vip System for The Forgotten Server 1.0
# https://github.com/otland/forgottenserver/releases (1.0)

# Vip System by Summ
## Version v0.2
## Link: http://otland.net/threads/vip-system-the-forgotten-server-1-0.224910/

# Credits to Printer upon whose script this is based
## Link: http://otland.net/threads/vip-system-tfs-1-1.224758/

# MySQL query
    ALTER TABLE `accounts`
        ADD COLUMN `viplastday` int(10) NOT NULL DEFAULT 0 AFTER `lastday`,
        ADD COLUMN `vipdays` int(11) NOT NULL DEFAULT 0 AFTER `lastday`;

]]

local config = {
    -- true = player will be teleported to this position if Vip runs out
    -- false = player will not be teleported
    useTeleport = true,
    expirationPosition = Position(95, 114, 7),

    -- true = player will received the message you set
    -- false = player will not receive a message
    useMessage = true,
    expirationMessage = 'Your vip days ran out.',
    expirationMessageType = MESSAGE_STATUS_WARNING
}

if not VipData then
    VipData = { }
end

function Player.onRemoveVip(self)
    if config.useTeleport then
        self:teleportTo(config.expirationPosition)
        config.expirationPosition:sendMagicEffect(CONST_ME_TELEPORT)
    end

    if config.useMessage then
        self:sendTextMessage(config.expirationMessageType, config.expirationMessage)
    end
end

function Player.getVipDays(self)
    return VipData[self:getId()].days
end

function Player.getLastVipDay(self)
    return VipData[self:getId()].lastDay
end

function Player.isVip(self)
    return self:getVipDays() > 0
end

function Player.addInfiniteVip(self)
    local data = VipData[self:getId()]
    data.days = 0xFFFF
    data.lastDay = 0

    db.query(string.format('UPDATE `accounts` SET `vipdays` = %i, `viplastday` = %i WHERE `id` = %i;', 0xFFFF, 0, self:getAccountId()))
end

function Player.addVipDays(self, amount)
    local data = VipData[self:getId()]
    local amount = math.min(0xFFFE - data.days, amount)
    if amount > 0 then
        if data.days == 0 then
            local time = os.time()
            db.query(string.format('UPDATE `accounts` SET `vipdays` = `vipdays` + %i, `viplastday` = %i WHERE `id` = %i;', amount, time, self:getAccountId()))
            data.lastDay = time
        else
            db.query(string.format('UPDATE `accounts` SET `vipdays` = `vipdays` + %i WHERE `id` = %i;', amount, self:getAccountId()))
        end
        data.days = data.days + amount
    end

    return true
end

function Player.removeVipDays(self, amount)
    local data = VipData[self:getId()]
    if data.days == 0xFFFF then
        return false
    end

    local amount = math.min(data.days, amount)
    if amount > 0 then
        db.query(string.format('UPDATE `accounts` SET `vipdays` = `vipdays` - %i WHERE `id` = %i;', amount, self:getAccountId()))
        data.days = data.days - amount

        if data.days == 0 then
            self:onRemoveVip()
        end
    end

    return true
end

function Player.removeVip(self)
    local data = VipData[self:getId()]
    if data.days == 0 then
        return
    end

    data.days = 0
    data.lastDay = 0

    self:onRemoveVip()

    db.query(string.format('UPDATE `accounts` SET `vipdays` = 0, `viplastday` = 0 WHERE `id` = %i;', self:getAccountId()))
end

function Player.loadVipData(self)
    local resultId = db.storeQuery(string.format('SELECT `vipdays`, `viplastday` FROM `accounts` WHERE `id` = %i;', self:getAccountId()))
    if resultId then
        VipData[self:getId()] = {
            days = result.getDataInt(resultId, 'vipdays'),
            lastDay = result.getDataInt(resultId, 'viplastday')
        }

        result.free(resultId)
        return true
    end

    VipData[self:getId()] = { days = 0, lastDay = 0 }
    return false
end

function Player.updateVipTime(self)
    local save = false

    local data = VipData[self:getId()]
    local days, lastDay = data.days, data.lastDay
    local daysBefore = days
    if days == 0 or days == 0xFFFF then
        if lastDay ~= 0 then
            lastDay = 0
            save = true
        end
    elseif lastDay == 0 then
        lastDay = os.time()
        save = true
    else
        local time = os.time()
        local elapsedDays = math.floor((time - lastDay) / 86400)
        if elapsedDays > 0 then
            if elapsedDays >= days then
                days = 0
                lastDay = 0
            else
                days = days - elapsedDays
                lastDay = time - ((time - lastDay) % 86400)
            end
            save = true
        end
    end

    if save then
        if daysBefore > 0 and days == 0 then
            self:onRemoveVip()
        end

        db.query(string.format('UPDATE `accounts` SET `vipdays` = %i, `viplastday` = %i WHERE `id` = %i;', days, lastDay, self:getAccountId()))
        data.days = days
        data.lastDay = lastDay
    end
end
hello friends, I don't know if this is still supported but adding the tables to the database doesn't work for me, it presents me with this problem.
Post automatically merged:

thanks friend I had not seen your message, thanks for your help to the community
 

Attachments

Last edited:
I want an effect on the player can you help me create a script like this to work with your scripts

Lua:
<globalevent name="vipEffect" interval="5000" script="vipEffect.lua"/>
Code:
function onThink(interval, lastExecution)
         for _, name in ipairs(getOnlinePlayers()) do
         local cid = getPlayerByName(name)
               if getPlayerVipDays(cid) >= 1 then
                  doSendMagicEffect(getPlayerPosition(cid), 27)
                  doPlayerSetRate(cid, SKILL__LEVEL, 1)
                  doSendAnimatedText(getPlayerPosition(cid), "{VIP}", TEXTCOLOR_RED)
               end
         end
         return true
end
 
Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/checkvip.lua:eek:nSay
data/vip-system.lua:49: attempt to index a nil value
stack traceback:
[C]: in function '__index'
data/vip-system.lua:49: in function 'getVipDays'
data/talkactions/scripts/checkvip.lua:4: in function <data/talkactions/scripts/checkvip.lua:1>
I get this error 'getVipDays' in almost every scripts. Help
 
Did u guys copy it right?
add this to your database
Lua:
ALTER TABLE accounts ADD viplastday int(10) NOT NULL DEFAULT 0;
ALTER TABLE accounts ADD vipdays int(11) NOT NULL DEFAULT 0;
 
Back
Top