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

Imbuiment System tfs 1.2

Lais Prad

Disgusting Scammer
Joined
Apr 12, 2017
Messages
153
Solutions
6
Reaction score
15
We need fix somethings, if someone can help...
there we go:

modules.cpp
/**
* This file doesn't belong to theforgottenserver developers.
*/

#include "otpch.h"

#include "modules.h"
#include "player.h"

Modules::Modules() :
scriptInterface("Modules Interface")
{
scriptInterface.initState();
}

Modules::~Modules()
{
for (const auto& it : recvbyteList) {
delete it.second;
}
}

void Modules::clear()
{
//clear recvbyte list
for (const auto& it : recvbyteList) {
it.second->clearEvent();
}

//clear lua state
scriptInterface.reInitState();
}

LuaScriptInterface& Modules::getScriptInterface()
{
return scriptInterface;
}

std::string Modules::getScriptBaseName() const
{
return "modules";
}

Event* Modules::getEvent(const std::string& nodeName)
{
if (strcasecmp(nodeName.c_str(), "module") != 0) {
return nullptr;
}
return new Module(&scriptInterface);
}

bool Modules::registerEvent(Event* event, const pugi::xml_node&)
{
Module* module = static_cast<Module*>(event);
if (module->getEventType() == MODULE_TYPE_NONE) {
std::cout << "Error: [Modules::registerEvent] Trying to register event without type!" << std::endl;
return false;
}

Module* oldModule = getEventByRecvbyte(module->getRecvbyte(), false);
if (oldModule) {
if (!oldModule->isLoaded() && oldModule->getEventType() == module->getEventType()) {
oldModule->copyEvent(module);
}
return false;
} else {
recvbyteList[module->getRecvbyte()] = module;
return true;
}
}

Module* Modules::getEventByRecvbyte(uint8_t recvbyte, bool force)
{
ModulesList::iterator it = recvbyteList.find(recvbyte);
if (it != recvbyteList.end()) {
if (!force || it->second->isLoaded()) {
return it->second;
}
}
return nullptr;
}

void Modules::executeOnRecvbyte(Player* player, NetworkMessage& msg, uint8_t byte)
{
for (const auto& it : recvbyteList) {
Module* module = it.second;
if (module->getEventType() == MODULE_TYPE_RECVBYTE && module->getRecvbyte() == byte && player->canRunModule(module->getRecvbyte())) {
player->setModuleDelay(module->getRecvbyte(), module->getDelay());
module->executeOnRecvbyte(player, msg);
return;
}
}
}
/////////////////////////////////////

Module::Module(LuaScriptInterface* interface) :
Event(interface), type(MODULE_TYPE_NONE), loaded(false) {}

bool Module::configureEvent(const pugi::xml_node& node)
{
delay = 0;

pugi::xml_attribute typeAttribute = node.attribute("type");
if (!typeAttribute) {
std::cout << "[Error - Modules::configureEvent] Missing type for module." << std::endl;
return false;
}

std::string tmpStr = asLowerCaseString(typeAttribute.as_string());
if (tmpStr == "recvbyte") {
pugi::xml_attribute byteAttribute = node.attribute("byte");
if (!byteAttribute) {
std::cout << "[Error - Modules::configureEvent] Missing byte for module typed recvbyte." << std::endl;
return false;
}

recvbyte = static_cast<uint8_t>(byteAttribute.as_int());
type = MODULE_TYPE_RECVBYTE;
} else {
std::cout << "[Error - Modules::configureEvent] Invalid type for module." << std::endl;
return false;
}

pugi::xml_attribute delayAttribute = node.attribute("delay");
if (delayAttribute) {
delay = static_cast<uint16_t>(delayAttribute.as_uint());
}

loaded = true;
return true;
}

std::string Module::getScriptEventName() const
{
switch (type) {
case MODULE_TYPE_RECVBYTE:
return "onRecvbyte";
default:
return std::string();
}
}

void Module::copyEvent(Module* module)
{
m_scriptId = module->m_scriptId;
m_scriptInterface = module->m_scriptInterface;
m_scripted = module->m_scripted;
loaded = module->loaded;
}

void Module::clearEvent()
{
m_scriptId = 0;
m_scriptInterface = nullptr;
m_scripted = false;
loaded = false;
}

