Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: vip system #1063

Merged
merged 26 commits into from
Jul 29, 2023
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
e399345
Vip System: Created vip system functionality.
elsongabriel Mar 1, 2023
29c9386
Vip System: Validating vip days.
elsongabriel May 9, 2023
3b56e03
Vip System: Improved vip_manager.
github-actions[bot] May 21, 2023
e04a94f
Vip System: Created functionality to add an optional bonus to familia…
elsongabriel May 22, 2023
8073463
Vip System: adjusts in gamestore offers.
elsongabriel May 26, 2023
0a94efb
Vip System: updated configs, created max value to exp and bonus perce…
elsongabriel May 26, 2023
13b7be2
Vip System: updated configs and removed some validations unnecessary.
elsongabriel May 28, 2023
4a423c5
Vip System: update migrations and schema.
elsongabriel Jun 13, 2023
3de311b
Vip System: fixes math.floor.
elsongabriel Jun 13, 2023
c6e2b4b
Vip System: merge and update migrations.
elsongabriel Jul 27, 2023
9f9f22d
refactor from lua -> cpp, fix familiars, fix online points, simplify …
luan Jul 27, 2023
ccf686e
Update data/modules/scripts/gamestore/gamestore.lua
luan Jul 27, 2023
a5fdea3
Update data/modules/scripts/gamestore/gamestore.lua
luan Jul 27, 2023
68e3a07
Vip System: globalevents improvement.
elsongabriel Jul 27, 2023
72b1a38
Vip System: boosts improvements (check max 100% and code format).
elsongabriel Jul 27, 2023
ea142b3
Vip System: familiar improvements (var renamed and code format).
elsongabriel Jul 27, 2023
b5e717c
Vip System: talkactions improvements (removed script duplicated).
elsongabriel Jul 27, 2023
d4ef96e
Vip System: configs improvements (adjusted usage and removed old).
elsongabriel Jul 27, 2023
959e7db
Vip System: vip title on look.
elsongabriel Jul 27, 2023
eb72697
Code format - (Clang-format)
github-actions[bot] Jul 27, 2023
46d9ab3
Vip System: removed migration unused.
elsongabriel Jul 27, 2023
b25dd42
Vip System: removed code unused.
elsongabriel Jul 27, 2023
9f166b9
Vip System: fix reviewdog reported.
elsongabriel Jul 27, 2023
70701f5
Merge branch 'main' of https://github.com/elsongabriel/canary into fe…
elsongabriel Jul 28, 2023
2d20043
Vip System: vip_manager fix.
elsongabriel Jul 28, 2023
576b203
Update src/lua/functions/creatures/player/player_functions.cpp
dudantas Jul 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 20 additions & 0 deletions config.lua.dist
Original file line number Diff line number Diff line change
Expand Up @@ -415,3 +415,23 @@ location = "South America"
-- Leave empty if you wish to disable.
discordWebhookURL = ""

-- Vip System (Get more info in: https://github.com/opentibiabr/canary/pull/1063)
-- NOTE: set vipSystemEnabled to true to enable the vip system functionalities (this overrides premium checks)
-- NOTE: vipBonusExp = 0 is deactivated, active changing value between 1 and 100 (percent xp bonus to gain. ex: 3 = 3%, 30 = 30%)
-- NOTE: vipBonusLoot = 0 is deactivated, active changing value between 1 and 100 (percent loot bonus to gain. ex: 3 = 3%, 30 = 30%)
-- NOTE: vipBonusSkill = 0 is deactivated, active changing value between 1 and 100 (percent skill bonus to gain. ex: 3 = 3%, 30 = 30%)
-- NOTE: vipAutoLootVipOnly = activates only vip to get automatic loot, config 'autoLoot' need to be enabled, for this config works
-- NOTE: vipStayOnline = when this config is activated, players vip will be kicked after 'kickIdlePlayerAfterMinutes' config minutes too
-- NOTE: vipFamiliarTimeCooldownReduction = the minutes that will be debited from the familiar time cooldown for vip accounts, use 0 to deactivate the bonus (the default maximum value is 15, but it is calculated automatically)
-- examples: The default config 'familiarTime' is 30, this value is divided by 2 (15 minutes familiar and 15 minutes to cooldown)
-- If you use 'vipFamiliarTimeCooldownReduction = 10' the vip players will have only, in this case, 5 minutes of cooldown.
-- If you use 'vipFamiliarTimeCooldownReduction' greater than half of 'familiarTime', it will get the highest possible value, in this case 15
-- NOTE: GainCoin function, please configure script: data-otservbr-global/scripts/globalevents/vip/online_coins.lua
-- NOTE: GainToken function, please configure script: data-otservbr-global/scripts/globalevents/vip/online_tokens.lua
vipSystemEnabled = false
vipBonusExp = 0
vipBonusLoot = 0
vipBonusSkill = 0
vipAutoLootVipOnly = false
vipStayOnline = false
vipFamiliarTimeCooldownReduction = 0
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_AUTOLOOT_VIP_ONLY) 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()
6 changes: 6 additions & 0 deletions data-otservbr-global/lib/core/storages.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2989,6 +2989,12 @@ Storage = {
LastActivatedAt = 64039,
},
},

