• 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++ Update system to tfs 1.42

_M4G0_

Well-Known Member
Joined
Feb 6, 2016
Messages
509
Solutions
16
Reaction score
99
please somebody can help-me upgrade this system for tfs 1.4
enums
C++:
enum SpecialSkills_t {
    SPECIALSKILL_MAGICLEVEL = 1,

    SPECIALSKILL_FIRST = SPECIALSKILL_MAGICLEVEL,
    SPECIALSKILL_LAST = SPECIALSKILL_MAGICLEVEL
};

enum itemCustomAttrTypes : uint32_t {
    ITEM_CUSTOMATTRIBUTE_SPECIALSKILL_MAGICLEVEL = 1,
};

events.cpp
C++:
bool Events::eventPlayerOnEquipItem(Player* player, Item* item, slots_t slot, bool isCheck)
{
    // Player:onEquipItem(item, slot, isCheck)
    if (info.playerOnEquipItem == -1) {
        return true;
    }

    if (!scriptInterface.reserveScriptEnv()) {
        std::cout << "[Error - Events::eventPlayerOnEquipItem] Call stack overflow" << std::endl;
        return false;
    }

    ScriptEnvironment* env = scriptInterface.getScriptEnv();
    env->setScriptId(info.playerOnEquipItem, &scriptInterface);

    lua_State* L = scriptInterface.getLuaState();
    scriptInterface.pushFunction(info.playerOnEquipItem);

    LuaScriptInterface::pushUserdata<Player>(L, player);
    LuaScriptInterface::setMetatable(L, -1, "Player");

    LuaScriptInterface::pushUserdata<Item>(L, item);
    LuaScriptInterface::setMetatable(L, -1, "Item");

    lua_pushnumber(L, (int8_t)slot);
    lua_pushboolean(L, isCheck);

    return scriptInterface.callFunction(4);
}

bool Events::eventPlayerOnDeEquipItem(Player* player, Item* item, slots_t slot, bool isCheck)
{
    // Player:onDeEquipItem(item, slot, isCheck)
    if (info.playerOnDeEquipItem == -1) {
        return true;
    }

    if (!scriptInterface.reserveScriptEnv()) {
        std::cout << "[Error - Events::eventPlayerOnDeEquipItem] Call stack overflow" << std::endl;
        return false;
    }

    ScriptEnvironment* env = scriptInterface.getScriptEnv();
    env->setScriptId(info.playerOnDeEquipItem, &scriptInterface);

    lua_State* L = scriptInterface.getLuaState();
    scriptInterface.pushFunction(info.playerOnDeEquipItem);

    LuaScriptInterface::pushUserdata<Player>(L, player);
    LuaScriptInterface::setMetatable(L, -1, "Player");

    LuaScriptInterface::pushUserdata<Item>(L, item);
    LuaScriptInterface::setMetatable(L, -1, "Item");

    lua_pushnumber(L, (int8_t)slot);
    lua_pushboolean(L, isCheck);

    return scriptInterface.callFunction(4);
}
 bool eventPlayerOnEquipItem(Player* player, Item* item, slots_t slot, bool isCheck);
 bool eventPlayerOnDeEquipItem(Player* player, Item* item, slots_t slot, bool isCheck);
