Skip to content

Commit

Permalink
Vip System: Created vip system functionality.
Browse files Browse the repository at this point in the history
- Created functions on login;
- Adjusted store checking to sell vip or premium;
- Reordered storages;
- Created configs and scripts;
- Created validation to autoloot flag enabled by each player;
- Improved validations of autoloot and showing messages about VIP on look players;
  • Loading branch information
elsongabriel committed May 6, 2023
1 parent 2f4dd4b commit e271b74
Show file tree
Hide file tree
Showing 29 changed files with 718 additions and 98 deletions.
17 changes: 17 additions & 0 deletions config.lua.dist
Original file line number Diff line number Diff line change
Expand Up @@ -348,3 +348,20 @@ location = "South America"
-- Leave empty if you wish to disable.
discordWebhookURL = ""

-- Vip System
-- NOTE: set vipSystemEnabled to true to enable the vip system functionality.
-- NOTE: vipSystemExpEnabled = activates accounts vip to win a bonus of xp.
-- NOTE: vipSystemExpPercent = the percent bonus to win. ex: 3 = 3%, 30 = 30%
-- NOTE: vipSystemLootEnabled = activates accounts vip to win a bonus of loot.
-- NOTE: vipSystemLootPercent = the percent bonus to win. ex: 3 = 3%, 30 = 30%
-- NOTE: vipSystemGainCoinsEnabled before active, please configure script: data-otservbr-global\scripts\globalevents\online_vip_coins.lua
-- NOTE: vipSystemGainTokensEnabled before active, please configure script: data-otservbr-global\scripts\globalevents\online_tokens.lua
-- NOTE: vipSystemAutoLootOnlyVip = activates only vip to get automatic loot, config 'autoLoot' need to be enabled, for this config works
vipSystemEnabled = false
vipSystemExpEnabled = false
vipSystemExpPercent = 3
vipSystemLootEnabled = false
vipSystemLootPercent = 3
vipSystemGainCoinsEnabled = false
vipSystemGainTokensEnabled = false
vipSystemAutoLootOnlyVip = false
27 changes: 27 additions & 0 deletions data-canary/scripts/talkactions/player/auto_loot.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
local autoLoot = TalkAction("!autoloot")

function autoLoot.onSay(player, words, param)
if not configManager.getBoolean(configKeys.AUTOLOOT) then
return false
end
if (configManager.getBoolean(configKeys.VIP_SYSTEM_ENABLED) and
configManager.getBoolean(configKeys.VIP_SYSTEM_AUTO_LOOT_ONLY_VIP) and not player:isVip()) then
player:sendCancelMessage("You need to be VIP to use this command!")
return false
end
if param == "" then
player:sendCancelMessage("You need to specify on/off param.")
return false
end
if param == "on" then
player:setStorageValue(STORAGEVALUE_AUTO_LOOT, 1)
player:sendTextMessage(MESSAGE_INFO_DESCR, "You have successfully enabled your automatic looting!")
elseif param == "off" then
player:setStorageValue(STORAGEVALUE_AUTO_LOOT, 0)
player:sendTextMessage(MESSAGE_INFO_DESCR, "You have successfully disabled your automatic looting!")
end
return true
end