VipSystem = {
IsVip = 150001,
OnlineCoinsGain = 150002,
OnlineTokensGain = 150003,
},
}

GlobalStorage = {
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')
50 changes: 50 additions & 0 deletions data-otservbr-global/lib/vip/vip_system.lua
elsongabriel marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
local config = {
activationMessage = 'You have received %s VIP days.',
activationMessageType = MESSAGE_EVENT_ADVANCE,

expirationMessage = 'Your VIP days ran out.',
expirationMessageType = MESSAGE_STATUS_WARNING,

outfits = {},
mounts = {},
}

function Player.onRemoveVip(self)
self:sendTextMessage(config.expirationMessageType, config.expirationMessage)

for _, outfit in ipairs(config.outfits) do
self:removeOutfit(outfit)
end

for _, mount in ipairs(config.mounts) do
self:removeMount(mount)
end

local playerOutfit = self:getOutfit()
if table.contains(config.outfits, self:getOutfit().lookType) then
if self:getSex() == PLAYERSEX_FEMALE then
playerOutfit.lookType = 136
else
playerOutfit.lookType = 128
end
playerOutfit.lookAddons = 0
self:setOutfit(playerOutfit)
end

self:setStorageValue(Storage.VipSystem.IsVip, 0)
end

function Player.onAddVip(self, days)
self:sendTextMessage(config.activationMessageType, string.format(config.activationMessage, days))

for _, outfit in ipairs(config.outfits) do
self:addOutfitAddon(outfit, 3)
end

for _, mount in ipairs(config.mounts) do
self:removeMount(mount)
end

self:setStorageValue(Storage.VipSystem.IsVip, 1)
end

10 changes: 9 additions & 1 deletion data-otservbr-global/migrations/33.lua
elsongabriel marked this conversation as resolved.
Show resolved Hide resolved
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 34 (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/34.lua
elsongabriel marked this conversation as resolved.
Show resolved Hide resolved
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
16 changes: 16 additions & 0 deletions data-otservbr-global/scripts/creaturescripts/customs/vip.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
local playerLogin = CreatureEvent("VipLogin")

function playerLogin.onLogin(player)
if configManager.getBoolean(configKeys.VIP_SYSTEM_ENABLED) then
local wasVip = player:getStorageValue(Storage.VipSystem.IsVip) == 1
if wasVip and not player:isVip() then player:onRemoveVip() end
if not wasVip and player:isVip() then player:onAddVip(player:getVipDays()) end
if 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
return true
end

playerLogin:register()
64 changes: 35 additions & 29 deletions data-otservbr-global/scripts/creaturescripts/others/login.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ local function onMovementRemoveProtection(cid, oldPos, time)
end

local function protectionZoneCheck(playerName)
doRemoveCreature(playerName)
return true
doRemoveCreature(playerName)
elsongabriel marked this conversation as resolved.
Show resolved Hide resolved
return true
end

local playerLogin = CreatureEvent("PlayerLogin")

function playerLogin.onLogin(player)
local items = {
{3003, 1},
{3031, 3}
{ 3003, 1 },
{ 3031, 3 }
}
if player:getLastLoginSaved() == 0 then
player:sendOutfitWindow()
Expand All @@ -34,17 +34,22 @@ function playerLogin.onLogin(player)
end
end
player:addItem(2920, 1, true, 1, CONST_SLOT_AMMO)
db.query('UPDATE `players` SET `istutorial` = 0 where `id`='..player:getGuid())
db.query('UPDATE `players` SET `istutorial` = 0 where `id`=' .. player:getGuid())
-- Open channels
if table.contains({TOWNS_LIST.DAWNPORT, TOWNS_LIST.DAWNPORT_TUTORIAL}, player:getTown():getId())then
if table.contains({ TOWNS_LIST.DAWNPORT, TOWNS_LIST.DAWNPORT_TUTORIAL }, player:getTown():getId()) then
player:openChannel(3) -- World chat
else
player:openChannel(3) -- World chat
player:openChannel(5) -- Advertsing main
end
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())))
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')))
elsongabriel marked this conversation as resolved.
Show resolved Hide resolved
end
end