void Module::executeOnRecvbyte(Player* player, NetworkMessage& msg)
{
//onAdvance(player, skill, oldLevel, newLevel)
if (!m_scriptInterface->reserveScriptEnv()) {
std::cout << "[Error - CreatureEvent::executeAdvance] Call stack overflow" << std::endl;
return;
}

ScriptEnvironment* env = m_scriptInterface->getScriptEnv();
env->setScriptId(m_scriptId, m_scriptInterface);

lua_State* L = m_scriptInterface->getLuaState();

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

LuaScriptInterface::pushUserdata<NetworkMessage>(L, const_cast<NetworkMessage*>(&msg));
LuaScriptInterface::setWeakMetatable(L, -1, "NetworkMessage");

lua_pushnumber(L, recvbyte);

m_scriptInterface->callVoidFunction(3);
}
 
I dont know, but I cant edit posts above, then I'll write here:
modules.cpp
/**
* This file doesn't belong to theforgottenserver developers.
*/

#include "otpch.h"

#include "modules.h"
#include "player.h"

Modules::Modules() :
scriptInterface("Modules Interface")
{
scriptInterface.initState();
}

Modules::~Modules()
{
for (const auto& it : recvbyteList) {
delete it.second;
}
}

void Modules::clear()
{
//clear recvbyte list
for (const auto& it : recvbyteList) {
it.second->clearEvent();
}

//clear lua state
scriptInterface.reInitState();
}

LuaScriptInterface& Modules::getScriptInterface()
{
return scriptInterface;
}

std::string Modules::getScriptBaseName() const
{
return "modules";
}

Event* Modules::getEvent(const std::string& nodeName)
{
if (strcasecmp(nodeName.c_str(), "module") != 0) {
return nullptr;
}
return new Module(&scriptInterface);
}

bool Modules::registerEvent(Event* event, const pugi::xml_node&)
{
Module* module = static_cast<Module*>(event);
if (module->getEventType() == MODULE_TYPE_NONE) {
std::cout << "Error: [Modules::registerEvent] Trying to register event without type!" << std::endl;
return false;
}

Module* oldModule = getEventByRecvbyte(module->getRecvbyte(), false);
if (oldModule) {
if (!oldModule->isLoaded() && oldModule->getEventType() == module->getEventType()) {
oldModule->copyEvent(module);
}
return false;
} else {
recvbyteList[module->getRecvbyte()] = module;
return true;
}
}

Module* Modules::getEventByRecvbyte(uint8_t recvbyte, bool force)
{
ModulesList::iterator it = recvbyteList.find(recvbyte);
if (it != recvbyteList.end()) {
if (!force || it->second->isLoaded()) {
return it->second;
}
}
return nullptr;
}

void Modules::executeOnRecvbyte(Player* player, NetworkMessage& msg, uint8_t byte)
{
for (const auto& it : recvbyteList) {
Module* module = it.second;
if (module->getEventType() == MODULE_TYPE_RECVBYTE && module->getRecvbyte() == byte && player->canRunModule(module->getRecvbyte())) {
player->setModuleDelay(module->getRecvbyte(), module->getDelay());
module->executeOnRecvbyte(player, msg);
return;
}
}
}
/////////////////////////////////////

Module::Module(LuaScriptInterface* interface) :
Event(interface), type(MODULE_TYPE_NONE), loaded(false) {}

bool Module::configureEvent(const pugi::xml_node& node)
{
delay = 0;

pugi::xml_attribute typeAttribute = node.attribute("type");
if (!typeAttribute) {
std::cout << "[Error - Modules::configureEvent] Missing type for module." << std::endl;
return false;
}

std::string tmpStr = asLowerCaseString(typeAttribute.as_string());
if (tmpStr == "recvbyte") {
pugi::xml_attribute byteAttribute = node.attribute("byte");
if (!byteAttribute) {
std::cout << "[Error - Modules::configureEvent] Missing byte for module typed recvbyte." << std::endl;
return false;
}

recvbyte = static_cast<uint8_t>(byteAttribute.as_int());
type = MODULE_TYPE_RECVBYTE;
} else {
std::cout << "[Error - Modules::configureEvent] Invalid type for module." << std::endl;
return false;
}

pugi::xml_attribute delayAttribute = node.attribute("delay");
if (delayAttribute) {
delay = static_cast<uint16_t>(delayAttribute.as_uint());
}

loaded = true;
return true;
}

std::string Module::getScriptEventName() const
{
switch (type) {
case MODULE_TYPE_RECVBYTE:
return "onRecvbyte";
default:
return std::string();
}
}

void Module::copyEvent(Module* module)
{
m_scriptId = module->m_scriptId;
m_scriptInterface = module->m_scriptInterface;
m_scripted = module->m_scripted;
loaded = module->loaded;
}

