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
in const.h in the part enum WeaponType_t : uint8_t { I added this
In Enumhs.h
there in enum skills_t : uint8_t { I added this
In iologindata.cpp
In item.cpp case CONST_SLOT_LEFT: I added this
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 = {
In const std::unordered_map<std::string, WeaponType_t> WeaponTypesMap = {
In Items.h in enum ItemParseAttributes_t {
In luascript.cpp
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
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
In tools.cpp
in tools.cpp in std::string getWeaponName(WeaponType_t weaponType)
In Weapons.cpp in void Weapons::loadDefaults()
This is the weapon code I use in weapons on my otserv, it looks like this
Weapons.xml
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.
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)
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";
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.
First of all, I make this thread because I was struggling to add a new skill that I could show using bars on the skill section of the client.
I know this pieces of code are not something really complex and I only post it in case someone is struggling like I did with this issue, will also create a thread on how to display it on OtClient. (Show additional skills on client (https://otland.net/threads/show-additional-skills-on-client.265785/))


This will create a skill that has all working functions for it (addSkillTries, getSkillLevel and so on) BUT you need to...
I know this pieces of code are not something really complex and I only post it in case someone is struggling like I did with this issue, will also create a thread on how to display it on OtClient. (Show additional skills on client (https://otland.net/threads/show-additional-skills-on-client.265785/))


This will create a skill that has all working functions for it (addSkillTries, getSkillLevel and so on) BUT you need to...