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

C++ [OTHire 1.0] Adding new skills - [Solved]

cleaso

New Member
Joined
Feb 29, 2020
Messages
7
Reaction score
3
Hello community, I've been using OTHire for a 7.72 version:
OTHire - Github

So, I'm trying to add a new skill called Cooking

So far I've modified the source/
condition.cpp
C++:
case CONDITIONPARAM_SKILL_FISHING:
{
    skills[SKILL_FISH] = value;
    return true;
}

case CONDITIONPARAM_SKILL_FISHINGPERCENT:
{
    skillsPercent[SKILL_FISH] = value;
    return true;
}

case CONDITIONPARAM_SKILL_COOKING:
{
    skills[SKILL_COOK] = value;
    return true;
}

case CONDITIONPARAM_SKILL_COOKINGPERCENT:
{
    skillsPercent[SKILL_COOK] = value;
    return true;
}

enums.h
C++:
enum ConditionParam_t{
...
    CONDITIONPARAM_SKILL_MELEEPERCENT = 36,
    CONDITIONPARAM_SKILL_FISTPERCENT = 37,
    CONDITIONPARAM_SKILL_CLUBPERCENT = 38,
    CONDITIONPARAM_SKILL_SWORDPERCENT = 39,
    CONDITIONPARAM_SKILL_AXEPERCENT = 40,
    CONDITIONPARAM_SKILL_DISTANCEPERCENT = 41,
    CONDITIONPARAM_SKILL_SHIELDPERCENT = 42,
    CONDITIONPARAM_SKILL_FISHINGPERCENT = 43,
    CONDITIONPARAM_BUFF_SPELL = 44,
    CONDITIONPARAM_SUBID = 45,
    CONDITIONPARAM_SKILL_COOKING = 46,
    CONDITIONPARAM_SKILL_COOKINGPERCENT = 47
};


enum levelTypes_t {
    LEVEL_FIRST = 0,
    LEVEL_SKILL_FIST = LEVEL_FIRST,
    LEVEL_SKILL_CLUB = 1,
    LEVEL_SKILL_SWORD = 2,
    LEVEL_SKILL_AXE = 3,
    LEVEL_SKILL_DIST = 4,
    LEVEL_SKILL_SHIELD = 5,
    LEVEL_SKILL_FISH = 6,
    LEVEL_SKILL_COOK = 7,
    LEVEL_MAGIC = 8,
    LEVEL_EXPERIENCE = 9,
    LEVEL_LAST = LEVEL_EXPERIENCE
};

enum skills_t {
    SKILL_FIRST = 0,
    SKILL_FIST = SKILL_FIRST,
    SKILL_CLUB = 1,
    SKILL_SWORD = 2,
    SKILL_AXE = 3,
    SKILL_DIST = 4,
    SKILL_SHIELD = 5,
    SKILL_FISH = 6,
    SKILL_COOK = 7,
    SKILL_LAST = SKILL_COOK
};

monsters.cpp
C++:
else if(readXMLInteger(node, "fishing", intValue) || readXMLInteger(node, "fish", intValue)){
    param = CONDITIONPARAM_SKILL_FISHING;
}
else if(readXMLInteger(node, "cooking", intValue) || readXMLInteger(node, "cook", intValue)){
    param = CONDITIONPARAM_SKILL_COOKING;
}

player.cpp
C++:
std::string Player::getSkillName(int skillid)
{
    std::string skillname;
    switch(skillid){
    case SKILL_FIST:
        skillname = "fist fighting";
        break;
    case SKILL_CLUB:
        skillname = "club fighting";
        break;
    case SKILL_SWORD:
        skillname = "sword fighting";
        break;
    case SKILL_AXE:
        skillname = "axe fighting";
        break;
    case SKILL_DIST:
        skillname = "distance fighting";
        break;
    case SKILL_SHIELD:
        skillname = "shielding";
        break;
    case SKILL_FISH:
        skillname = "fishing";
        break;
    case SKILL_COOK:
        skillname = "cooking";
        break;
    default:
        skillname = "unknown";
        break;
    }
    return skillname;
}