-- Reset bosstiary time
Expand All @@ -58,7 +63,7 @@ function playerLogin.onLogin(player)
end
-- Premium Ends Teleport to Temple, change addon (citizen) houseless
local defaultTown = "Thais" -- default town where player is teleported if his home town is in premium area
local freeTowns = {"Ab'Dendriel", "Carlin", "Kazordoon", "Thais", "Venore", "Rookgaard", "Dawnport", "Dawnport Tutorial", "Island of Destiny"} -- towns in free account area
local freeTowns = { "Ab'Dendriel", "Carlin", "Kazordoon", "Thais", "Venore", "Rookgaard", "Dawnport", "Dawnport Tutorial", "Island of Destiny" } -- towns in free account area

if isPremium(player) == false and isInArray(freeTowns, player:getTown():getName()) == false then
local town = player:getTown()
Expand All @@ -70,20 +75,20 @@ function playerLogin.onLogin(player)
player:sendTextMessage(MESSAGE_FAILURE, "Your premium time has expired.")
player:setStorageValue(Storage.PremiumAccount, 0)
if sex == 1 then
player:setOutfit({lookType = 128, lookFeet = 114, lookLegs = 134, lookHead = 114,lookAddons = 0})
elseif sex == 0 then
player:setOutfit({lookType = 136, lookFeet = 114, lookLegs = 134, lookHead = 114, lookAddons = 0})
end
if home ~= nil and not isPremium(player) then
setHouseOwner(home, 0)
player:sendTextMessage(MESSAGE_GAME_HIGHLIGHT, 'You\'ve lost your house because you are not premium anymore.')
player:setOutfit({ lookType = 128, lookFeet = 114, lookLegs = 134, lookHead = 114, lookAddons = 0 })
elseif sex == 0 then
player:setOutfit({ lookType = 136, lookFeet = 114, lookLegs = 134, lookHead = 114, lookAddons = 0 })
end
if home ~= nil and not isPremium(player) then
setHouseOwner(home, 0)
player:sendTextMessage(MESSAGE_GAME_HIGHLIGHT, 'You\'ve lost your house because you are not premium anymore.')
player:sendTextMessage(MESSAGE_GAME_HIGHLIGHT, 'Your items from house are send to your inbox.')
end
end
end
-- End 'Premium Ends Teleport to Temple'