item.cpp
C++:
void Item::setCustomAttribute(std::string& key, ItemAttributes::CustomAttribute& value)
{
    int64_t tmpInt = atoi(key.c_str());
    getAttributes()->setCustomAttribute(key, value);
    if (tmpInt > 0) {
        SpecialSkills_t skill = getCustomAttributeSpecialSkill((itemCustomAttrTypes)tmpInt);
        if (skill > 0) {
            Thing* thing = getTopParent() ? (Thing*)getTopParent() : nullptr;
            if (thing)
                if (Creature* creature = thing->getCreature()) {
                    if (Player* player = creature->getPlayer())
                        player->updateSpecialSkills();
                }
        }
    }
}
(tmpStrValue == "specialskillmagiclevel") {
            abilities.specialSkills[SPECIALSKILL_MAGICLEVEL] = pugi::cast<int32_t>(valueAttribute.value());

luascript.cpp
C++:
int LuaScriptInterface::luaPlayerGetSpecialSkill(lua_State* L)
{
    // player:getSpecialSkill(specialSkillType)
    SpecialSkills_t specialSkillType = getNumber<SpecialSkills_t>(L, 2);
    Player* player = getUserdata<Player>(L, 1);
    if (player && specialSkillType <= SPECIALSKILL_LAST) {
        lua_pushnumber(L, player->getSpecialSkill(specialSkillType));
    }
    else {
        lua_pushnil(L);
    }
    return 1;
}

int LuaScriptInterface::luaPlayerAddSpecialSkill(lua_State* L)
{
    // player:addSpecialSkill(specialSkillType, value)
    Player* player = getUserdata<Player>(L, 1);
    if (!player) {
        lua_pushnil(L);
        return 1;
    }

    SpecialSkills_t specialSkillType = getNumber<SpecialSkills_t>(L, 2);
    if (specialSkillType > SPECIALSKILL_LAST) {
        lua_pushnil(L);
        return 1;
    }

    player->addVarSpecialSkill(specialSkillType, getNumber<int32_t>(L, 3));
    player->sendSkills();
    pushBoolean(L, true);
    return 1;
}
int LuaScriptInterface::luaItemTypeGetSpecialSkillMagicLevel(lua_State* L) {
    // itemType:getSpecialSkillMagicLevel()
    const ItemType* itemType = getUserdata<const ItemType>(L, 1);
    if (itemType) {
        lua_pushnumber(L, itemType->getSpecialSkillMagicLevel());
    } else {
        lua_pushnil(L);
    }
    return 1;
}
movements.cpp
C++:
uint32_t MoveEvents::onPlayerEquip(Player* player, Item* item, slots_t slot, bool isCheck)
{
    player->updateSpecialSkills();
    if (g_events->eventPlayerOnEquipItem(player, item, slot, isCheck)) {
        MoveEvent* moveEvent = getEvent(item, MOVE_EVENT_EQUIP, slot);
        if (!moveEvent) {
            return 1;
        }
        return moveEvent->fireEquip(player, item, slot, isCheck);
    }
    return false;
}

uint32_t MoveEvents::onPlayerDeEquip(Player* player, Item* item, slots_t slot)
{
    player->updateSpecialSkills();
    if (g_events->eventPlayerOnDeEquipItem(player, item, slot, false)) {
        MoveEvent* moveEvent = getEvent(item, MOVE_EVENT_DEEQUIP, slot);
        if (!moveEvent) {
            return 1;
        }
        return moveEvent->fireEquip(player, item, slot, false);
    }
    return false;
}
player.cpp
C++:
void Player::updateSpecialSkills()
{
    for (int32_t i = SPECIALSKILL_FIRST; i <= SPECIALSKILL_LAST; ++i) {
        setVarSpecialSkill(static_cast<SpecialSkills_t>(i), 0);
    }

    for (uint8_t slot = CONST_SLOT_FIRST; slot < CONST_SLOT_LAST; slot++) {
        Thing* thing = getThing(slot);
        if (thing) {
            Item* item = thing->getItem();
            if (item) {
                const ItemType& iType = Item::items[item->getID()];

                for (int32_t i = SPECIALSKILL_FIRST; i <= SPECIALSKILL_LAST; ++i) {
                    if (iType.abilities->specialSkills[i]) {
                        int64_t skillValue = iType.abilities->specialSkills[i];
                        addVarSpecialSkill(static_cast<SpecialSkills_t>(i), skillValue);
                    }

                    const ItemAttributes::CustomAttribute* attr = item->getCustomAttribute(getSpecialSkillCustomAttribute(i));
                    if (attr) {
                        int64_t skillValue = boost::get<int64_t>(attr->value);
                        addVarSpecialSkill(static_cast<SpecialSkills_t>(i), skillValue);
                    }
                }
            }
        }
    }
    sendSkills();
    sendStats();
}

player.h
C++:
        void addVarSpecialSkill(SpecialSkills_t skill, int32_t modifier) {
            varSpecialSkills[skill] += modifier;
        }

        void setVarSpecialSkill(SpecialSkills_t skill, int32_t modifier)
        {
            varSpecialSkills[skill] = modifier;
        }

        void updateSpecialSkills();
uint16_t getSpecialSkill(uint8_t skill) const {
            return std::max<int32_t>(0, varSpecialSkills[skill]);
        }
tools.h
C++:
itemCustomAttrTypes getSpecialSkillCustomAttribute(uint8_t skillid);
SpecialSkills_t getCustomAttributeSpecialSkill(itemCustomAttrTypes attr);

ITEM_ATTRIBUTE_SPECIAL

 
Last edited:
please somebody can help-me upgrade this system for tfs 1.4
enums
C++:
enum SpecialSkills_t {
    SPECIALSKILL_MAGICLEVEL = 1,

    SPECIALSKILL_FIRST = SPECIALSKILL_MAGICLEVEL,
    SPECIALSKILL_LAST = SPECIALSKILL_MAGICLEVEL
};

enum itemCustomAttrTypes : uint32_t {
    ITEM_CUSTOMATTRIBUTE_SPECIALSKILL_MAGICLEVEL = 1,
};

events.cpp
C++:
bool Events::eventPlayerOnEquipItem(Player* player, Item* item, slots_t slot, bool isCheck)
{
    // Player:onEquipItem(item, slot, isCheck)
    if (info.playerOnEquipItem == -1) {
        return true;
    }

    if (!scriptInterface.reserveScriptEnv()) {
        std::cout << "[Error - Events::eventPlayerOnEquipItem] Call stack overflow" << std::endl;
        return false;
    }

    ScriptEnvironment* env = scriptInterface.getScriptEnv();
    env->setScriptId(info.playerOnEquipItem, &scriptInterface);

    lua_State* L = scriptInterface.getLuaState();
    scriptInterface.pushFunction(info.playerOnEquipItem);

    LuaScriptInterface::pushUserdata<Player>(L, player);
    LuaScriptInterface::setMetatable(L, -1, "Player");

    LuaScriptInterface::pushUserdata<Item>(L, item);
    LuaScriptInterface::setMetatable(L, -1, "Item");

    lua_pushnumber(L, (int8_t)slot);
    lua_pushboolean(L, isCheck);

    return scriptInterface.callFunction(4);
}

bool Events::eventPlayerOnDeEquipItem(Player* player, Item* item, slots_t slot, bool isCheck)
{
    // Player:onDeEquipItem(item, slot, isCheck)
    if (info.playerOnDeEquipItem == -1) {
        return true;
    }

    if (!scriptInterface.reserveScriptEnv()) {
        std::cout << "[Error - Events::eventPlayerOnDeEquipItem] Call stack overflow" << std::endl;
        return false;
    }

    ScriptEnvironment* env = scriptInterface.getScriptEnv();
    env->setScriptId(info.playerOnDeEquipItem, &scriptInterface);

    lua_State* L = scriptInterface.getLuaState();
    scriptInterface.pushFunction(info.playerOnDeEquipItem);

    LuaScriptInterface::pushUserdata<Player>(L, player);
    LuaScriptInterface::setMetatable(L, -1, "Player");

    LuaScriptInterface::pushUserdata<Item>(L, item);
    LuaScriptInterface::setMetatable(L, -1, "Item");

    lua_pushnumber(L, (int8_t)slot);
    lua_pushboolean(L, isCheck);

    return scriptInterface.callFunction(4);
}
 bool eventPlayerOnEquipItem(Player* player, Item* item, slots_t slot, bool isCheck);
 bool eventPlayerOnDeEquipItem(Player* player, Item* item, slots_t slot, bool isCheck);
item.cpp
C++:
void Item::setCustomAttribute(std::string& key, ItemAttributes::CustomAttribute& value)
{
    int64_t tmpInt = atoi(key.c_str());
    getAttributes()->setCustomAttribute(key, value);
    if (tmpInt > 0) {
        SpecialSkills_t skill = getCustomAttributeSpecialSkill((itemCustomAttrTypes)tmpInt);
        if (skill > 0) {
            Thing* thing = getTopParent() ? (Thing*)getTopParent() : nullptr;
            if (thing)
                if (Creature* creature = thing->getCreature()) {
                    if (Player* player = creature->getPlayer())
                        player->updateSpecialSkills();
                }
        }
    }
}
(tmpStrValue == "specialskillmagiclevel") {
            abilities.specialSkills[SPECIALSKILL_MAGICLEVEL] = pugi::cast<int32_t>(valueAttribute.value());

luascript.cpp
C++:
int LuaScriptInterface::luaPlayerGetSpecialSkill(lua_State* L)
{
    // player:getSpecialSkill(specialSkillType)
    SpecialSkills_t specialSkillType = getNumber<SpecialSkills_t>(L, 2);
    Player* player = getUserdata<Player>(L, 1);
    if (player && specialSkillType <= SPECIALSKILL_LAST) {
        lua_pushnumber(L, player->getSpecialSkill(specialSkillType));
    }
    else {
        lua_pushnil(L);
    }
    return 1;
}

int LuaScriptInterface::luaPlayerAddSpecialSkill(lua_State* L)
{
    // player:addSpecialSkill(specialSkillType, value)
    Player* player = getUserdata<Player>(L, 1);
    if (!player) {
        lua_pushnil(L);
        return 1;
    }

    SpecialSkills_t specialSkillType = getNumber<SpecialSkills_t>(L, 2);
    if (specialSkillType > SPECIALSKILL_LAST) {
        lua_pushnil(L);
        return 1;
    }

    player->addVarSpecialSkill(specialSkillType, getNumber<int32_t>(L, 3));
    player->sendSkills();
    pushBoolean(L, true);
    return 1;
}
int LuaScriptInterface::luaItemTypeGetSpecialSkillMagicLevel(lua_State* L) {
    // itemType:getSpecialSkillMagicLevel()
    const ItemType* itemType = getUserdata<const ItemType>(L, 1);
    if (itemType) {
        lua_pushnumber(L, itemType->getSpecialSkillMagicLevel());
    } else {
        lua_pushnil(L);
    }
    return 1;
}
movements.cpp
C++:
uint32_t MoveEvents::onPlayerEquip(Player* player, Item* item, slots_t slot, bool isCheck)
{
    player->updateSpecialSkills();
    if (g_events->eventPlayerOnEquipItem(player, item, slot, isCheck)) {
        MoveEvent* moveEvent = getEvent(item, MOVE_EVENT_EQUIP, slot);
        if (!moveEvent) {
            return 1;
        }
        return moveEvent->fireEquip(player, item, slot, isCheck);
    }
    return false;
}

uint32_t MoveEvents::onPlayerDeEquip(Player* player, Item* item, slots_t slot)
{
    player->updateSpecialSkills();
    if (g_events->eventPlayerOnDeEquipItem(player, item, slot, false)) {
        MoveEvent* moveEvent = getEvent(item, MOVE_EVENT_DEEQUIP, slot);
        if (!moveEvent) {
            return 1;
        }
        return moveEvent->fireEquip(player, item, slot, false);
    }
    return false;
}
player.cpp
C++:
void Player::updateSpecialSkills()
{
    for (int32_t i = SPECIALSKILL_FIRST; i <= SPECIALSKILL_LAST; ++i) {
        setVarSpecialSkill(static_cast<SpecialSkills_t>(i), 0);
    }

    for (uint8_t slot = CONST_SLOT_FIRST; slot < CONST_SLOT_LAST; slot++) {
        Thing* thing = getThing(slot);
        if (thing) {
            Item* item = thing->getItem();
            if (item) {
                const ItemType& iType = Item::items[item->getID()];

                for (int32_t i = SPECIALSKILL_FIRST; i <= SPECIALSKILL_LAST; ++i) {
                    if (iType.abilities->specialSkills[i]) {
                        int64_t skillValue = iType.abilities->specialSkills[i];
                        addVarSpecialSkill(static_cast<SpecialSkills_t>(i), skillValue);
                    }

                    const ItemAttributes::CustomAttribute* attr = item->getCustomAttribute(getSpecialSkillCustomAttribute(i));
                    if (attr) {
                        int64_t skillValue = boost::get<int64_t>(attr->value);
                        addVarSpecialSkill(static_cast<SpecialSkills_t>(i), skillValue);
                    }
                }
            }
        }
    }
    sendSkills();
    sendStats();
}

player.h
C++:
        void addVarSpecialSkill(SpecialSkills_t skill, int32_t modifier) {
            varSpecialSkills[skill] += modifier;
        }

        void setVarSpecialSkill(SpecialSkills_t skill, int32_t modifier)
        {
            varSpecialSkills[skill] = modifier;
        }

        void updateSpecialSkills();
uint16_t getSpecialSkill(uint8_t skill) const {
            return std::max<int32_t>(0, varSpecialSkills[skill]);
        }
tools.h
C++:
itemCustomAttrTypes getSpecialSkillCustomAttribute(uint8_t skillid);
SpecialSkills_t getCustomAttributeSpecialSkill(itemCustomAttrTypes attr);

ITEM_ATTRIBUTE_SPECIAL

TFS 1.4.2 doesn't need that system, as it has item custom attributes already
 
TFS 1.4.2 doesn't need that system, as it has item custom attributes already
thanks for the answer ☺️
yes, it already has customized attributes, but it needs special attributes, the system works as it is, but does not update the attributes when logging in
 
thanks for the answer ☺️
yes, it already has customized attributes, but it needs special attributes, the system works as it is, but does not update the attributes when logging in
so you use the creatureevent called "onlogin" check if they have the "special attribute" you are looking for, and if so, apply it. It's pretty basic stuff that doesn't require a source edit.
 
so you use the creatureevent called "onlogin" check if they have the "special attribute" you are looking for, and if so, apply it. It's pretty basic stuff that doesn't require a source edit.
have this funcion in events
Lua:
function Player:onEquipItem(item, slot, isCheck)
    SlotSystem.updatePlayer(self)
    return true
end

function Player:onDeEquipItem(item, slot, isCheck)
    SlotSystem.updatePlayer(self)
    return true
end

and
login.lua
Lua:
    player:loadSpecialStorage()
 
add

SlotSystem.updatePlayer(player)

to your login script, just underneath "player:loadSpecialStorage()"

and it should apply the update on login like you wanted.
 
for some reason the client is not updating the attributes 😭 😭 😭
I tested in tfs 1.3 everything works
1715400223595.png
 
Back
Top