void Module::clearEvent()
{
m_scriptId = 0;
m_scriptInterface = nullptr;
m_scripted = false;
loaded = false;
}

void Module::executeOnRecvbyte(Player* player, NetworkMessage& msg)
{
//onAdvance(player, skill, oldLevel, newLevel)
if (!m_scriptInterface->reserveScriptEnv()) {
std::cout << "[Error - CreatureEvent::executeAdvance] Call stack overflow" << std::endl;
return;
}

ScriptEnvironment* env = m_scriptInterface->getScriptEnv();
env->setScriptId(m_scriptId, m_scriptInterface);

lua_State* L = m_scriptInterface->getLuaState();

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

LuaScriptInterface::pushUserdata<NetworkMessage>(L, const_cast<NetworkMessage*>(&msg));
LuaScriptInterface::setWeakMetatable(L, -1, "NetworkMessage");

lua_pushnumber(L, recvbyte);

m_scriptInterface->callVoidFunction(3);
}

modules.h
/**
* This file doesn't belong to theforgottenserver developers.
*/

#ifndef FS_MODULE_H_73FCAF4608CB41399D53C919316646A9
#define FS_MODULE_H_73FCAF4608CB41399D53C919316646A9

#include "luascript.h"
#include "baseevents.h"
#include "networkmessage.h"

enum ModuleType_t {
MODULE_TYPE_RECVBYTE,
MODULE_TYPE_NONE,
};

class Module;

class Modules final : public BaseEvents
{
public:
Modules();
~Modules();

// non-copyable
Modules(const Modules&) = delete;
Modules& operator=(const Modules&) = delete;

void executeOnRecvbyte(Player* player, NetworkMessage& msg, uint8_t byte);

protected:
LuaScriptInterface& getScriptInterface() final;
std::string getScriptBaseName() const final;
Event* getEvent(const std::string& nodeName) final;
bool registerEvent(Event* event, const pugi::xml_node& node) final;
Module* getEventByRecvbyte(uint8_t recvbyte, bool force);
void clear() final;


typedef std::map<uint8_t, Module*> ModulesList;
ModulesList recvbyteList;

LuaScriptInterface scriptInterface;
};

class Module final : public Event
{
public:
explicit Module(LuaScriptInterface* interface);

bool configureEvent(const pugi::xml_node& node) final;

ModuleType_t getEventType() const {
return type;
}
bool isLoaded() const {
return loaded;
}

void clearEvent();
void copyEvent(Module* creatureEvent);

//scripting
void executeOnRecvbyte(Player* player, NetworkMessage& msg);
//

uint8_t getRecvbyte() {
return recvbyte;
}

int16_t getDelay() {
return delay;
}
protected:
std::string getScriptEventName() const final;

ModuleType_t type;
uint8_t recvbyte;
int16_t delay;
bool loaded;
};

#endif

scriptmanager.cpp
after
#include "events.h"
add:
#include "modules.h"


enums.h
after
ITEM_ATTRIBUTE_CHARGES = 1 << 20,
add:
ITEM_ATTRIBUTE_IMBUINGSLOTS = 1 << 24,

luascript.cpp
after
registerMethod("ItemType", "getExtraDefense", LuaScriptInterface::luaItemTypeGetExtraDefense);
add:
registerMethod("ItemType", "getImbuingSlots", LuaScriptInterface::luaItemTypeGetImbuingSlots);

above
int LuaScriptInterface::luaItemTypeGetArmor(lua_State* L)
add:
C++:
int LuaScriptInterface::luaItemTypeGetImbuingSlots(lua_State* L)
{
    // itemType:getImbuingSlots()
    const ItemType* itemType = getUserdata<const ItemType>(L, 1);
    if (itemType) {
        lua_pushnumber(L, itemType->imbuingSlots);
    } else {
        lua_pushnil(L);
    }
    return 1;
}

luascript.h
after
static int luaItemTypeGetExtraDefense(lua_State* L);
add:
static int luaItemTypeGetImbuingSlots(lua_State* L);

protocolgame.cpp
after
extern Chat* g_chat;
add:
extern Modules* g_modules;

before
MarketStatistics* statistics = IOMarket::getInstance()->getPurchaseStatistics(itemId);
add:
C++:
 if (version >= 1100) {
          msg.add<uint16_t>(0x00); // imbuement detail
       }

combat.cpp
change
damage.secondary.type = weapon->getElementType();
damage.secondary.value = weapon->getElementDamage(player, nullptr, tool);