protocolgame.cpp
C++:
void ProtocolGame::AddPlayerSkills(NetworkMessage_ptr msg)
{
    msg->AddByte(0xA1);
    msg->AddByte(player->getSkill(SKILL_FIST,   SKILL_LEVEL));
    msg->AddByte(player->getSkill(SKILL_FIST,   SKILL_PERCENT));
    msg->AddByte(player->getSkill(SKILL_CLUB,   SKILL_LEVEL));
    msg->AddByte(player->getSkill(SKILL_CLUB,   SKILL_PERCENT));
    msg->AddByte(player->getSkill(SKILL_SWORD,  SKILL_LEVEL));
    msg->AddByte(player->getSkill(SKILL_SWORD,  SKILL_PERCENT));
    msg->AddByte(player->getSkill(SKILL_AXE,    SKILL_LEVEL));
    msg->AddByte(player->getSkill(SKILL_AXE,    SKILL_PERCENT));
    msg->AddByte(player->getSkill(SKILL_DIST,   SKILL_LEVEL));
    msg->AddByte(player->getSkill(SKILL_DIST,   SKILL_PERCENT));
    msg->AddByte(player->getSkill(SKILL_SHIELD, SKILL_LEVEL));
    msg->AddByte(player->getSkill(SKILL_SHIELD, SKILL_PERCENT));
    msg->AddByte(player->getSkill(SKILL_FISH,   SKILL_LEVEL));
    msg->AddByte(player->getSkill(SKILL_FISH,   SKILL_PERCENT));
    msg->AddByte(player->getSkill(SKILL_COOK,   SKILL_LEVEL));
    msg->AddByte(player->getSkill(SKILL_COOK,   SKILL_PERCENT));
}

items.cpp
C++:
else if(asLowerCaseString(strValue) == "skillfish"){
    if(readXMLInteger(itemAttributesNode, "value", intValue)){
        it.abilities.skill.upgrades[SKILL_FISH] = intValue;
    }
}
else if(asLowerCaseString(strValue) == "skillcook"){
    if(readXMLInteger(itemAttributesNode, "value", intValue)){
        it.abilities.skill.upgrades[SKILL_COOK] = intValue;
    }
}

vocation.cpp
C++:
skillMultipliers[6] = 1.1f;
skillMultipliers[7] = 1.1f;


skillBases[6] = 20;
skillBases[7] = 20;

Now on the server data/

global.lua
Lua:
LEVEL_SKILL_FIST = 0
LEVEL_SKILL_CLUB = 1
LEVEL_SKILL_SWORD = 2
LEVEL_SKILL_AXE = 3
LEVEL_SKILL_DISTANCE = 4
LEVEL_SKILL_SHIELDING = 5
LEVEL_SKILL_FISHING = 6
LEVEL_SKILL_COOKING = 7
LEVEL_MAGIC = 8
LEVEL_EXPERIENCE = 9

CONST_SKILL_FIST = 0
CONST_SKILL_CLUB = 1
CONST_SKILL_SWORD = 2
CONST_SKILL_AXE = 3
CONST_SKILL_DISTANCE = 4
CONST_SKILL_SHIELDING = 5
CONST_SKILL_FISHING = 6
CONST_SKILL_COOKING = 7

vocations.xml
XML:
<skill id="7" base="20" multiplier="1.1"/>

Created an action script for cooking raw fish into cooked fish:

cooking.lua
Lua:
local ITEM_RAW_FISH = 2667
local ITEM_COOKED FISH = 5135


function onUse(cid, item, fromPosition, itemEx, toPosition)

