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

Canary RL 13.21 - Loyalty System (and other) questions - newbie needs experienced users' help

conman

New Member
Joined
Aug 4, 2023
Messages
13
Reaction score
1
Hello,

Few words of introduction- I have recently set up a Canary 13.21 RL map server. For now, as weird as it may sound, I am not planning on hosting the server. Instead I am trying to create a strong character to test a high level EK vs what modern Tibia has to offer- in a safe environment :)
I've had plenty of experience with XML servers years ago (and old Tibia in general, starting from 2002/2003) but I am a total newbie when it comes to these "big" servers, databases and so on.

So far I was able to very slowly figure some things out- I have created (through the database) a strong EK, gave it proper level, experience, HP/MP, cap... well, everything I could figure out.
Right now I am trying to sort the Loyalty System out.
So far I have found just few places in the database where the Loyalty system was mentioned.

loyalty_ranking under a character itself - set it to 10 (I figured out that would mean the Sage title) and the site indeed shows the character with a title of Sage of...

loyalty_points under account - set it to 7000
premdays; premdays_purchased under account - just show the same number, currently ~700, dont think I'd have to set it any higher, more later.


Problem: no matter what I change, when logging with that character (account) I get a message:

Due to your long-term loyalty to XXX Server you currently benefit from a 15% bonus on all of your skills. (You have 1395 loyalty points)

  • yesterday, first day of configuring the server, the number was 1394 so... it slowly goes up
  • I cannot find that number anywhere in the database, I don't know where it's stored and how it's counted
  • Title in-game says: You are a Squire of Tibia. That makes sense in accordance with the number ~1395

TLDR: I want my character to have a working Sage of XXX in-game, with a maximum skill bonus and correct informations displaying in-game and I have no idea how to sort that out


Since my message turned out to be quite long- while I have plenty of other questions- let's start with that one :)

Thanks in advance for anyone willing to help.
 
Please copy the values you have for the current character you are playing
database -> accounts:
premdays
premdays_purchased
lastday
creation

and that config values from ur config.lua
-- Loyalty system
loyaltyEnabled = true
loyaltyPointsPerCreationDay = 1
loyaltyPointsPerPremiumDaySpent = 0
loyaltyPointsPerPremiumDayPurchased = 0
loyaltyBonusPercentageMultiplier = 1.0
and release version ur canary engine
 
Last edited:
Hello, thank you for the reply. Here are the values:

premdays 725
premdays_purchased 725
lastday 1776196267
creation 1592969263


config.lua

loyaltyEnabled = true
loyaltyPointsPerCreationDay = 1
loyaltyPointsPerPremiumDaySpent = 0
loyaltyPointsPerPremiumDayPurchased = 0
loyaltyBonusPercentageMultiplier = 1.0

as for the version- how do I check it exactly?
 
Hello
Hello, thank you for the reply. Here are the values:

premdays 725
premdays_purchased 725
lastday 1776196267
creation 1592969263

config.lua
loyaltyEnabled = true
loyaltyPointsPerCreationDay = 1
loyaltyPointsPerPremiumDaySpent = 0
loyaltyPointsPerPremiumDayPurchased = 0
loyaltyBonusPercentageMultiplier = 1.0
iologindata_load_player.cpp
account.cpp

As you can see, it's all explained in the files above. Referring to your settings, you receive points for every day from the moment you create your account. You don't get additional points for premium time etc. because everything is set to zero.
creation 1592969263
This value is a TimeStamp (Wed Jun 24 2020 03:27:43 GMT+0000)
So, to put it simply, in your case the code works by subtracting the current date from the account creation date. (Both in timestamp of course)
Divide the result by 86400. Then multiply actual result by (loyaltyPointsPerCreationDay = 1) from your config.lua. (Then you can add points for premium days, but you don't use it)

Example (Paste and run that code on: Compiler):
C++:
#include <iostream>
#include <cmath>
#include <time.h>

int main() {
    time_t actualtimestamp = time(NULL);
    uint32_t creation = 1592969263;
    uint32_t loyaltyPointsPerCreationDay = 1;


    uint32_t loyaltyPoints = static_cast<uint32_t>(std::ceil((actualtimestamp - creation) / 86400)*loyaltyPointsPerCreationDay);
    std::cout << "OUTPUT: " << loyaltyPoints <<"\n\nDue to your long-term loyalty to XXX Server you currently benefit from a X% bonus on all of your skills. (You have "<< loyaltyPoints <<" loyalty points)";
}
This starting date is probably there for a reason, because every new player can enjoy the bonus from the very beginning of the game, not only after a year or two :)
If you want to increase this bonus, you need to set a different character creation date (timestamp)

as for the version- how do I check it exactly?
Judging by your topic, I would start using the original source CanaryMain, because if you don't know what version you have, it is probably not official, as there is no mention of loyalty_points in the sql database file. It may be a modified source and it may be more difficult for the person trying to help.
 
Thank you very much for your detailed help, I have lots to learn, hehe :)
But I indeed was able to make it work now.


If by any chance you'd be willing to help again, I am curious about where is the state of the quest log stored. Is there any possibility to, for example, make all quests completed on a particular character? Giving all the map access and so on? I imagine some rewards/ chests would be kinda "unclaimed" but because of a filled quest log the game would be treating the character as if they finished everything?


#EDIT

I have figured some things out, learned that talkactions > god is a very useful place to understand some of the commands better :) therefore I have deleted some part of this post

so for now my question remains about the possibility of interfering with the quest log- however, the more I am reading about it, about quest stages and so on... not sure if it's possible ;/
 
Last edited:
Thank you very much for your detailed help, I have lots to learn, hehe :)
But I indeed was able to make it work now.


If by any chance you'd be willing to help again, I am curious about where is the state of the quest log stored. Is there any possibility to, for example, make all quests completed on a particular character? Giving all the map access and so on? I imagine some rewards/ chests would be kinda "unclaimed" but because of a filled quest log the game would be treating the character as if they finished everything?


#EDIT

I have figured some things out, learned that talkactions > god is a very useful place to understand some of the commands better :) therefore I have deleted some part of this post

so for now my question remains about the possibility of interfering with the quest log- however, the more I am reading about it, about quest stages and so on... not sure if it's possible ;/
This is mostly a long process, of giving your character all the storage values they are missing.

You'd have to read through the quest log, and find the storage key and value required to 'complete' the quests.

Here's a small script you can throw into data/scripts, that will consume an item, and give you all the storage values listed.

You'll have to setup all the keys and values still, but it's easy and simple to add at least. lol

Lua:
local itemId = 11111  -- item you want to use to give storages to the character

local questStorages = {
    {key = 11111, value = 1},
    {key = 22222, value = 1},
    {key = 33333, value = 1}
}

local action = Action()

function action.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local removeItem = false
    for k, v in pairs(questStorages) do
        if player:getStorageValue(v.key) < v.value then
            player:setStorageValue(v.key, v.value)
            removeItem = true
        end
    end
    if removeItem then
        item:remove(1)
    end
    return true
end

action:id(itemId)
action:register()
 
Thanks for the response. I will have to look into that, for me all that is far from easy and clear, at least right now :D
 
Back
Top