autoLoot:separator(" ")
autoLoot:register()
7 changes: 6 additions & 1 deletion data-otservbr-global/lib/core/storages.lua
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,12 @@ Storage = {
PremiumAccount = 30058,
BattleAxeQuest = 30059,
ShrineEntrance = 30060,

VipSystem = {
-- Vip System Storages
GainTibiaCoins = 30061,
GainTokens = 30062,
AutoLoot = 30063
},
--[[
Old storages
Over time, this will be dropped and replaced by the table above
Expand Down
3 changes: 3 additions & 0 deletions data-otservbr-global/lib/lib.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ dofile(DATA_DIRECTORY .. '/lib/others/load.lua')

-- Quests library
dofile(DATA_DIRECTORY .. '/lib/quests/quest.lua')

-- Vip System library
dofile(DATA_DIRECTORY .. '/lib/vip/vip_system.lua')
206 changes: 206 additions & 0 deletions data-otservbr-global/lib/vip/vip_system.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
local config = {
-- true = para o player ser teleportado após o termino da vip
-- false = para o player não ser teleportado
useTeleport = true,
-- posição para onde o player ira ser teleportado
expirationPosition = Position(32369, 32241, 7),

-- true = para o player receber a mensagem de termino
-- false = para o player nao receber a mensagem
useMessage = true,
expirationMessage = 'Your vip days ran out.',
expirationMessageType = MESSAGE_STATUS_WARNING,

-- remover todos os addons e mounts vips, após o termino da vip
removeAddonsAndMounts = true
}

if not VipData then
VipData = { }
end

function Player.onRemoveVip(self)

if config.useTeleport then
self:teleportTo(config.expirationPosition)
self:setDirection(SOUTH)
config.expirationPosition:sendMagicEffect(CONST_ME_TELEPORT)
end

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

if config.removeAddonsAndMounts then
local outfitsToDelete = { 963, 965, 967, 969, 971, 973, 975, 962, 964, 966, 968, 970, 972, 974 } -- retro outfits ids
for i = 1, #outfitsToDelete do
self:removeOutfit(outfitsToDelete[i])
end

local mountsToDelete = { 168, 169, 170 } -- mounts id
for i = 1, #mountsToDelete do
self:removeMount(mountsToDelete[i])
end
end

local currentSex = self:getSex()
local playerOutfit = self:getOutfit()

playerOutfit.lookAddons = 0
if currentSex == PLAYERSEX_FEMALE then
playerOutfit.lookType = 136
else
playerOutfit.lookType = 128
end
self:setOutfit(playerOutfit)

end

function Player.addAddonMount(self)

local outfitsToUpgrade = { 963, 965, 967, 969, 971, 973, 975, 962, 964, 966, 968, 970, 972, 974 } -- add outfits ids
local mountsToUpgrade = { 168, 169, 170 } -- add mounts ids

if self:getVipDays() > 0 then
for i = 1, #outfitsToUpgrade do
local outfit = self:hasOutfit(outfitsToUpgrade[i], 3)
if outfit == false then
self:addOutfitAddon(outfitsToUpgrade[i], 3)
end
end
for i = 1, #mountsToUpgrade do
local outfit = self:hasMount(mountsToUpgrade[i])
if outfit == false then
self:addMount(mountsToUpgrade[i])
end
end
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, days)
local data = VipData[self:getId()]
if data.days == 0xFFFF or days <= 0 then
return false
end

if data.days == 0 then
data.lastDay = os.time() + (days * 24 * 60 * 60)
else
data.lastDay = data.lastDay + (days * 24 * 60 * 60)
end
data.days = data.days + days

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

return true
end

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

if (days > data.days) then
days = data.days
end
data.lastDay = data.lastDay - (days * 24 * 60 * 60)
data.days = data.days - days

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

if data.days == 0 then
self:onRemoveVip()
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
days = 0
save = true
else
local time = os.time()
local daysLeft = math.floor((lastDay - time) / 86400)
local timeLeft = math.floor((lastDay - time) % 86400)
if daysLeft > 0 then
days = daysLeft
elseif daysLeft == 0 and timeLeft > 0 then
days = 1
else
days = 0
lastDay = 0
end
save = true
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
10 changes: 9 additions & 1 deletion data-otservbr-global/migrations/28.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
function onUpdateDatabase()
return false -- true = There are others migrations file | false = this is the last migration file
Spdlog.info("Updating database to version 29 (create vip system columns)")
db.query(
[[
ALTER TABLE `accounts`
ADD COLUMN `vipdays` int(11) NOT NULL DEFAULT 0 AFTER `lastday`,
ADD COLUMN `viplastday` int(10) NOT NULL DEFAULT 0 AFTER `vipdays`;
]]
)
return true
end
3 changes: 3 additions & 0 deletions data-otservbr-global/migrations/29.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function onUpdateDatabase()
return false -- true = There are others migrations file | false = this is the last migration file
end
13 changes: 13 additions & 0 deletions data-otservbr-global/scripts/creaturescripts/others/login.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ end
local playerLogin = CreatureEvent("PlayerLogin")

function playerLogin.onLogin(player)

if configManager.getBoolean(configKeys.VIP_SYSTEM_ENABLED) then
-- Vip system functions
player:loadVipData()
player:updateVipTime()
player:addAddonMount()
end

local items = {
{3003, 1},
{3031, 3}
Expand All @@ -45,6 +53,11 @@ function playerLogin.onLogin(player)
else
player:sendTextMessage(MESSAGE_STATUS, SERVER_MOTD)
player:sendTextMessage(MESSAGE_LOGIN, string.format("Your last visit in ".. SERVER_NAME ..": %s.", os.date("%d. %b %Y %X", player:getLastLoginSaved())))
-- Vip system
if (configManager.getBoolean(configKeys.VIP_SYSTEM_ENABLED) and player:isVip()) then
local days = player:getVipDays()
player:sendTextMessage(MESSAGE_LOGIN, string.format('You have %s vip day%s left.', (days == 0xFFFF and 'infinite amount of' or days), (days == 1 and '' or 's')))
end
end

-- Reset bosstiary time
Expand Down
54 changes: 54 additions & 0 deletions data-otservbr-global/scripts/globalevents/online_tokens.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
local config = {
storage = tonumber(Storage.VipSystem.GainTokens),
checkDuplicateIps = true,
tokenItemId = 14112, -- bar of gold
tokensPerHour = 2, -- amount of tokens, players free will win
tokensPerHourVip = 5 -- amount of tokens, players vip will win
}

local onlineTokensEvent = GlobalEvent("GainTokenPerHour")

function onlineTokensEvent.onThink(interval)
if (not configManager.getBoolean(configKeys.VIP_SYSTEM_ENABLED)
or not configManager.getBoolean(configKeys.VIP_SYSTEM_GAIN_TOKENS_ENABLED)) then
return false
end

local players = Game.getPlayers()
if #players == 0 then
return true
end

local checkIp = {}
for _, player in pairs(players) do
local ip = player:getIp()
if ip ~= 0 and (not config.checkDuplicateIps or not checkIp[ip]) then
checkIp[ip] = true
local seconds = math.max(0, player:getStorageValue(config.storage))
if seconds >= 3600 then

if player:getAccountType() >= ACCOUNT_TYPE_GAMEMASTER then
return true
end

local tokensToWin = (player:isVip() and config.tokensPerHourVip) or config.tokensPerHour
if tokensToWin > 0 then
player:setStorageValue(config.storage, 0)
local item = player:addItem(config.tokenItemId, tokensToWin)
if item then
player:sendTextMessage(MESSAGE_EVENT_DEFAULT,
string.format("Congratulations %s!\z You have received %d %s for being online%s.", player:getName(), tokensToWin, "tokens", (player:isVip() and " and being VIP") or "")
)
end
end

return true
end
player:setStorageValue(config.storage, seconds + math.ceil(interval / 1000))
end
end
return true
end

onlineTokensEvent:interval(10000)
onlineTokensEvent:register()

0 comments on commit e271b74

Please sign in to comment.