to:
C++:
CombatType_t imbuingCombat = COMBAT_NONE;
                int32_t imbuingDamage = 0;

                g_events->eventPlayerOnCombatSpell(player, attackValue, imbuingDamage, imbuingCombat);

               
                damage.secondary.type = (imbuingCombat != COMBAT_NONE) ? imbuingCombat : weapon->getElementType();
                damage.secondary.value = weapon->getElementDamage(player, nullptr, tool, imbuingDamage, imbuingCombat);

items.cpp
after
it.extraDefense = pugi::cast<int32_t>(valueAttribute.value());
add:
} else if (tmpStrValue == "imbuingslots") {
it.imbuingSlots = pugi::cast<int32_t>(valueAttribute.value());

items.h
after
int32_t extraDefense;
add:
int32_t imbuingSlots = 0;

weapons.h

change
virtual int32_t getElementDamage(const Player* player, const Creature* target, const Item* item) const = 0;
to:
virtual int32_t getElementDamage(const Player* player, const Creature* target, const Item* item, int32_t imbuingDamage = 0, CombatType_t imbuingType = COMBAT_NONE) const = 0;

change (2x)
int32_t getElementDamage(const Player* player, const Creature* target, const Item* item) const final;
to:
int32_t getElementDamage(const Player* player, const Creature* target, const Item* item, int32_t imbuingDamage, CombatType_t imbuingType) const final;

change (2x)
CombatType_t elementType = COMBAT_NONE;
uint16_t elementDamage = 0;
to
CombatType_t elementType;
uint16_t elementDamage;

change
int32_t getElementDamage(const Player*, const Creature*, const Item*) const final { return 0; }
to:
int32_t getElementDamage(const Player*, const Creature*, const Item*, int32_t, CombatType_t) const final { return 0; }

item.h
after
int32_t getExtraDefense() const {
if (hasAttribute(ITEM_ATTRIBUTE_EXTRADEFENSE)) {
return getIntAttr(ITEM_ATTRIBUTE_EXTRADEFENSE);
}
return items[id].extraDefense;
}

add:
int32_t getImbuingSlots() const {
if (hasAttribute(ITEM_ATTRIBUTE_IMBUINGSLOTS)) {
return getIntAttr(ITEM_ATTRIBUTE_IMBUINGSLOTS);
}
return items[id].imbuingSlots;
}

after
ATTR_SHOOTRANGE = 33,
add:
ATTR_IMBUINGSLOTS = 35,

after
case ATTR_EXTRADEFENSE: {
int32_t extraDefense;
if (!propStream.read<int32_t>(extraDefense)) {
return ATTR_READ_ERROR;
}

setIntAttr(ITEM_ATTRIBUTE_EXTRADEFENSE, extraDefense);
break;
}

add:
case ATTR_IMBUINGSLOTS: {
int32_t imbuingSlots;
if (!propStream.read<int32_t>(imbuingSlots)) {
return ATTR_READ_ERROR;
}

setIntAttr(ITEM_ATTRIBUTE_IMBUINGSLOTS, imbuingSlots);
break;
}


after
if (hasAttribute(ITEM_ATTRIBUTE_EXTRADEFENSE)) {
propWriteStream.write<uint8_t>(ATTR_EXTRADEFENSE);
propWriteStream.write<int32_t>(getIntAttr(ITEM_ATTRIBUTE_EXTRADEFENSE));
}

add:
if (hasAttribute(ITEM_ATTRIBUTE_IMBUINGSLOTS)) {
propWriteStream.write<uint8_t>(ATTR_IMBUINGSLOTS);
propWriteStream.write<int32_t>(getIntAttr(ITEM_ATTRIBUTE_IMBUINGSLOTS));
}
 
events.h
after
int32_t playerOnGainSkillTries;
add:
int32_t playerOnUseWeapon = -1;
int32_t playerOnCombatSpell = -1;

events.cpp
change whole function
void Events::eventPlayerOnUseWeapon
to:
C++:
void Events::eventPlayerOnUseWeapon(Player* player, int32_t& normalDamage, CombatType_t& elementType, int32_t& elementDamage)
{
    // Player:onGainSkillTries(skill, tries)
    if (playerOnUseWeapon == -1) {
        return;
    }

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

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

    lua_State* L = scriptInterface.getLuaState();
    scriptInterface.pushFunction(playerOnUseWeapon);

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

    lua_pushnumber(L, normalDamage);
    lua_pushnumber(L, elementType);
    lua_pushnumber(L, elementDamage);

    if (scriptInterface.protectedCall(L, 4, 3) != 0) {
        LuaScriptInterface::reportError(nullptr, LuaScriptInterface::popString(L));
    } else {
        normalDamage = LuaScriptInterface::getNumber<int32_t>(L, -3);
        elementType = LuaScriptInterface::getNumber<CombatType_t>(L, -2);
        elementDamage = LuaScriptInterface::getNumber<int32_t>(L, -1);
        lua_pop(L, 3);
    }

    scriptInterface.resetScriptEnv();
}

whole function
void Events::eventPlayerOnCombatSpell
to:
C++:
void Events::eventPlayerOnCombatSpell(Player* player, int32_t& normalDamage, int32_t& elementDamage, CombatType_t& elementType)
{
    // Player:onGainSkillTries(skill, tries)
    if (playerOnCombatSpell == -1) {
        return;
    }

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

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

    lua_State* L = scriptInterface.getLuaState();
    scriptInterface.pushFunction(playerOnCombatSpell);

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

    lua_pushnumber(L, normalDamage);
    lua_pushnumber(L, elementDamage);
    lua_pushnumber(L, elementType);

    if (scriptInterface.protectedCall(L, 4, 3) != 0) {
        LuaScriptInterface::reportError(nullptr, LuaScriptInterface::popString(L));
    } else {
        normalDamage = LuaScriptInterface::getNumber<int32_t>(L, -3);
        elementType = LuaScriptInterface::getNumber<CombatType_t>(L, -2);
        elementDamage = LuaScriptInterface::getNumber<int32_t>(L, -1);
        lua_pop(L, 3);
    }

    scriptInterface.resetScriptEnv();
}
 
make diff in weapons.cpp and make the changes:
hastebin



player.lua events
before
local function useStamina(player)
add:
Lua:
function useStaminaImbuing(player, item)
    for i = 1, item:getType():getImbuingSlots() do
        if (item:isActiveImbuement(i+3)) then
            local staminaMinutes = item:getSpecialAttribute(i+3)/60
            if (staminaMinutes > 0) then
                local currentTime = os.time()
                local timePassed = currentTime - item:getSpecialAttribute(i+6)
                if timePassed > 0 then
                    if timePassed > 60 then
                        if staminaMinutes > 2 then
                            staminaMinutes = staminaMinutes - 2
                        else
                            staminaMinutes = 0
                        end

                        item:setSpecialAttribute(i+6, currentTime + 120)
                    else
                        staminaMinutes = staminaMinutes - 1
                        item:setSpecialAttribute(i+6, currentTime + 60)
                    end
                end

                item:setSpecialAttribute(i+3, staminaMinutes*60)
            end
        end
    end
end

actions.xml
<!--Imbuiment-->
<action fromid="28375" toid="28376" script="other/imbuement.lua" />

imbuiment.lua
Lua:
function onUse(cid, item, fromPosition, itemEx, toPosition)
    local player = Player(cid)
    if (not player) then
        return false
    end

    player:openImbuementWindow(itemEx)

    return true
end

global.lua

after
if nextUseStaminaTime == nil then
nextUseStaminaTime = {}
end

add:

if lastItemImbuing == nil then
lastItemImbuing = {}
end



modules.xml
<?xml version="1.0" encoding="UTF-8"?>
<modules>

<!-- Imbuiment -->
<module type="recvbyte" byte="213" script="imbuement/imbuement.lua" />

</modules>

imbuement.lua

Lua:
--[[
    1~3 => Element Type
    4~6 => Total Time (segundos - 20 h)
    7~9 => Time Passed (seconds)
]]--

local Imbuements = {
    {
        Name = "Scorch",
        Category = "Elemental Damage (Fire)",
        Type = "firedamage",
        Description = "Converts % of the physical damage to fire damage.",
        Levels = {"Basic", "Intricate", "Powerful"},
        LevelsPercent = {10, 25, 50},
        Weapons = {"axe", "club", "sword"},
        Items = {{10553, 25}, {5920, 5}, {5954, 5}}
    },
    {
        Name = "Venom",
        Category = "Elemental Damage (Earth)",
        Type = "earthdamage",
        Description = "Converts % of the physical damage to earth damage.",
        Levels = {"Basic", "Intricate", "Powerful"},
        LevelsPercent = {10, 25, 50},
        Weapons = {"axe", "club", "sword"},
        Items = {{10603, 25}, {10557, 5}, {23565, 5}}
    },
    {
        Name = "Frost",
        Category = "Elemental Damage (Ice)",
        Type = "icedamage",
        Description = "Converts % of the physical damage to ice damage.",
        Levels = {"Basic", "Intricate", "Powerful"},
        LevelsPercent = {10, 25, 50},
        Weapons = {"axe", "club", "sword"},
        Items = {{10567, 25}, {10578, 20}, {24170, 1}}
    },
    {
        Name = "Electrify",
        Category = "Elemental Damage (Energy)",
        Type = "energydamage",
        Description = "Converts % of the physical damage to energy damage.",
        Levels = {"Basic", "Intricate", "Powerful"},
        LevelsPercent = {10, 25, 50},
        Weapons = {"axe", "club", "sword"},
        Items = {{21310, 25}, {24631, 5}, {26164, 1}}
    },
    {
        Name = "Reap",
        Category = "Elemental Damage (Death)",
        Type = "deathdamage",
        Description = "Converts % of the physical damage to death damage.",
        Levels = {"Basic", "Intricate", "Powerful"},
        LevelsPercent = {10, 25, 50},
        Weapons = {"axe", "club", "sword"},
        Items = {{12440, 25}, {10564, 20}, {11337, 5}}
    },
    {
        Name = "Vampirism",
        Category = "Life Leech",
        Type = "hitpointsleech",
        Description = "converts % of damage to HP with a chance of 100%",
        Levels = {"Basic", "Intricate", "Powerful"},
        LevelsPercent = {5, 10, 25},
        Weapons = {"axe", "club", "sword", "wand", "rod", "bow", "armor"},
        Items = {{10602, 25}, {10550, 15}, {10580, 5}}
    }
}

local Weapons = {
    ["axe"] = {3962, 7412, 18451, 8926, 2414, 11305, 7419, 2435, 7453, 2415, 2427, 8924, 15492, 7435, 7455, 7456, 2443, 25383, 7434, 6553, 8925, 2431, 2447, 15451, 11323},
    ["club"] = {7414, 7426, 2453, 7429, 15647, 7431, 7430, 23543, 2444, 2452, 20093, 7424, 25418, 18452, 8928, 7421, 15414, 7410, 7437, 7451, 2424, 2436, 7423, 12648, 7452, 8929, 2421},
    ["sword"] = {7404, 7403, 12649, 7416, 2407, 2413, 7385, 7382, 2451, 8930, 2438, 2393, 7407, 7405, 2400, 7418, 7417, 18465, 2376, 7391, 6528, 8931, 12613, 11309, 7408, 11307}
}

local ImbuingInfo = {
    [1] = {Price = 5000, Protection = 10000, Percent = 90},
    [2] = {Price = 25000, Protection = 30000, Percent = 70},
    [3] = {Price = 100000, Protection = 50000, Percent = 50}
}

local imbuingShrineIds = {
    28376, 28375, 28384, 28383
}

local ImbuementElements = {
    "firedamage", "earthdamage", "energydamage", "deathdamage", "icedamage"
}

function onRecvbyte(player, msg, byte)
    if (byte == 0xD5) then
        -- Apply Imbuement
        --player:sendCancelMessage("Sorry, not possible.")
        --return false
        player:applyImbuement(msg)
    end
end

local function tableContains(table, value)
    for i = 1, #table do
        if (table[i] == value) then
            return true
        end
    end

    return false
end

local function haveImbuingShrine(player)
    for x = -1, 1 do
        for y = -1, 1 do
            local posX, posY, posZ = player:getPosition().x+x, player:getPosition().y+y, player:getPosition().z
            local tile = Tile(posX, posY, posZ)
            if (tile) then
                local topItem = tile:getTopTopItem()
                if (topItem) then
                    if (tableContains(imbuingShrineIds, topItem:getId())) then
                        return true
                    end
                end
            end
        end
    end

    return false
end

local function getEquipById(id)
    for i, v in pairs(Weapons) do
        if (tableContains(v, id)) then
            return i
        end
    end

    return nil
end

local function getImbuementEquip(equip)
    local tableReturn = {}
    for i = 1, #Imbuements do
        if (tableContains(Imbuements[i].Weapons, equip)) then
            tableReturn[#tableReturn+1] = Imbuements[i]
        end
    end

    return tableReturn
end

local function getActiveImbuement(item, slot)
    for i = 1, #Imbuements do
        for j = 1, 3 do
            local level = Imbuements[i].Levels[j]
            local enchant = item:getSpecialAttribute(slot)
            if (enchant:find(level) and enchant:find(Imbuements[i].Name)) then
                return Imbuements[i], j
            end
        end
    end

    return nil
end

local function getImbuementByIndex(index, id)
    local equip = getEquipById(id)
    local myImbuements = getImbuementEquip(equip)
    local tmpIndex = 0
    for i = 1, #myImbuements do
        for k = 1, 3 do
            tmpIndex = tmpIndex + 1
            if (index == tmpIndex) then
                return myImbuements[i], k
            end
        end
    end

    return nil
end

local function sendImbuementError(self, message)
    local msg = NetworkMessage()
    msg:addByte(0xED)
    msg:addByte(0x01)
    msg:addString(message)
    msg:sendToPlayer(self)
end

local function mergeImbuementList(table1, table2)
    local newTable = {}
    for i, v in pairs(table1) do
        if (v.Name ~= table2.Name and not (tableContains(ImbuementElements, v.Type) and tableContains(ImbuementElements, table2.Type))) then
            newTable[#newTable+1] = v
        end
    end

    return newTable
end

function Player.applyImbuement(self, msg)
    if (not haveImbuingShrine(self)) then
        self:sendCancelMessage("Sorry, not possible.")
        return false
    end

    local item = lastItemImbuing[self:getGuid()]
    if (item == nil) then
        self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Cannot find item, please send this message to a Administrator.")
        return false
    end

    local slot, choiceId, useProtection = msg:getByte(), msg:getU32(), msg:getByte()
    local myImbuement, imbuingLevel = getImbuementByIndex(choiceId, item:getId())
    if (not myImbuement) then
        self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Cannot find imbuement data, please send this message to a Administrator.")
        return false
    end

    slot = slot + 1
    if (item:isActiveImbuement(slot+3)) then
        self:sendCancelMessage("Sorry, not possible.")
        return false
    end
   
    item:setSpecialAttribute(slot, myImbuement.Levels[imbuingLevel].. " " ..myImbuement.Name, slot+3, 72000, slot+6, 0)
    self:openImbuementWindow(item)
end

function Player.closeImbuementWindow(self)
    local msg = NetworkMessage()
    msg:addByte(0xEC)
    msg:sendToPlayer(self)
end

function Player.openImbuementWindow(self, item)
    if (not item:isImbuementEquip()) then
        self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "This item is not imbuable.")
        return false
    end

    if (self:getSlotItem(CONST_SLOT_LEFT) and self:getSlotItem(CONST_SLOT_LEFT):getUniqueId() == item:getUniqueId()) then
        self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You cannot imbue an equipped item.")
        return false
    end

    local msg = NetworkMessage()
    local itemID = item:getId()
    local equip = getEquipById(item:getId())
    local myImbuements = getImbuementEquip(equip)
    local imbuingSlots = item:getType():getImbuingSlots()
    lastItemImbuing[self:getGuid()] = item

    msg:addByte(0xEB)
    msg:addItemId(itemID) -- Item to put slots imbuement
    msg:addByte(imbuingSlots) -- Loop Exists Imbuement and slot (soon)

    for i = 1, imbuingSlots do
        if (item:isActiveImbuement(i+3)) then
            local existsImbuement, enchantLevel = getActiveImbuement(item, i)
            myImbuements = mergeImbuementList(myImbuements, existsImbuement)
            msg:addByte(0x01) -- No have imbuement (byte 1 need more packets)
            msg:addU32(900) -- Start Read Imbuement Data
            msg:addString(existsImbuement.Levels[enchantLevel].. " " ..existsImbuement.Name) -- Name Element
            local newDescription = existsImbuement.Description:gsub(" %%", " " ..existsImbuement.LevelsPercent[enchantLevel].."%%")
            msg:addString(newDescription.. "\nLasts for 20h 0min while fighting.") -- Description
            msg:addString(existsImbuement.Category) -- Type Imbuement
            msg:addU16(4) -- Icon ID (wtf?)
            msg:addU32(72000) -- duration in seconds (20hrs)
            msg:addByte(0x01) -- premium true
            msg:addByte(enchantLevel) -- Loop Length astral sources
            for j = 1, enchantLevel do
                local itemID, itemName = existsImbuement.Items[j][1], ItemType(existsImbuement.Items[j][1]):getName()
                msg:addItemId(itemID or 2160) -- Astral ID
                msg:addString(itemName or "") -- Astral Name
                msg:addU16(existsImbuement.Items[j][2]) -- Astral Necessary count
            end
            msg:addU32(ImbuingInfo[enchantLevel].Price)
            msg:addByte(ImbuingInfo[enchantLevel].Percent)
            msg:addU32(ImbuingInfo[enchantLevel].Protection) -- End Read Imbuement Data
            msg:addU32(item:getTimeImbuement(i+3)) -- Remaining Seconds
            msg:addU32(15000) -- Clear Cost Gold
        else
            msg:addByte(0x00)
        end
    end

    msg:addU16(#myImbuements*3) -- Loop Read Imbuement data
    local index = 0
    for k = 1, #myImbuements do
        for i = 1, 3 do
            index = index + 1
            msg:addU32(index) -- Start Read Imbuement Data
            msg:addString(myImbuements[k].Levels[i].. " " ..myImbuements[k].Name) -- Name Element
            local newDescription = myImbuements[k].Description:gsub(" %%", " " ..myImbuements[k].LevelsPercent[i].."%%")
            msg:addString(newDescription.. "\nLasts for 20h 0min while fighting.") -- Description
            msg:addString(myImbuements[k].Category) -- Type Imbuement
            msg:addU16(1) -- Icon ID (wtf?)
            msg:addU32(72000) -- duration in seconds (20hrs)
            if (i > 1) then
                msg:addByte(0x01) -- premium true
            else
                msg:addByte(0x00) -- premium false
            end
            msg:addByte(i) -- Loop Length astral sources
            for j = 1, i do
                local itemID, itemName = myImbuements[k].Items[j][1], ItemType(myImbuements[k].Items[j][1]):getName()
                msg:addItemId(itemID or 2160) -- Astral ID
                msg:addString(itemName or "") -- Astral Name
                msg:addU16(myImbuements[k].Items[j][2]) -- Astral Necessary count
            end
            msg:addU32(ImbuingInfo[i].Price)
            msg:addByte(ImbuingInfo[i].Percent)
            msg:addU32(ImbuingInfo[i].Protection) -- End Read Imbuement Data
        end
    end

    msg:addU32(#myImbuements*3)
    for k = 1, #myImbuements do
        for j = 1, 3 do
            msg:addItemId(myImbuements[k].Items[j][1])
            msg:addU16(self:getItemCount(myImbuements[k].Items[j][1]))
        end
    end
    self:sendResource("bank", self:getBankBalance())
    self:sendResource("inventory", self:getMoney())
    msg:sendToPlayer(self)
end

function Item:isActiveImbuement(index)
    local time = self:getSpecialAttribute(index)
    if (time and time > 0) then
        return true
    end

    return false
end

function Item:getTimeImbuement(index)
    local time = self:getSpecialAttribute(index)
    if (time and time > 0) then
        return time
    end

    return false
end

function Item:isImbuementEquip()
    if (not self) then
        return false
    end

    if (self:getType() and self:getType():getImbuingSlots() > 0) then
        return true
    end

    return false
end

function Item:getImbuementType(slot)
    local enchant = self:getSpecialAttribute(slot)
    if (not enchant) then
        return false
    end

    for i, v in pairs(Imbuements) do
        for j = 1, 3 do
            if (enchant:find(v.Name) and enchant:find(v.Levels[j])) then
                return v.Type
            end
        end
    end

    return nil
end

function Item:getImbuementPercent(name)
    for i, v in pairs(Imbuements) do
        for j = 1, 3 do
            if (name:find(v.Name) and name:find(v.Levels[j])) then
                return v.LevelsPercent[j]
            end
        end
    end

    return nil
end
 
You are copying-pasre my modules.cpp without credits

I do not know who developed it, someone passed me a datapack and I was just taking out the parts of the imbuiment, instead of complaining that he is the developer or whatever, why not help us and commit to the forgotten server github? We are a community, we need help, do not keep scripts for yourself just to sell .
 
I do not know who developed it, someone passed me a datapack and I was just taking out the parts of the imbuiment, instead of complaining that he is the developer or whatever, why not help us and commit to the forgotten server github? We are a community, we need help, do not keep scripts for yourself just to sell .

From your behaviour I can see you think we are here only to help you, you are spamming support board expecting everyone to help you. + You can't even describe the problem, you are like "it has bugs" fix it. Wtf?
 
What community we are? you just spam support boards

we are this community:
6d98f818dd154791b7dc66052026b132.png
 
Showing up private messages.
nice from your part.
Hope you will not receive support from any1

Friends, I put here a system that none of you who commented above would make available for free, please avoid spamming in the topic. If want to talk, I'll introduce you: Chit Chat
 
1 - I'm not your friend.
2 - Do you like to take pictures? maybe you can be well known photographer.
3 - Showing up private messages is still bad i dont see the points to start to talking to me, just accept that you are a kid.
4 - Read again #3
 
Back
Top