-- Recruiter system
local resultId = db.storeQuery('SELECT `recruiter` from `accounts` where `id`='..getAccountNumberByPlayerName(getPlayerName(player)))
local resultId = db.storeQuery('SELECT `recruiter` from `accounts` where `id`=' .. getAccountNumberByPlayerName(getPlayerName(player)))
local recruiterStatus = Result.getNumber(resultId, 'recruiter')
local sex = player:getSex()
if recruiterStatus >= 1 then
Expand All @@ -101,27 +106,27 @@ function playerLogin.onLogin(player)
end
if recruiterStatus >= 3 then
if sex == 1 then
local outfit = player:hasOutfit(746,1)
local outfit = player:hasOutfit(746, 1)
if outfit == false then
player:addOutfitAddon(746,1)
player:addOutfitAddon(746, 1)
end
else
local outfit = player:hasOutfit(745,1)
local outfit = player:hasOutfit(745, 1)
if outfit == false then
player:addOutfit(745,1)
player:addOutfit(745, 1)
end
end
end
if recruiterStatus >= 10 then
if sex == 1 then
local outfit = player:hasOutfit(746,2)
local outfit = player:hasOutfit(746, 2)
if outfit == false then
player:addOutfitAddon(746,2)
player:addOutfitAddon(746, 2)
end
else
local outfit = player:hasOutfit(745,2)
local outfit = player:hasOutfit(745, 2)
if outfit == false then
player:addOutfit(745,2)
player:addOutfit(745, 2)
end
end
end
Expand Down Expand Up @@ -195,7 +200,7 @@ function playerLogin.onLogin(player)
nextUseConcoctionTime[playerId] = 1

if (player:getAccountType() == ACCOUNT_TYPE_TUTOR) then
local msg = [[:: Tutor Rules
local msg = [[:: Tutor Rules
1 *> 3 Warnings you lose the job.
2 *> Without parallel conversations with players in Help, if the player starts offending, you simply mute it.
3 *> Be educated with the players in Help and especially in the Private, try to help as much as possible.
Expand All @@ -218,9 +223,9 @@ function playerLogin.onLogin(player)

-- Rewards
local rewards = #player:getRewardList()
if(rewards > 0) then
if (rewards > 0) then
player:sendTextMessage(MESSAGE_LOGIN, string.format("You have %d %s in your reward chest.",
rewards, rewards > 1 and "rewards" or "reward"))
rewards, rewards > 1 and "rewards" or "reward"))
end

-- Update player id
Expand All @@ -245,7 +250,8 @@ function playerLogin.onLogin(player)

player:getFinalLowLevelBonus()

if onExerciseTraining[player:getId()] then -- onLogin & onLogout
if onExerciseTraining[player:getId()] then
-- onLogin & onLogout
stopEvent(onExerciseTraining[player:getId()].event)
onExerciseTraining[player:getId()] = nil
player:setTraining(false)
Expand Down
60 changes: 60 additions & 0 deletions data-otservbr-global/scripts/globalevents/vip/online_coins.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
local config = {
enabled = false,
storage = Storage.VipSystem.OnlineCoinsGain,
checkDuplicateIps = false,

interval = 60 * 1000,

-- per hour | system will calculate how many coins will be given and when
-- put 0 in coinsPerHour.free to disable free from receiving coins
coinsPerHour = {
free = 1,
vip = 5,
},

-- system will distribute when the player accumulate x coins
awardOn = 5,
}

local onlineCoinsEvent = GlobalEvent("GainCoinInterval")
local runsPerHour = 3600 / (config.interval / 1000)

local function coinsPerRun(coinsPerHour)
return coinsPerHour / runsPerHour
end

function onlineCoinsEvent.onThink(interval)
local players = Game.getPlayers()
if #players == 0 then
return true
end

local checkIp = {}
for _, player in pairs(players) do
if player:getAccountType() >= ACCOUNT_TYPE_GAMEMASTER then
goto continue
end

local ip = player:getIp()
if ip ~= 0 and (not config.checkDuplicateIps or not checkIp[ip]) then
checkIp[ip] = true
local remainder = math.max(0, player:getStorageValue(config.storage)) / 10000000
local coins = coinsPerRun(player:isVip() and config.coinsPerHour.vip or config.coinsPerHour.free) + remainder
player:setStorageValue(config.storage, coins * 10000000)
if coins >= config.awardOn then
local coinsMath = math.floor(coins)
player:addTibiaCoins(coinsMath, true)
player:sendTextMessage(MESSAGE_STATUS_SMALL, string.format("Congratulations %s!\z You have received %d %s for being online.", player:getName(), coinsMath, "tibia coins"))
player:setStorageValue(config.storage, (coins - coinsMath) * 10000000)
end
end

:: continue ::
end
return true
end

if config.enabled then
onlineCoinsEvent:interval(config.interval)
onlineCoinsEvent:register()
end