local formula = (getPlayerSkill(cid, CONST_SKILL_COOKING) / 200) + (0.85 * math.random())
    if(item.itemid == 2667 and isInArray(OVEN_ON, itemEx.itemid) == true) then
        doPlayerAddItem(cid, 5135)
        doRemoveItem(item.uid, 1)
        doPlayerAddSkillTry(cid, CONST_SKILL_COOKING, 1)
        return true
    end
 
    return false
end

Also, I've changed the sql schema to allow all new characters to have this new skill
schema.sql
PHP:
-- Triggers `players`
--
DROP TRIGGER IF EXISTS `oncreate_players`;
DELIMITER //
CREATE TRIGGER `oncreate_players` AFTER INSERT ON `players`
 FOR EACH ROW BEGIN
    INSERT INTO `player_skills` (`player_id`, `skillid`, `value`) VALUES (NEW.`id`, 0, 10);
    INSERT INTO `player_skills` (`player_id`, `skillid`, `value`) VALUES (NEW.`id`, 1, 10);
    INSERT INTO `player_skills` (`player_id`, `skillid`, `value`) VALUES (NEW.`id`, 2, 10);
    INSERT INTO `player_skills` (`player_id`, `skillid`, `value`) VALUES (NEW.`id`, 3, 10);
    INSERT INTO `player_skills` (`player_id`, `skillid`, `value`) VALUES (NEW.`id`, 4, 10);
    INSERT INTO `player_skills` (`player_id`, `skillid`, `value`) VALUES (NEW.`id`, 5, 10);
    INSERT INTO `player_skills` (`player_id`, `skillid`, `value`) VALUES (NEW.`id`, 6, 10);
    INSERT INTO `player_skills` (`player_id`, `skillid`, `value`) VALUES (NEW.`id`, 7, 10);
END

So far so good, everything works as intended:
tibia_cooking.png

But when I logout, seems the skill advance and the count tries are not being registered at the database player_skills:
View attachment 76494
And I'm back at cooking level 10, even if I modify the D.B. manually with some counts (1) it will load them at the front-end.
View attachment 76496
View attachment 76495
Any guess on what's going on, why is it not sending the tries?

Greatly appreciated if anyone could take a look, thanks.
 
Last edited:
in enums.h

Lua:
enum skills_t {
    SKILL_FIRST = 0,
    SKILL_FIST = SKILL_FIRST,
    SKILL_CLUB = 1,
    SKILL_SWORD = 2,
    SKILL_AXE = 3,
    SKILL_DIST = 4,
    SKILL_SHIELD = 5,
    SKILL_FISH = 6,
    SKILL_LAST = SKILL_FISH
};

add cooking here.
 
in enums.h

Lua:
enum skills_t {
    SKILL_FIRST = 0,
    SKILL_FIST = SKILL_FIRST,
    SKILL_CLUB = 1,
    SKILL_SWORD = 2,
    SKILL_AXE = 3,
    SKILL_DIST = 4,
    SKILL_SHIELD = 5,
    SKILL_FISH = 6,
    SKILL_LAST = SKILL_FISH
};

add cooking here.
True, forgot to add that part of the code but it's already there, editing the post.

C++:
enum skills_t {
    SKILL_FIRST = 0,
    SKILL_FIST = SKILL_FIRST,
    SKILL_CLUB = 1,
    SKILL_SWORD = 2,
    SKILL_AXE = 3,
    SKILL_DIST = 4,
    SKILL_SHIELD = 5,
    SKILL_FISH = 6,
    SKILL_COOK = 7,
    SKILL_LAST = SKILL_COOK
};
 
Last edited:
Thanks, you are the true MVP.

C++:
//skills
for(int32_t i = 0; i <= 7; ++i){
    query << "UPDATE `player_skills` SET `value` = " << player->skills[i][SKILL_LEVEL] << ", `count` = " << player->skills[i][SKILL_TRIES] << " WHERE `player_id` = " << player->getGUID() << " AND `skillid` = " << i;

    if(!db->executeQuery(query.str())){
        return false;
    }
    query.str("");
}

Database

1688155351392.png
 
Back
Top