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

Failed to add new skill

2057623

Member
Joined
Jan 16, 2012
Messages
129
Reaction score
15
I'm recently trying to add new skills to my server, like a distance skill and the same as Skill_distance, but I'm going to need several skills, so I added them here, but I don't know what's going on, it doesn't give an error to compile or anything, in items.xml I register weaponType correctly but it doesn't upload anything, I'll leave below what I added if someone can help me I'll be grateful I've been trying for over a week I've seen several topics videos ETC.



One skill is the pistol, and I want to add a weapon like Tibiagun, you know, where it shoots automatically, it increases the normal pistol skill and in the client too.

condition.cpp
LUA:
        case CONDITION_PARAM_SKILL_PISTOLA: {
            skills[SKILL_PISTOLA] = value;
            return true;
        }

        case CONDITION_PARAM_SKILL_PISTOLAPERCENT: {
            skillsPercent[SKILL_PISTOLA] = value;
            return true;
        }

Code:
       case CONDITION_PARAM_SKILL_PISTOLA:
            return skills[SKILL_PISTOLA];

        case CONDITION_PARAM_SKILL_PISTOLAPERCENT:
            return skillsPercent[SKILL_PISTOLA];

in const.h in the part enum WeaponType_t : uint8_t { I added this

Code:
WEAPON_PISTOLA,

In Enumhs.h
Code:
   CONDITION_PARAM_SKILL_PISTOLA = 56,
   CONDITION_PARAM_SKILL_PISTOLAPERCENT = 57,

there in enum skills_t : uint8_t { I added this
Code:
SKILL_PISTOLA = 7,

In iologindata.cpp

Code:
    query << "`skill_pistola` = " << player->skills[SKILL_PISTOLA].level << ',';
    query << "`skill_pistola_tries` = " << player->skills[SKILL_PISTOLA].tries << ',';

Code:
, `skill_pistola`, `skill_pistola_tries`

In item.cpp case CONST_SLOT_LEFT: I added this
Code:
else if (it.weaponType == WEAPON_SWORD || it.weaponType == WEAPON_CLUB || it.weaponType == WEAPON_AXE || it.weaponType == WEAPON_DISTANCE || it.weaponType == WEAPON_PISTOLA || it.weaponType == WEAPON_DOZE || it.weaponType == WEAPON_SUBMETRA || it.weaponType == WEAPON_FUZILASSALTO || it.weaponType == WEAPON_FUZILPRECISAO)
All the fields that I am putting the SKILL_PISTOLA ARE ALL IN THIS CODE, HERE IT IS ALL BECAUSE IT IS ALL ON ONE LINE, THERE I HAVE ALREADY PUT THEM ALL IN

In Items.cpp const std::unordered_map<std::string, ItemParseAttributes_t> ItemParseAttributesMap = {
Code:
 {"skillpistola", ITEM_PARSE_SKILLPISTOLA},

In const std::unordered_map<std::string, WeaponType_t> WeaponTypesMap = {
Code:
{"pistola", WEAPON_PISTOLA},

Code:
case ITEM_PARSE_SKILLPISTOLA: {
                    abilities.skills[SKILL_PISTOLA] = pugi::cast<int32_t>(valueAttribute.value());
                    break;
                }

In Items.h in enum ItemParseAttributes_t {
Code:
ITEM_PARSE_SKILLPISTOLA,

In luascript.cpp
Code:
REGISTER_ENUM(L, CONDITION_PARAM_SKILL_PISTOLA);
REGISTER_ENUM(L, CONDITION_PARAM_SKILL_PISTOLAPERCENT);

Code:
REGISTER_ENUM(L, SKILL_PISTOLA);

Code:
REGISTER_ENUM(L, WEAPON_PISTOLA);



Well, I saw another topic, I must have done a workaround here, it was to test it, it didn't give an error and it didn't work either, lol, I'm terrible with Source and everything :(.
Still in luascript.cpp I did this
Code:
WeaponType_t type = getNumber<WeaponType_t>(L, 2);
    switch (type) {
        case WEAPON_SWORD:
        case WEAPON_AXE:
        case WEAPON_CLUB:
        case WEAPON_PUNHO: {
            WeaponMelee* weapon = new WeaponMelee(getScriptEnv()->getScriptInterface());
            if (weapon) {
                pushUserdata<WeaponMelee>(L, weapon);
                setMetatable(L, -1, "Weapon");
                weapon->weaponType = type;
                weapon->fromLua = true;
            } else {
                lua_pushnil(L);
            }
            break;
        }
    case WEAPON_DISTANCE:
    case WEAPON_PISTOLA:
    case WEAPON_DOZE:
    case WEAPON_SUBMETRA:
    case WEAPON_FUZILASSALTO:
    case WEAPON_FUZILPRECISAO:
    case WEAPON_ESPECIAIS:
       case WEAPON_AMMO: {
            WeaponDistance* weapon = new WeaponDistance(getScriptEnv()->getScriptInterface());
            if (weapon) {
                pushUserdata<WeaponDistance>(L, weapon);
                setMetatable(L, -1, "Weapon");
                weapon->weaponType = type;
                weapon->fromLua = true;
            } else {
                lua_pushnil(L);
            }
            break;
        }

I added a fist skill in melee, I don't know if it's right, and in distance I put all the weapons.


In player.cpp
Code:
case WEAPON_PISTOLA: {
            attackSkill = getSkillLevel(SKILL_PISTOLA);
            break;
        }

In tools.cpp
Code:
case SKILL_PISTOLA:
            return "pistola";
in tools.cpp in std::string getWeaponName(WeaponType_t weaponType)
Code:
case WEAPON_PISTOLA: return "pistola";


In Weapons.cpp in void Weapons::loadDefaults()
Code:
void Weapons::loadDefaults()
{
    for (size_t i = 100, size = Item::items.size(); i < size; ++i) {
        const ItemType& it = Item::items.getItemType(i);
        if (it.id == 0 || weapons.find(i) != weapons.end()) {
            continue;
        }

        switch (it.weaponType) {
            case WEAPON_AXE:
            case WEAPON_SWORD:
            case WEAPON_CLUB:
            case WEAPON_PUNHO: {
                WeaponMelee* weapon = new WeaponMelee(&scriptInterface);
                weapon->configureWeapon(it);
                weapons[i] = weapon;
                break;
            }

        
            case WEAPON_AMMO:
            case WEAPON_DISTANCE:
            case WEAPON_PISTOLA:
            case WEAPON_DOZE:
            case WEAPON_SUBMETRA:
            case WEAPON_FUZILASSALTO:
            case WEAPON_FUZILPRECISAO:
            case WEAPON_ESPECIAIS: {
                if (it.weaponType == WEAPON_DISTANCE && it.ammoType != AMMO_NONE) {
                    continue;
                }

                WeaponDistance* weapon = new WeaponDistance(&scriptInterface);
                weapon->configureWeapon(it);
                weapons[i] = weapon;
                break;
            }

            default:
                break;
        }
    }
}


This is the weapon code I use in weapons on my otserv, it looks like this
LUA:
local WEAPON_ID = 31155 -- ID da sua arma personalizada
local AMMO_ID = 29185 -- ID da munição
local MISSILE_EFFECT = 113 -- Efeito de míssil
local DAMAGE_TYPE = COMBAT_PHYSICALDAMAGE -- Tipo de dano físico
local ATTACK_DELAY = 1000 -- Delay de 1 segundo entre os disparos (em milissegundos)
local MAX_ATTACK_DISTANCE = 5 -- Distância máxima para atacar

function onUseWeapon(player, variant)
    -- Verifica se o jogador tem munição suficiente
    if player:getItemCount(AMMO_ID) <= 0 then
        player:sendCancelMessage("Voce nao tem municao suficiente.")
        return false
    end

    -- Função que realiza o ataque
    local function performAttack()
        -- Obtém o alvo diretamente do jogador
        local target = player:getTarget()
        if not target or not target:isCreature() then
            player:sendCancelMessage("Alvo invalido durante o ataque.")
            return false
        end

        -- Verifica a distância do alvo
        if player:getPosition():getDistance(target:getPosition()) > MAX_ATTACK_DISTANCE then
            player:sendCancelMessage("Alvo fora de alcance.")
            return false
        end

        -- Remove uma unidade de munição
        if player:getItemCount(AMMO_ID) > 0 then
            player:removeItem(AMMO_ID, 1)
        else
            player:sendCancelMessage("Voce nao tem municao suficiente.")
            return false
        end

        -- Calcula o dano
        local minDamage = 8
        local maxDamage = 13
        local damage = math.random(minDamage, maxDamage)

        -- Aplica o dano
        local targetPosition = target:getPosition()
        local playerPosition = player:getPosition()

        -- Dispara o míssil
        playerPosition:sendDistanceEffect(targetPosition, MISSILE_EFFECT)

        -- Aplica o dano
        doTargetCombatHealth(player, target, DAMAGE_TYPE, -damage, -damage, CONST_ME_HITAREA)
    end

    -- Realiza o ataque inicial
    performAttack()

    -- Agendar o próximo ataque com o delay
    addEvent(function()
        local target = player:getTarget()
        if target and target:isCreature() then
            performAttack()
        else
            player:sendCancelMessage("Alvo invalido durante o ataque agendado.")
        end
    end, ATTACK_DELAY)

    return true
end

Weapons.xml
Code:
<distance id="31155" script="armas/Pistola 0.1.lua"/>

I've already tried changing <distance> to <pistol> in weapons.xml.

In items.xml it's like this: <attribute key="weaponType" value="Pistola" />

Well, my request is a bit long. I don't think people will read half of it because it's a waste of time. But if someone with a good heart wants to give me a tip, help me out.
I asked CHATGPT for my weapons code, but not even he can help me with this ;(





Oh, before anyone says anything, I've already seen this topic.
 
I'm recently trying to add new skills to my server, like a distance skill and the same as Skill_distance, but I'm going to need several skills, so I added them here, but I don't know what's going on, it doesn't give an error to compile or anything, in items.xml I register weaponType correctly but it doesn't upload anything, I'll leave below what I added if someone can help me I'll be grateful I've been trying for over a week I've seen several topics videos ETC.



One skill is the pistol, and I want to add a weapon like Tibiagun, you know, where it shoots automatically, it increases the normal pistol skill and in the client too.

condition.cpp
LUA:
        case CONDITION_PARAM_SKILL_PISTOLA: {
            skills[SKILL_PISTOLA] = value;
            return true;
        }

        case CONDITION_PARAM_SKILL_PISTOLAPERCENT: {
            skillsPercent[SKILL_PISTOLA] = value;
            return true;
        }

Code:
       case CONDITION_PARAM_SKILL_PISTOLA:
            return skills[SKILL_PISTOLA];

        case CONDITION_PARAM_SKILL_PISTOLAPERCENT:
            return skillsPercent[SKILL_PISTOLA];

in const.h in the part enum WeaponType_t : uint8_t { I added this

Code:
WEAPON_PISTOLA,

In Enumhs.h
Code:
   CONDITION_PARAM_SKILL_PISTOLA = 56,
   CONDITION_PARAM_SKILL_PISTOLAPERCENT = 57,

there in enum skills_t : uint8_t { I added this
Code:
SKILL_PISTOLA = 7,

In iologindata.cpp

Code:
    query << "`skill_pistola` = " << player->skills[SKILL_PISTOLA].level << ',';
    query << "`skill_pistola_tries` = " << player->skills[SKILL_PISTOLA].tries << ',';

Code:
, `skill_pistola`, `skill_pistola_tries`

In item.cpp case CONST_SLOT_LEFT: I added this
Code:
else if (it.weaponType == WEAPON_SWORD || it.weaponType == WEAPON_CLUB || it.weaponType == WEAPON_AXE || it.weaponType == WEAPON_DISTANCE || it.weaponType == WEAPON_PISTOLA || it.weaponType == WEAPON_DOZE || it.weaponType == WEAPON_SUBMETRA || it.weaponType == WEAPON_FUZILASSALTO || it.weaponType == WEAPON_FUZILPRECISAO)
All the fields that I am putting the SKILL_PISTOLA ARE ALL IN THIS CODE, HERE IT IS ALL BECAUSE IT IS ALL ON ONE LINE, THERE I HAVE ALREADY PUT THEM ALL IN

In Items.cpp const std::unordered_map<std::string, ItemParseAttributes_t> ItemParseAttributesMap = {
Code:
 {"skillpistola", ITEM_PARSE_SKILLPISTOLA},

In const std::unordered_map<std::string, WeaponType_t> WeaponTypesMap = {
Code:
{"pistola", WEAPON_PISTOLA},

Code:
case ITEM_PARSE_SKILLPISTOLA: {
                    abilities.skills[SKILL_PISTOLA] = pugi::cast<int32_t>(valueAttribute.value());
                    break;
                }

In Items.h in enum ItemParseAttributes_t {
Code:
ITEM_PARSE_SKILLPISTOLA,

In luascript.cpp
Code:
REGISTER_ENUM(L, CONDITION_PARAM_SKILL_PISTOLA);
REGISTER_ENUM(L, CONDITION_PARAM_SKILL_PISTOLAPERCENT);

Code:
REGISTER_ENUM(L, SKILL_PISTOLA);

Code:
REGISTER_ENUM(L, WEAPON_PISTOLA);



Well, I saw another topic, I must have done a workaround here, it was to test it, it didn't give an error and it didn't work either, lol, I'm terrible with Source and everything :(.
Still in luascript.cpp I did this
Code:
WeaponType_t type = getNumber<WeaponType_t>(L, 2);
    switch (type) {
        case WEAPON_SWORD:
        case WEAPON_AXE:
        case WEAPON_CLUB:
        case WEAPON_PUNHO: {
            WeaponMelee* weapon = new WeaponMelee(getScriptEnv()->getScriptInterface());
            if (weapon) {
                pushUserdata<WeaponMelee>(L, weapon);
                setMetatable(L, -1, "Weapon");
                weapon->weaponType = type;
                weapon->fromLua = true;
            } else {
                lua_pushnil(L);
            }
            break;
        }
    case WEAPON_DISTANCE:
    case WEAPON_PISTOLA:
    case WEAPON_DOZE:
    case WEAPON_SUBMETRA:
    case WEAPON_FUZILASSALTO:
    case WEAPON_FUZILPRECISAO:
    case WEAPON_ESPECIAIS:
       case WEAPON_AMMO: {
            WeaponDistance* weapon = new WeaponDistance(getScriptEnv()->getScriptInterface());
            if (weapon) {
                pushUserdata<WeaponDistance>(L, weapon);
                setMetatable(L, -1, "Weapon");
                weapon->weaponType = type;
                weapon->fromLua = true;
            } else {
                lua_pushnil(L);
            }
            break;
        }

I added a fist skill in melee, I don't know if it's right, and in distance I put all the weapons.


In player.cpp
Code:
case WEAPON_PISTOLA: {
            attackSkill = getSkillLevel(SKILL_PISTOLA);
            break;
        }

In tools.cpp
Code:
case SKILL_PISTOLA:
            return "pistola";
in tools.cpp in std::string getWeaponName(WeaponType_t weaponType)
Code:
case WEAPON_PISTOLA: return "pistola";


In Weapons.cpp in void Weapons::loadDefaults()
Code:
void Weapons::loadDefaults()
{
    for (size_t i = 100, size = Item::items.size(); i < size; ++i) {
        const ItemType& it = Item::items.getItemType(i);
        if (it.id == 0 || weapons.find(i) != weapons.end()) {
            continue;
        }

        switch (it.weaponType) {
            case WEAPON_AXE:
            case WEAPON_SWORD:
            case WEAPON_CLUB:
            case WEAPON_PUNHO: {
                WeaponMelee* weapon = new WeaponMelee(&scriptInterface);
                weapon->configureWeapon(it);
                weapons[i] = weapon;
                break;
            }

       
            case WEAPON_AMMO:
            case WEAPON_DISTANCE:
            case WEAPON_PISTOLA:
            case WEAPON_DOZE:
            case WEAPON_SUBMETRA:
            case WEAPON_FUZILASSALTO:
            case WEAPON_FUZILPRECISAO:
            case WEAPON_ESPECIAIS: {
                if (it.weaponType == WEAPON_DISTANCE && it.ammoType != AMMO_NONE) {
                    continue;
                }

                WeaponDistance* weapon = new WeaponDistance(&scriptInterface);
                weapon->configureWeapon(it);
                weapons[i] = weapon;
                break;
            }

            default:
                break;
        }
    }
}


This is the weapon code I use in weapons on my otserv, it looks like this
LUA:
local WEAPON_ID = 31155 -- ID da sua arma personalizada
local AMMO_ID = 29185 -- ID da munição
local MISSILE_EFFECT = 113 -- Efeito de míssil
local DAMAGE_TYPE = COMBAT_PHYSICALDAMAGE -- Tipo de dano físico
local ATTACK_DELAY = 1000 -- Delay de 1 segundo entre os disparos (em milissegundos)
local MAX_ATTACK_DISTANCE = 5 -- Distância máxima para atacar

function onUseWeapon(player, variant)
    -- Verifica se o jogador tem munição suficiente
    if player:getItemCount(AMMO_ID) <= 0 then
        player:sendCancelMessage("Voce nao tem municao suficiente.")
        return false
    end

    -- Função que realiza o ataque
    local function performAttack()
        -- Obtém o alvo diretamente do jogador
        local target = player:getTarget()
        if not target or not target:isCreature() then
            player:sendCancelMessage("Alvo invalido durante o ataque.")
            return false
        end

        -- Verifica a distância do alvo
        if player:getPosition():getDistance(target:getPosition()) > MAX_ATTACK_DISTANCE then
            player:sendCancelMessage("Alvo fora de alcance.")
            return false
        end

        -- Remove uma unidade de munição
        if player:getItemCount(AMMO_ID) > 0 then
            player:removeItem(AMMO_ID, 1)
        else
            player:sendCancelMessage("Voce nao tem municao suficiente.")
            return false
        end

        -- Calcula o dano
        local minDamage = 8
        local maxDamage = 13
        local damage = math.random(minDamage, maxDamage)

        -- Aplica o dano
        local targetPosition = target:getPosition()
        local playerPosition = player:getPosition()

        -- Dispara o míssil
        playerPosition:sendDistanceEffect(targetPosition, MISSILE_EFFECT)

        -- Aplica o dano
        doTargetCombatHealth(player, target, DAMAGE_TYPE, -damage, -damage, CONST_ME_HITAREA)
    end

    -- Realiza o ataque inicial
    performAttack()

    -- Agendar o próximo ataque com o delay
    addEvent(function()
        local target = player:getTarget()
        if target and target:isCreature() then
            performAttack()
        else
            player:sendCancelMessage("Alvo invalido durante o ataque agendado.")
        end
    end, ATTACK_DELAY)

    return true
end

Weapons.xml
Code:
<distance id="31155" script="armas/Pistola 0.1.lua"/>

I've already tried changing <distance> to <pistol> in weapons.xml.

In items.xml it's like this: <attribute key="weaponType" value="Pistola" />

Well, my request is a bit long. I don't think people will read half of it because it's a waste of time. But if someone with a good heart wants to give me a tip, help me out.
I asked CHATGPT for my weapons code, but not even he can help me with this ;(





Oh, before anyone says anything, I've already seen this topic.
Then you didn't do something correctly, I have added 6 skills following the thread you linked, and all worked perfectly.
Read carefully and add the lines accordingly, it should be really easy since the code is already there you just need to add upon it.

Reset all your changes, read carefully and do one skill at first if that makes life easier.
Once that works, voila add as much skills as you want.

Also took me two compiles since I forgot to add something in one src file
 
Then you didn't do something correctly, I have added 6 skills following the thread you linked, and all worked perfectly.
Read carefully and add the lines accordingly, it should be really easy since the code is already there you just need to add upon it.

Reset all your changes, read carefully and do one skill at first if that makes life easier.
Once that works, voila add as much skills as you want.

Also took me two compiles since I forgot to add something in one src file
Yes, I've redone it several times, but it always gives the same thing. I don't know if it's the code I used or what, because I cloned everything that contains distance and did the same thing, because my new skills are of the type attack from afar, and you can see what it contains there. I also put it here showing that mine already has that. It's impossible to have done something since everything is practically the same. I even put my codes in the topic. But thanks for the answer S2
 
You have to check
  • Weapon Type when weapon its "pistola"
  • Make sure u have in items.xml instead of "distance" to pistola, also you have to register there which type of ammo it use

at your place i would try to add melee new skill with new weapon type at first place, to make sure you are understading the structure of this system, then u can try add distance one

in my opinion weaponType return nill here so its not registered to onUseWeapon event
 
I recommend following the tutorial to understand how to add the first skill. This is how I learned, and it helped me understand the process. Eventually, I was able to create several different skills for my project.

So, take the opportunity to compare it with CodinBlack and Ramirow, where you've already made applications to your source. Which one do you think is missing something? Just compare both CodinBlack and Ramirow tutorials to understand what might be lacking, etc.
 
You have to check
  • Weapon Type when weapon its "pistola"
  • Make sure u have in items.xml instead of "distance" to pistola, also you have to register there which type of ammo it use

at your place i would try to add melee new skill with new weapon type at first place, to make sure you are understading the structure of this system, then u can try add distance one

in my opinion weaponType return nill here so its not registered to onUseWeapon event
In item.xml it is registered like this

<item id="31155" article="a" name="Pistol 0.1">
<attribute key="weight" value="2000" />
<attribute key="weaponType" value="Pistol" />
<attribute key="range" value="3" />
</item>

but if I add something melee the attack will not be at a distance.
The ammunition is directly in the weapon code which is in weapons.



I recommend following the tutorial to understand how to add the first skill. This is how I learned, and it helped me understand the process. Eventually, I was able to create several different skills for my project.

So, take the opportunity to compare it with CodinBlack and Ramirow, where you've already made applications to your source. Which one do you think is missing something? Just compare both CodinBlack and Ramirow tutorials to understand what might be lacking, etc.
But that's where the problem lies. I've already tried to add it like his. You can see that my code is the same. I added everything he said to add. Codinablack's is also the same.

But here's the question: does he teach how to add a SKILL_FIST? Isn't the SKILL_FIST different from a distance skill? Because I think my code has to follow the Distance logic, because if it's a sword, axe, club, it uses melee in weapons. Well, I don't know. That's still very confusing for me. My source has everything they said, but it doesn't work.
 
I redid it again in the source, but it still didn't work, I put everything right as he said below the fishing I'm not able to make it work I don't know why. Even though I redo everything from 0 I don't know why.
 
Back
Top