Jump to content
You Know Nothing

Scripting Push com exhaust com outras actions

Recommended Posts

Gostaria de saber se alguém sabe tirar a interferência de exaust de PUSH com RUNAS/POTIONS/outras actions em geral.

Pois quando o player está segurando a potion por exemplo, ele não consegue empurrar outro player nem com milagre.

 

OBS:

a configuração do config.lua pushCreatureDelay, não resolve, pois é somente a velocidade que voce consegue chutar o cara, mas mesmo que coloque 0, se estiver potando ou usando sd, nao consegue.

Edited by You Know Nothing (see edit history)

Share this post


Link to post
Share on other sites

Precisa ser realizada uma alteração na source, você possui a sources do servidor?


 

 

 

Nós somos aquilo que fazemos repetidamente. Excelência, não é um modo de agir, mas um hábito.

                                                                                                                                                                                                                                        Aristóteles 

Share this post


Link to post
Share on other sites
1 hora atrás, You Know Nothing disse:

Possuo sim@WooX 

Posta actions.cpp


 

 

 

Nós somos aquilo que fazemos repetidamente. Excelência, não é um modo de agir, mas um hábito.

                                                                                                                                                                                                                                        Aristóteles 

Share this post


Link to post
Share on other sites
20 horas atrás, WooX disse:

Posta actions.cpp

 

@WooX segue o actions.cpp:

 

Spoiler

////////////////////////////////////////////////////////////////////////
// OpenTibia - an opensource roleplaying game
////////////////////////////////////////////////////////////////////////
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
////////////////////////////////////////////////////////////////////////
#include "otpch.h"

#include "const.h"

#include "actions.h"
#include "tools.h"

#include "player.h"
#include "monster.h"
#include "npc.h"

#include "item.h"
#include "container.h"

#include "game.h"
#include "configmanager.h"

#include "combat.h"
#include "spells.h"

#include "house.h"
#include "beds.h"

#include <libxml/xmlmemory.h>
#include <libxml/parser.h>

extern Game g_game;
extern Spells* g_spells;
extern Actions* g_actions;
extern ConfigManager g_config;

Actions::Actions():
m_interface("Action Interface")
{
    m_interface.initState();
    defaultAction = NULL;
}

Actions::~Actions()
{
    clear();
}

inline void Actions::clearMap(ActionUseMap& map)
{
    for(ActionUseMap::iterator it = map.begin(); it != map.end(); ++it)
        delete it->second;

    map.clear();
}

void Actions::clear()
{
    clearMap(useItemMap);
    clearMap(uniqueItemMap);
    clearMap(actionItemMap);

    m_interface.reInitState();
    delete defaultAction;
    defaultAction = NULL;
}

Event* Actions::getEvent(const std::string& nodeName)
{
    if(asLowerCaseString(nodeName) == "action")
        return new Action(&m_interface);

    return NULL;
}

bool Actions::registerEvent(Event* event, xmlNodePtr p, bool override)
{
    Action* action = dynamic_cast<Action*>(event);
    if(!action)
        return false;

    std::string strValue;
    if(readXMLString(p, "default", strValue) && booleanString(strValue))
    {
        if(!defaultAction)
            defaultAction = action;
        else if(override)
        {
            delete defaultAction;
            defaultAction = action;
        }
        else
            std::clog << "[Warning - Actions::registerEvent] You cannot define more than one default action, if you want to do so "
                << "Please define \"override\"." << std::endl;

        return true;
    }

    bool success = true;
    std::string endValue;
    if(readXMLString(p, "itemid", strValue))
    {
        IntegerVec intVector;
        if(!parseIntegerVec(strValue, intVector))
        {
            std::clog << "[Warning - Actions::registerEvent] Invalid itemid - '" << strValue << "'" << std::endl;
            return false;
        }

        if(useItemMap.find(intVector[0]) != useItemMap.end())
        {
            if(!override)
            {
                std::clog << "[Warning - Actions::registerEvent] Duplicate registered item id: " << intVector[0] << std::endl;
                success = false;
            }
            else
                delete useItemMap[intVector[0]];
        }

        if(success)
            useItemMap[intVector[0]] = action;

        for(size_t i = 1, size = intVector.size(); i < size; ++i)
        {
            if(useItemMap.find(intVector) != useItemMap.end())
            {
                if(!override)
                {
                    std::clog << "[Warning - Actions::registerEvent] Duplicate registered item id: " << intVector << std::endl;
                    continue;
                }
                else
                    delete useItemMap[intVector];
            }

            useItemMap[intVector] = new Action(action);
        }
    }
    else if(readXMLString(p, "fromid", strValue) && readXMLString(p, "toid", endValue))
    {
        IntegerVec intVector = vectorAtoi(explodeString(strValue, ";")), endVector = vectorAtoi(explodeString(endValue, ";"));
        if(intVector[0] && endVector[0] && intVector.size() == endVector.size())
        {
            int32_t tmp = 0;
            for(size_t i = 0, size = intVector.size(); i < size; ++i)
            {
                tmp = intVector;
                while(intVector <= endVector)
                {
                    if(useItemMap.find(intVector) != useItemMap.end())
                    {
                        if(!override)
                        {
                            std::clog << "[Warning - Actions::registerEvent] Duplicate registered item with id: " << intVector <<
                                ", in fromid: " << tmp << " and toid: " << endVector << std::endl;
                            intVector++;
                            continue;
                        }
                        else
                            delete useItemMap[intVector];
                    }

                    useItemMap[intVector++] = new Action(action);
                }
            }
        }
        else
            std::clog << "[Warning - Actions::registerEvent] Malformed entry (from item: \"" << strValue <<
                "\", to item: \"" << endValue << "\")" << std::endl;
    }

    if(readXMLString(p, "uniqueid", strValue))
    {
        IntegerVec intVector;
        if(!parseIntegerVec(strValue, intVector))
        {
            std::clog << "[Warning - Actions::registerEvent] Invalid uniqueid - '" << strValue << "'" << std::endl;
            return false;
        }

        if(uniqueItemMap.find(intVector[0]) != uniqueItemMap.end())
        {
            if(!override)
            {
                std::clog << "[Warning - Actions::registerEvent] Duplicate registered item uid: " << intVector[0] << std::endl;
                success = false;
            }
            else
                delete uniqueItemMap[intVector[0]];
        }

        if(success)
            uniqueItemMap[intVector[0]] = action;

        for(size_t i = 1, size = intVector.size(); i < size; ++i)
        {
            if(uniqueItemMap.find(intVector) != uniqueItemMap.end())
            {
                if(!override)
                {
                    std::clog << "[Warning - Actions::registerEvent] Duplicate registered item uid: " << intVector << std::endl;
                    continue;
                }
                else
                    delete uniqueItemMap[intVector];
            }

            uniqueItemMap[intVector] = new Action(action);
        }
    }
    else if(readXMLString(p, "fromuid", strValue) && readXMLString(p, "touid", endValue))
    {
        IntegerVec intVector = vectorAtoi(explodeString(strValue, ";")), endVector = vectorAtoi(explodeString(endValue, ";"));
        if(intVector[0] && endVector[0] && intVector.size() == endVector.size())
        {
            int32_t tmp = 0;
            for(size_t i = 0, size = intVector.size(); i < size; ++i)
            {
                tmp = intVector;
                while(intVector <= endVector)
                {
                    if(uniqueItemMap.find(intVector) != uniqueItemMap.end())
                    {
                        if(!override)
                        {
                            std::clog << "[Warning - Actions::registerEvent] Duplicate registered item with uid: " << intVector <<
                                ", in fromuid: " << tmp << " and touid: " << endVector << std::endl;
                            intVector++;
                            continue;
                        }
                        else
                            delete uniqueItemMap[intVector];
                    }

                    uniqueItemMap[intVector++] = new Action(action);
                }
            }
        }
        else
            std::clog << "[Warning - Actions::registerEvent] Malformed entry (from unique: \"" << strValue <<
                "\", to unique: \"" << endValue << "\")" << std::endl;
    }

    if(readXMLString(p, "actionid", strValue) || readXMLString(p, "aid", strValue))
    {
        IntegerVec intVector;
        if(!parseIntegerVec(strValue, intVector))
        {
            std::clog << "[Warning - Actions::registerEvent] Invalid actionid - '" << strValue << "'" << std::endl;
            return false;
        }

        if(actionItemMap.find(intVector[0]) != actionItemMap.end())
        {
            if(!override)
            {
                std::clog << "[Warning - Actions::registerEvent] Duplicate registered item aid: " << intVector[0] << std::endl;
                success = false;
            }
            else
                delete actionItemMap[intVector[0]];
        }

        if(success)
            actionItemMap[intVector[0]] = action;

        for(size_t i = 1, size = intVector.size(); i < size; ++i)
        {
            if(actionItemMap.find(intVector) != actionItemMap.end())
            {
                if(!override)
                {
                    std::clog << "[Warning - Actions::registerEvent] Duplicate registered item aid: " << intVector << std::endl;
                    continue;
                }
                else
                    delete actionItemMap[intVector];
            }

            actionItemMap[intVector] = new Action(action);
        }
    }
    else if(readXMLString(p, "fromaid", strValue) && readXMLString(p, "toaid", endValue))
    {
        IntegerVec intVector = vectorAtoi(explodeString(strValue, ";")), endVector = vectorAtoi(explodeString(endValue, ";"));
        if(intVector[0] && endVector[0] && intVector.size() == endVector.size())
        {
            int32_t tmp = 0;
            for(size_t i = 0, size = intVector.size(); i < size; ++i)
            {
                tmp = intVector;
                while(intVector <= endVector)
                {
                    if(actionItemMap.find(intVector) != actionItemMap.end())
                    {
                        if(!override)
                        {
                            std::clog << "[Warning - Actions::registerEvent] Duplicate registered item with aid: " << intVector <<
                                ", in fromaid: " << tmp << " and toaid: " << endVector << std::endl;
                            intVector++;
                            continue;
                        }
                        else
                            delete actionItemMap[intVector];
                    }

                    actionItemMap[intVector++] = new Action(action);
                }
            }
        }
        else
            std::clog << "[Warning - Actions::registerEvent] Malformed entry (from action: \"" << strValue <<
                "\", to action: \"" << endValue << "\")" << std::endl;
    }

    return success;
}

ReturnValue Actions::canUse(const Player* player, const Position& pos)
{
    const Position& playerPos = player->getPosition();
    if(pos.x == 0xFFFF)
        return RET_NOERROR;

    if(playerPos.z > pos.z)
        return RET_FIRSTGOUPSTAIRS;

    if(playerPos.z < pos.z)
        return RET_FIRSTGODOWNSTAIRS;

    if(!Position::areInRange<1,1,0>(playerPos, pos))
        return RET_TOOFARAWAY;

    Tile* tile = g_game.getTile(pos);
    if(tile)
    {
        HouseTile* houseTile = tile->getHouseTile();
        if(houseTile && houseTile->getHouse() && !houseTile->getHouse()->isInvited(player))
            return RET_PLAYERISNOTINVITED;
    }

    return RET_NOERROR;
}

ReturnValue Actions::canUseEx(const Player* player, const Position& pos, const Item* item)
{
    Action* action = NULL;
    if((action = getAction(item, ACTION_UNIQUEID)))
        return action->canExecuteAction(player, pos);

    if((action = getAction(item, ACTION_ACTIONID)))
        return action->canExecuteAction(player, pos);

    if((action = getAction(item, ACTION_ITEMID)))
        return action->canExecuteAction(player, pos);

    if((action = getAction(item, ACTION_RUNEID)))
        return action->canExecuteAction(player, pos);

    if(defaultAction)
        return defaultAction->canExecuteAction(player, pos);

    return RET_NOERROR;
}

ReturnValue Actions::canUseFar(const Creature* creature, const Position& toPos, bool checkLineOfSight)
{
    if(toPos.x == 0xFFFF)
        return RET_NOERROR;

    const Position& creaturePos = creature->getPosition();
    if(creaturePos.z > toPos.z)
        return RET_FIRSTGOUPSTAIRS;

    if(creaturePos.z < toPos.z)
        return RET_FIRSTGODOWNSTAIRS;

    if(!Position::areInRange<7,5,0>(toPos, creaturePos))
        return RET_TOOFARAWAY;

    if(checkLineOfSight && !g_game.canThrowObjectTo(creaturePos, toPos))
        return RET_CANNOTTHROW;

    return RET_NOERROR;
}

Action* Actions::getAction(const Item* item, ActionType_t type) const
{
    if(item->getUniqueId() && (type == ACTION_ANY || type == ACTION_UNIQUEID))
    {
        ActionUseMap::const_iterator it = uniqueItemMap.find(item->getUniqueId());
        if(it != uniqueItemMap.end())
            return it->second;
    }

    if(item->getActionId() && (type == ACTION_ANY || type == ACTION_ACTIONID))
    {
        ActionUseMap::const_iterator it = actionItemMap.find(item->getActionId());
        if(it != actionItemMap.end())
            return it->second;
    }

    if(type == ACTION_ANY || type == ACTION_ITEMID)
    {
        ActionUseMap::const_iterator it = useItemMap.find(item->getID());
        if(it != useItemMap.end())
            return it->second;
    }

    if(type == ACTION_ANY || type == ACTION_RUNEID)
    {
        if(Action* runeSpell = g_spells->getRuneSpell(item->getID()))
            return runeSpell;
    }

    return NULL;
}

bool Actions::executeUse(Action* action, Player* player, Item* item,
    const PositionEx& posEx, uint32_t creatureId)
{
    return action->executeUse(player, item, posEx, posEx, false, creatureId);
}

ReturnValue Actions::internalUseItem(Player* player, const Position& pos, uint8_t index, Item* item, uint32_t creatureId)
{
    if(Door* door = item->getDoor())
    {
        if(!door->canUse(player))
            return RET_CANNOTUSETHISOBJECT;
    }

    int32_t tmp = 0;
    if(item->getParent())
        tmp = item->getParent()->__getIndexOfThing(item);

    PositionEx posEx(pos, tmp);
    Action* action = NULL;
    if((action = getAction(item, ACTION_UNIQUEID)))
    {
        if(executeUse(action, player, item, posEx, creatureId))
            return RET_NOERROR;
    }

    if((action = getAction(item, ACTION_ACTIONID)))
    {
        if(executeUse(action, player, item, posEx, creatureId))
            return RET_NOERROR;
    }

    if((action = getAction(item, ACTION_ITEMID)))
    {
        if(executeUse(action, player, item, posEx, creatureId))
            return RET_NOERROR;
    }

    if((action = getAction(item, ACTION_RUNEID)))
    {
        if(executeUse(action, player, item, posEx, creatureId))
            return RET_NOERROR;
    }

    if(defaultAction)
    {
        if(executeUse(defaultAction, player, item, posEx, creatureId))
            return RET_NOERROR;
    }

    if(BedItem* bed = item->getBed())
    {
        if(!bed->canUse(player))
            return RET_CANNOTUSETHISOBJECT;

        bed->sleep(player);
        return RET_NOERROR;
    }

    if(Container* container = item->getContainer())
    {
        if(container->getCorpseOwner() && !player->canOpenCorpse(container->getCorpseOwner())
            && g_config.getBool(ConfigManager::CHECK_CORPSE_OWNER))
            return RET_YOUARENOTTHEOWNER;

        Container* tmpContainer = NULL;
        if(Depot* depot = container->getDepot())
        {
            if(player->hasFlag(PlayerFlag_CannotPickupItem))
                return RET_CANNOTUSETHISOBJECT;

            if(Depot* playerDepot = player->getDepot(depot->getDepotId(), true))
            {
                player->useDepot(depot->getDepotId(), true);
                playerDepot->setParent(depot->getParent());
                tmpContainer = playerDepot;
            }
        }

        if(!tmpContainer)
            tmpContainer = container;

        int32_t oldId = player->getContainerID(tmpContainer);
        if(oldId != -1)
        {
            player->onCloseContainer(tmpContainer);
            player->closeContainer(oldId);
        }
        else
        {
            player->addContainer(index, tmpContainer);
            player->onSendContainer(tmpContainer);
        }

        return RET_NOERROR;
    }

    if(item->isReadable())
    {
        if(item->canWriteText())
        {
            player->setWriteItem(item, item->getMaxWriteLength());
            player->sendTextWindow(item, item->getMaxWriteLength(), true);
        }
        else
        {
            player->setWriteItem(NULL);
            player->sendTextWindow(item, 0, false);
        }

        return RET_NOERROR;
    }

    const ItemType& it = Item::items[item->getID()];
    if(it.transformUseTo)
    {
        g_game.transformItem(item, it.transformUseTo);
        g_game.startDecay(item);
        return RET_NOERROR;
    }

    if(item->isPremiumScroll())
    {
        std::ostringstream ss;
        ss << " You have recived " << it.premiumDays << " premium days.";
        player->sendTextMessage(MSG_INFO_DESCR, ss.str());

        player->addPremiumDays(it.premiumDays);
        g_game.internalRemoveItem(NULL, item, 1);
        return RET_NOERROR;
    }

    return RET_CANNOTUSETHISOBJECT;
}

bool Actions::useItem(Player* player, const Position& pos, uint8_t index, Item* item)
{
    if(!player->canDoAction())
        return false;

    player->setNextActionTask(NULL);
    player->stopWalk();
    player->setNextAction(OTSYS_TIME() + g_config.getNumber(ConfigManager::ACTIONS_DELAY_INTERVAL) - 10);

    ReturnValue ret = internalUseItem(player, pos, index, item, 0);
    if(ret == RET_NOERROR)
        return true;

    player->sendCancelMessage(ret);
    return false;
}

bool Actions::executeUseEx(Action* action, Player* player, Item* item, const PositionEx& fromPosEx,
    const PositionEx& toPosEx, bool isHotkey, uint32_t creatureId)
{
    return (action->executeUse(player, item, fromPosEx, toPosEx, isHotkey,
        creatureId) || action->hasOwnErrorHandler());
}

ReturnValue Actions::internalUseItemEx(Player* player, const PositionEx& fromPosEx, const PositionEx& toPosEx,
    Item* item, bool isHotkey, uint32_t creatureId)
{
    Action* action = NULL;
    if((action = getAction(item, ACTION_UNIQUEID)))
    {
        ReturnValue ret = action->canExecuteAction(player, toPosEx);
        if(ret != RET_NOERROR)
            return ret;

        //only continue with next action in the list if the previous returns false
        if(executeUseEx(action, player, item, fromPosEx, toPosEx, isHotkey, creatureId))
            return RET_NOERROR;
    }

    if((action = getAction(item, ACTION_ACTIONID)))
    {
        ReturnValue ret = action->canExecuteAction(player, toPosEx);
        if(ret != RET_NOERROR)
            return ret;

        //only continue with next action in the list if the previous returns false
        if(executeUseEx(action, player, item, fromPosEx, toPosEx, isHotkey, creatureId))
            return RET_NOERROR;

    }

    if((action = getAction(item, ACTION_ITEMID)))
    {
        ReturnValue ret = action->canExecuteAction(player, toPosEx);
        if(ret != RET_NOERROR)
            return ret;

        //only continue with next action in the list if the previous returns false
        if(executeUseEx(action, player, item, fromPosEx, toPosEx, isHotkey, creatureId))
            return RET_NOERROR;
    }

    if((action = getAction(item, ACTION_RUNEID)))
    {
        ReturnValue ret = action->canExecuteAction(player, toPosEx);
        if(ret != RET_NOERROR)
            return ret;

        //only continue with next action in the list if the previous returns false
        if(executeUseEx(action, player, item, fromPosEx, toPosEx, isHotkey, creatureId))
            return RET_NOERROR;
    }

    if(defaultAction)
    {
        ReturnValue ret = defaultAction->canExecuteAction(player, toPosEx);
        if(ret != RET_NOERROR)
            return ret;

        //only continue with next action in the list if the previous returns false
        if(executeUseEx(defaultAction, player, item, fromPosEx, toPosEx, isHotkey, creatureId))
            return RET_NOERROR;
    }

    return RET_CANNOTUSETHISOBJECT;
}

bool Actions::useItemEx(Player* player, const Position& fromPos, const Position& toPos,
    uint8_t toStackPos, Item* item, bool isHotkey, uint32_t creatureId/* = 0*/)
{
    if(!player->canDoAction())
        return false;

    player->setNextActionTask(NULL);
    player->stopWalk();
    player->setNextAction(OTSYS_TIME() + g_config.getNumber(ConfigManager::EX_ACTIONS_DELAY_INTERVAL) - 10);

    int32_t fromStackPos = 0;
    if(item->getParent())
        fromStackPos = item->getParent()->__getIndexOfThing(item);

    PositionEx fromPosEx(fromPos, fromStackPos);
    PositionEx toPosEx(toPos, toStackPos);

    ReturnValue ret = internalUseItemEx(player, fromPosEx, toPosEx, item, isHotkey, creatureId);
    if(ret == RET_NOERROR)
        return true;

    player->sendCancelMessage(ret);
    return false;
}

Action::Action(LuaInterface* _interface):
Event(_interface)
{
    allowFarUse = false;
    checkLineOfSight = true;
}

Action::Action(const Action* copy):
Event(copy)
{
    allowFarUse = copy->allowFarUse;
    checkLineOfSight = copy->checkLineOfSight;
}

bool Action::configureEvent(xmlNodePtr p)
{
    std::string strValue;
    if(readXMLString(p, "allowfaruse", strValue) || readXMLString(p, "allowFarUse", strValue))
        setAllowFarUse(booleanString(strValue));

    if(readXMLString(p, "blockwalls", strValue) || readXMLString(p, "blockWalls", strValue))
        setCheckLineOfSight(booleanString(strValue));

    return true;
}

ReturnValue Action::canExecuteAction(const Player* player, const Position& pos)
{
    if(player->hasCustomFlag(PlayerCustomFlag_CanUseFar))
        return RET_NOERROR;

    if(!getAllowFarUse())
        return g_actions->canUse(player, pos);

    return g_actions->canUseFar(player, pos, getCheckLineOfSight());
}

bool Action::executeUse(Player* player, Item* item, const PositionEx& fromPos, const PositionEx& toPos, bool extendedUse, uint32_t)
{
    //onUse(cid, item, fromPosition, itemEx, toPosition)
    if(m_interface->reserveEnv())
    {
        ScriptEnviroment* env = m_interface->getEnv();
        if(m_scripted == EVENT_SCRIPT_BUFFER)
        {
            env->setRealPos(player->getPosition());
            std::ostringstream scriptstream;

            scriptstream << "local cid = " << env->addThing(player) << std::endl;
            env->streamThing(scriptstream, "item", item, env->addThing(item));
            env->streamPosition(scriptstream, "fromPosition", fromPos, fromPos.stackpos);

            Thing* thing = g_game.internalGetThing(player, toPos, toPos.stackpos);
            if(thing && (thing != item || !extendedUse))
            {
                env->streamThing(scriptstream, "itemEx", thing, env->addThing(thing));
                env->streamPosition(scriptstream, "toPosition", toPos, toPos.stackpos);
            }
            else
            {
                env->streamThing(scriptstream, "itemEx", NULL, 0);
                env->streamPosition(scriptstream, "toPosition", PositionEx());
            }

            if(m_scriptData)
                scriptstream << *m_scriptData;

            bool result = true;
            if(m_interface->loadBuffer(scriptstream.str()))
            {
                lua_State* L = m_interface->getState();
                result = m_interface->getGlobalBool(L, "_result", true);
            }

            m_interface->releaseEnv();
            return result;
        }
        else
        {
            #ifdef __DEBUG_LUASCRIPTS__
            std::ostringstream desc;
            desc << player->getName() << " - " << item->getID() << " " << fromPos << "|" << toPos;
            env->setEvent(desc.str());
            #endif

            env->setScriptId(m_scriptId, m_interface);
            env->setRealPos(player->getPosition());

            lua_State* L = m_interface->getState();
            m_interface->pushFunction(m_scriptId);

            lua_pushnumber(L, env->addThing(player));
            LuaInterface::pushThing(L, item, env->addThing(item));
            LuaInterface::pushPosition(L, fromPos, fromPos.stackpos);

            Thing* thing = g_game.internalGetThing(player, toPos, toPos.stackpos);
            if(thing && (thing != item || !extendedUse))
            {
                LuaInterface::pushThing(L, thing, env->addThing(thing));
                LuaInterface::pushPosition(L, toPos, toPos.stackpos);
            }
            else
            {
                LuaInterface::pushThing(L, NULL, 0);
                LuaInterface::pushPosition(L, PositionEx());
            }

            bool result = m_interface->callFunction(5);
            m_interface->releaseEnv();
            return result;
        }
    }
    else
    {
        std::clog << "[Error - Action::executeUse]: Call stack overflow." << std::endl;
        return false;
    }
}
 

 

 

Edited by You Know Nothing (see edit history)

Share this post


Link to post
Share on other sites
Em 27/03/2019 em 17:48, You Know Nothing disse:

@WooX segue o actions.cpp:

 

  Mostrar conteúdo oculto

////////////////////////////////////////////////////////////////////////
// OpenTibia - an opensource roleplaying game
////////////////////////////////////////////////////////////////////////
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
////////////////////////////////////////////////////////////////////////
#include "otpch.h"

#include "const.h"

#include "actions.h"
#include "tools.h"

#include "player.h"
#include "monster.h"
#include "npc.h"

#include "item.h"
#include "container.h"

#include "game.h"
#include "configmanager.h"

#include "combat.h"
#include "spells.h"

#include "house.h"
#include "beds.h"

#include <libxml/xmlmemory.h>
#include <libxml/parser.h>

extern Game g_game;
extern Spells* g_spells;
extern Actions* g_actions;
extern ConfigManager g_config;

Actions::Actions():
m_interface("Action Interface")
{
    m_interface.initState();
    defaultAction = NULL;
}

Actions::~Actions()
{
    clear();
}

inline void Actions::clearMap(ActionUseMap& map)
{
    for(ActionUseMap::iterator it = map.begin(); it != map.end(); ++it)
        delete it->second;

    map.clear();
}

void Actions::clear()
{
    clearMap(useItemMap);
    clearMap(uniqueItemMap);
    clearMap(actionItemMap);

    m_interface.reInitState();
    delete defaultAction;
    defaultAction = NULL;
}

Event* Actions::getEvent(const std::string& nodeName)
{
    if(asLowerCaseString(nodeName) == "action")
        return new Action(&m_interface);

    return NULL;
}

bool Actions::registerEvent(Event* event, xmlNodePtr p, bool override)
{
    Action* action = dynamic_cast<Action*>(event);
    if(!action)
        return false;

    std::string strValue;
    if(readXMLString(p, "default", strValue) && booleanString(strValue))
    {
        if(!defaultAction)
            defaultAction = action;
        else if(override)
        {
            delete defaultAction;
            defaultAction = action;
        }
        else
            std::clog << "[Warning - Actions::registerEvent] You cannot define more than one default action, if you want to do so "
                << "Please define \"override\"." << std::endl;

        return true;
    }

    bool success = true;
    std::string endValue;
    if(readXMLString(p, "itemid", strValue))
    {
        IntegerVec intVector;
        if(!parseIntegerVec(strValue, intVector))
        {
            std::clog << "[Warning - Actions::registerEvent] Invalid itemid - '" << strValue << "'" << std::endl;
            return false;
        }

        if(useItemMap.find(intVector[0]) != useItemMap.end())
        {
            if(!override)
            {
                std::clog << "[Warning - Actions::registerEvent] Duplicate registered item id: " << intVector[0] << std::endl;
                success = false;
            }
            else
                delete useItemMap[intVector[0]];
        }

        if(success)
            useItemMap[intVector[0]] = action;

        for(size_t i = 1, size = intVector.size(); i < size; ++i)
        {
            if(useItemMap.find(intVector) != useItemMap.end())
            {
                if(!override)
                {
                    std::clog << "[Warning - Actions::registerEvent] Duplicate registered item id: " << intVector << std::endl;
                    continue;
                }
                else
                    delete useItemMap[intVector];
            }

            useItemMap[intVector] = new Action(action);
        }
    }
    else if(readXMLString(p, "fromid", strValue) && readXMLString(p, "toid", endValue))
    {
        IntegerVec intVector = vectorAtoi(explodeString(strValue, ";")), endVector = vectorAtoi(explodeString(endValue, ";"));
        if(intVector[0] && endVector[0] && intVector.size() == endVector.size())
        {
            int32_t tmp = 0;
            for(size_t i = 0, size = intVector.size(); i < size; ++i)
            {
                tmp = intVector;
                while(intVector <= endVector)
                {
                    if(useItemMap.find(intVector) != useItemMap.end())
                    {
                        if(!override)
                        {
                            std::clog << "[Warning - Actions::registerEvent] Duplicate registered item with id: " << intVector <<
                                ", in fromid: " << tmp << " and toid: " << endVector << std::endl;
                            intVector++;
                            continue;
                        }
                        else
                            delete useItemMap[intVector];
                    }

                    useItemMap[intVector++] = new Action(action);
                }
            }
        }
        else
            std::clog << "[Warning - Actions::registerEvent] Malformed entry (from item: \"" << strValue <<
                "\", to item: \"" << endValue << "\")" << std::endl;
    }

    if(readXMLString(p, "uniqueid", strValue))
    {
        IntegerVec intVector;
        if(!parseIntegerVec(strValue, intVector))
        {
            std::clog << "[Warning - Actions::registerEvent] Invalid uniqueid - '" << strValue << "'" << std::endl;
            return false;
        }

        if(uniqueItemMap.find(intVector[0]) != uniqueItemMap.end())
        {
            if(!override)
            {
                std::clog << "[Warning - Actions::registerEvent] Duplicate registered item uid: " << intVector[0] << std::endl;
                success = false;
            }
            else
                delete uniqueItemMap[intVector[0]];
        }

        if(success)
            uniqueItemMap[intVector[0]] = action;

        for(size_t i = 1, size = intVector.size(); i < size; ++i)
        {
            if(uniqueItemMap.find(intVector) != uniqueItemMap.end())
            {
                if(!override)
                {
                    std::clog << "[Warning - Actions::registerEvent] Duplicate registered item uid: " << intVector << std::endl;
                    continue;
                }
                else
                    delete uniqueItemMap[intVector];
            }

            uniqueItemMap[intVector] = new Action(action);
        }
    }
    else if(readXMLString(p, "fromuid", strValue) && readXMLString(p, "touid", endValue))
    {
        IntegerVec intVector = vectorAtoi(explodeString(strValue, ";")), endVector = vectorAtoi(explodeString(endValue, ";"));
        if(intVector[0] && endVector[0] && intVector.size() == endVector.size())
        {
            int32_t tmp = 0;
            for(size_t i = 0, size = intVector.size(); i < size; ++i)
            {
                tmp = intVector;
                while(intVector <= endVector)
                {
                    if(uniqueItemMap.find(intVector) != uniqueItemMap.end())
                    {
                        if(!override)
                        {
                            std::clog << "[Warning - Actions::registerEvent] Duplicate registered item with uid: " << intVector <<
                                ", in fromuid: " << tmp << " and touid: " << endVector << std::endl;
                            intVector++;
                            continue;
                        }
                        else
                            delete uniqueItemMap[intVector];
                    }

                    uniqueItemMap[intVector++] = new Action(action);
                }
            }
        }
        else
            std::clog << "[Warning - Actions::registerEvent] Malformed entry (from unique: \"" << strValue <<
                "\", to unique: \"" << endValue << "\")" << std::endl;
    }

    if(readXMLString(p, "actionid", strValue) || readXMLString(p, "aid", strValue))
    {
        IntegerVec intVector;
        if(!parseIntegerVec(strValue, intVector))
        {
            std::clog << "[Warning - Actions::registerEvent] Invalid actionid - '" << strValue << "'" << std::endl;
            return false;
        }

        if(actionItemMap.find(intVector[0]) != actionItemMap.end())
        {
            if(!override)
            {
                std::clog << "[Warning - Actions::registerEvent] Duplicate registered item aid: " << intVector[0] << std::endl;
                success = false;
            }
            else
                delete actionItemMap[intVector[0]];
        }

        if(success)
            actionItemMap[intVector[0]] = action;

        for(size_t i = 1, size = intVector.size(); i < size; ++i)
        {
            if(actionItemMap.find(intVector) != actionItemMap.end())
            {
                if(!override)
                {
                    std::clog << "[Warning - Actions::registerEvent] Duplicate registered item aid: " << intVector << std::endl;
                    continue;
                }
                else
                    delete actionItemMap[intVector];
            }

            actionItemMap[intVector] = new Action(action);
        }
    }
    else if(readXMLString(p, "fromaid", strValue) && readXMLString(p, "toaid", endValue))
    {
        IntegerVec intVector = vectorAtoi(explodeString(strValue, ";")), endVector = vectorAtoi(explodeString(endValue, ";"));
        if(intVector[0] && endVector[0] && intVector.size() == endVector.size())
        {
            int32_t tmp = 0;
            for(size_t i = 0, size = intVector.size(); i < size; ++i)
            {
                tmp = intVector;
                while(intVector <= endVector)
                {
                    if(actionItemMap.find(intVector) != actionItemMap.end())
                    {
                        if(!override)
                        {
                            std::clog << "[Warning - Actions::registerEvent] Duplicate registered item with aid: " << intVector <<
                                ", in fromaid: " << tmp << " and toaid: " << endVector << std::endl;
                            intVector++;
                            continue;
                        }
                        else
                            delete actionItemMap[intVector];
                    }

                    actionItemMap[intVector++] = new Action(action);
                }
            }
        }
        else
            std::clog << "[Warning - Actions::registerEvent] Malformed entry (from action: \"" << strValue <<
                "\", to action: \"" << endValue << "\")" << std::endl;
    }

    return success;
}

ReturnValue Actions::canUse(const Player* player, const Position& pos)
{
    const Position& playerPos = player->getPosition();
    if(pos.x == 0xFFFF)
        return RET_NOERROR;

    if(playerPos.z > pos.z)
        return RET_FIRSTGOUPSTAIRS;

    if(playerPos.z < pos.z)
        return RET_FIRSTGODOWNSTAIRS;

    if(!Position::areInRange<1,1,0>(playerPos, pos))
        return RET_TOOFARAWAY;

    Tile* tile = g_game.getTile(pos);
    if(tile)
    {
        HouseTile* houseTile = tile->getHouseTile();
        if(houseTile && houseTile->getHouse() && !houseTile->getHouse()->isInvited(player))
            return RET_PLAYERISNOTINVITED;
    }

    return RET_NOERROR;
}

ReturnValue Actions::canUseEx(const Player* player, const Position& pos, const Item* item)
{
    Action* action = NULL;
    if((action = getAction(item, ACTION_UNIQUEID)))
        return action->canExecuteAction(player, pos);

    if((action = getAction(item, ACTION_ACTIONID)))
        return action->canExecuteAction(player, pos);

    if((action = getAction(item, ACTION_ITEMID)))
        return action->canExecuteAction(player, pos);

    if((action = getAction(item, ACTION_RUNEID)))
        return action->canExecuteAction(player, pos);

    if(defaultAction)
        return defaultAction->canExecuteAction(player, pos);

    return RET_NOERROR;
}

ReturnValue Actions::canUseFar(const Creature* creature, const Position& toPos, bool checkLineOfSight)
{
    if(toPos.x == 0xFFFF)
        return RET_NOERROR;

    const Position& creaturePos = creature->getPosition();
    if(creaturePos.z > toPos.z)
        return RET_FIRSTGOUPSTAIRS;

    if(creaturePos.z < toPos.z)
        return RET_FIRSTGODOWNSTAIRS;

    if(!Position::areInRange<7,5,0>(toPos, creaturePos))
        return RET_TOOFARAWAY;

    if(checkLineOfSight && !g_game.canThrowObjectTo(creaturePos, toPos))
        return RET_CANNOTTHROW;

    return RET_NOERROR;
}

Action* Actions::getAction(const Item* item, ActionType_t type) const
{
    if(item->getUniqueId() && (type == ACTION_ANY || type == ACTION_UNIQUEID))
    {
        ActionUseMap::const_iterator it = uniqueItemMap.find(item->getUniqueId());
        if(it != uniqueItemMap.end())
            return it->second;
    }

    if(item->getActionId() && (type == ACTION_ANY || type == ACTION_ACTIONID))
    {
        ActionUseMap::const_iterator it = actionItemMap.find(item->getActionId());
        if(it != actionItemMap.end())
            return it->second;
    }

    if(type == ACTION_ANY || type == ACTION_ITEMID)
    {
        ActionUseMap::const_iterator it = useItemMap.find(item->getID());
        if(it != useItemMap.end())
            return it->second;
    }

    if(type == ACTION_ANY || type == ACTION_RUNEID)
    {
        if(Action* runeSpell = g_spells->getRuneSpell(item->getID()))
            return runeSpell;
    }

    return NULL;
}

bool Actions::executeUse(Action* action, Player* player, Item* item,
    const PositionEx& posEx, uint32_t creatureId)
{
    return action->executeUse(player, item, posEx, posEx, false, creatureId);
}

ReturnValue Actions::internalUseItem(Player* player, const Position& pos, uint8_t index, Item* item, uint32_t creatureId)
{
    if(Door* door = item->getDoor())
    {
        if(!door->canUse(player))
            return RET_CANNOTUSETHISOBJECT;
    }

    int32_t tmp = 0;
    if(item->getParent())
        tmp = item->getParent()->__getIndexOfThing(item);

    PositionEx posEx(pos, tmp);
    Action* action = NULL;
    if((action = getAction(item, ACTION_UNIQUEID)))
    {
        if(executeUse(action, player, item, posEx, creatureId))
            return RET_NOERROR;
    }

    if((action = getAction(item, ACTION_ACTIONID)))
    {
        if(executeUse(action, player, item, posEx, creatureId))
            return RET_NOERROR;
    }

    if((action = getAction(item, ACTION_ITEMID)))
    {
        if(executeUse(action, player, item, posEx, creatureId))
            return RET_NOERROR;
    }

    if((action = getAction(item, ACTION_RUNEID)))
    {
        if(executeUse(action, player, item, posEx, creatureId))
            return RET_NOERROR;
    }

    if(defaultAction)
    {
        if(executeUse(defaultAction, player, item, posEx, creatureId))
            return RET_NOERROR;
    }

    if(BedItem* bed = item->getBed())
    {
        if(!bed->canUse(player))
            return RET_CANNOTUSETHISOBJECT;

        bed->sleep(player);
        return RET_NOERROR;
    }

    if(Container* container = item->getContainer())
    {
        if(container->getCorpseOwner() && !player->canOpenCorpse(container->getCorpseOwner())
            && g_config.getBool(ConfigManager::CHECK_CORPSE_OWNER))
            return RET_YOUARENOTTHEOWNER;

        Container* tmpContainer = NULL;
        if(Depot* depot = container->getDepot())
        {
            if(player->hasFlag(PlayerFlag_CannotPickupItem))
                return RET_CANNOTUSETHISOBJECT;

            if(Depot* playerDepot = player->getDepot(depot->getDepotId(), true))
            {
                player->useDepot(depot->getDepotId(), true);
                playerDepot->setParent(depot->getParent());
                tmpContainer = playerDepot;
            }
        }

        if(!tmpContainer)
            tmpContainer = container;

        int32_t oldId = player->getContainerID(tmpContainer);
        if(oldId != -1)
        {
            player->onCloseContainer(tmpContainer);
            player->closeContainer(oldId);
        }
        else
        {
            player->addContainer(index, tmpContainer);
            player->onSendContainer(tmpContainer);
        }

        return RET_NOERROR;
    }

    if(item->isReadable())
    {
        if(item->canWriteText())
        {
            player->setWriteItem(item, item->getMaxWriteLength());
            player->sendTextWindow(item, item->getMaxWriteLength(), true);
        }
        else
        {
            player->setWriteItem(NULL);
            player->sendTextWindow(item, 0, false);
        }

        return RET_NOERROR;
    }

    const ItemType& it = Item::items[item->getID()];
    if(it.transformUseTo)
    {
        g_game.transformItem(item, it.transformUseTo);
        g_game.startDecay(item);
        return RET_NOERROR;
    }

    if(item->isPremiumScroll())
    {
        std::ostringstream ss;
        ss << " You have recived " << it.premiumDays << " premium days.";
        player->sendTextMessage(MSG_INFO_DESCR, ss.str());

        player->addPremiumDays(it.premiumDays);
        g_game.internalRemoveItem(NULL, item, 1);
        return RET_NOERROR;
    }

    return RET_CANNOTUSETHISOBJECT;
}

bool Actions::useItem(Player* player, const Position& pos, uint8_t index, Item* item)
{
    if(!player->canDoAction())
        return false;

    player->setNextActionTask(NULL);
    player->stopWalk();
    player->setNextAction(OTSYS_TIME() + g_config.getNumber(ConfigManager::ACTIONS_DELAY_INTERVAL) - 10);

    ReturnValue ret = internalUseItem(player, pos, index, item, 0);
    if(ret == RET_NOERROR)
        return true;

    player->sendCancelMessage(ret);
    return false;
}

bool Actions::executeUseEx(Action* action, Player* player, Item* item, const PositionEx& fromPosEx,
    const PositionEx& toPosEx, bool isHotkey, uint32_t creatureId)
{
    return (action->executeUse(player, item, fromPosEx, toPosEx, isHotkey,
        creatureId) || action->hasOwnErrorHandler());
}

ReturnValue Actions::internalUseItemEx(Player* player, const PositionEx& fromPosEx, const PositionEx& toPosEx,
    Item* item, bool isHotkey, uint32_t creatureId)
{
    Action* action = NULL;
    if((action = getAction(item, ACTION_UNIQUEID)))
    {
        ReturnValue ret = action->canExecuteAction(player, toPosEx);
        if(ret != RET_NOERROR)
            return ret;

        //only continue with next action in the list if the previous returns false
        if(executeUseEx(action, player, item, fromPosEx, toPosEx, isHotkey, creatureId))
            return RET_NOERROR;
    }

    if((action = getAction(item, ACTION_ACTIONID)))
    {
        ReturnValue ret = action->canExecuteAction(player, toPosEx);
        if(ret != RET_NOERROR)
            return ret;

        //only continue with next action in the list if the previous returns false
        if(executeUseEx(action, player, item, fromPosEx, toPosEx, isHotkey, creatureId))
            return RET_NOERROR;

    }

    if((action = getAction(item, ACTION_ITEMID)))
    {
        ReturnValue ret = action->canExecuteAction(player, toPosEx);
        if(ret != RET_NOERROR)
            return ret;

        //only continue with next action in the list if the previous returns false
        if(executeUseEx(action, player, item, fromPosEx, toPosEx, isHotkey, creatureId))
            return RET_NOERROR;
    }

    if((action = getAction(item, ACTION_RUNEID)))
    {
        ReturnValue ret = action->canExecuteAction(player, toPosEx);
        if(ret != RET_NOERROR)
            return ret;

        //only continue with next action in the list if the previous returns false
        if(executeUseEx(action, player, item, fromPosEx, toPosEx, isHotkey, creatureId))
            return RET_NOERROR;
    }

    if(defaultAction)
    {
        ReturnValue ret = defaultAction->canExecuteAction(player, toPosEx);
        if(ret != RET_NOERROR)
            return ret;

        //only continue with next action in the list if the previous returns false
        if(executeUseEx(defaultAction, player, item, fromPosEx, toPosEx, isHotkey, creatureId))
            return RET_NOERROR;
    }

    return RET_CANNOTUSETHISOBJECT;
}

bool Actions::useItemEx(Player* player, const Position& fromPos, const Position& toPos,
    uint8_t toStackPos, Item* item, bool isHotkey, uint32_t creatureId/* = 0*/)
{
    if(!player->canDoAction())
        return false;

    player->setNextActionTask(NULL);
    player->stopWalk();
    player->setNextAction(OTSYS_TIME() + g_config.getNumber(ConfigManager::EX_ACTIONS_DELAY_INTERVAL) - 10);

    int32_t fromStackPos = 0;
    if(item->getParent())
        fromStackPos = item->getParent()->__getIndexOfThing(item);

    PositionEx fromPosEx(fromPos, fromStackPos);
    PositionEx toPosEx(toPos, toStackPos);

    ReturnValue ret = internalUseItemEx(player, fromPosEx, toPosEx, item, isHotkey, creatureId);
    if(ret == RET_NOERROR)
        return true;

    player->sendCancelMessage(ret);
    return false;
}

Action::Action(LuaInterface* _interface):
Event(_interface)
{
    allowFarUse = false;
    checkLineOfSight = true;
}

Action::Action(const Action* copy):
Event(copy)
{
    allowFarUse = copy->allowFarUse;
    checkLineOfSight = copy->checkLineOfSight;
}

bool Action::configureEvent(xmlNodePtr p)
{
    std::string strValue;
    if(readXMLString(p, "allowfaruse", strValue) || readXMLString(p, "allowFarUse", strValue))
        setAllowFarUse(booleanString(strValue));

    if(readXMLString(p, "blockwalls", strValue) || readXMLString(p, "blockWalls", strValue))
        setCheckLineOfSight(booleanString(strValue));

    return true;
}

ReturnValue Action::canExecuteAction(const Player* player, const Position& pos)
{
    if(player->hasCustomFlag(PlayerCustomFlag_CanUseFar))
        return RET_NOERROR;

    if(!getAllowFarUse())
        return g_actions->canUse(player, pos);

    return g_actions->canUseFar(player, pos, getCheckLineOfSight());
}

bool Action::executeUse(Player* player, Item* item, const PositionEx& fromPos, const PositionEx& toPos, bool extendedUse, uint32_t)
{
    //onUse(cid, item, fromPosition, itemEx, toPosition)
    if(m_interface->reserveEnv())
    {
        ScriptEnviroment* env = m_interface->getEnv();
        if(m_scripted == EVENT_SCRIPT_BUFFER)
        {
            env->setRealPos(player->getPosition());
            std::ostringstream scriptstream;

            scriptstream << "local cid = " << env->addThing(player) << std::endl;
            env->streamThing(scriptstream, "item", item, env->addThing(item));
            env->streamPosition(scriptstream, "fromPosition", fromPos, fromPos.stackpos);

            Thing* thing = g_game.internalGetThing(player, toPos, toPos.stackpos);
            if(thing && (thing != item || !extendedUse))
            {
                env->streamThing(scriptstream, "itemEx", thing, env->addThing(thing));
                env->streamPosition(scriptstream, "toPosition", toPos, toPos.stackpos);
            }
            else
            {
                env->streamThing(scriptstream, "itemEx", NULL, 0);
                env->streamPosition(scriptstream, "toPosition", PositionEx());
            }

            if(m_scriptData)
                scriptstream << *m_scriptData;

            bool result = true;
            if(m_interface->loadBuffer(scriptstream.str()))
            {
                lua_State* L = m_interface->getState();
                result = m_interface->getGlobalBool(L, "_result", true);
            }

            m_interface->releaseEnv();
            return result;
        }
        else
        {
            #ifdef __DEBUG_LUASCRIPTS__
            std::ostringstream desc;
            desc << player->getName() << " - " << item->getID() << " " << fromPos << "|" << toPos;
            env->setEvent(desc.str());
            #endif

            env->setScriptId(m_scriptId, m_interface);
            env->setRealPos(player->getPosition());

            lua_State* L = m_interface->getState();
            m_interface->pushFunction(m_scriptId);

            lua_pushnumber(L, env->addThing(player));
            LuaInterface::pushThing(L, item, env->addThing(item));
            LuaInterface::pushPosition(L, fromPos, fromPos.stackpos);

            Thing* thing = g_game.internalGetThing(player, toPos, toPos.stackpos);
            if(thing && (thing != item || !extendedUse))
            {
                LuaInterface::pushThing(L, thing, env->addThing(thing));
                LuaInterface::pushPosition(L, toPos, toPos.stackpos);
            }
            else
            {
                LuaInterface::pushThing(L, NULL, 0);
                LuaInterface::pushPosition(L, PositionEx());
            }

            bool result = m_interface->callFunction(5);
            m_interface->releaseEnv();
            return result;
        }
    }
    else
    {
        std::clog << "[Error - Action::executeUse]: Call stack overflow." << std::endl;
        return false;
    }
}
 

 

 

 

Preciso deixar você ciente, a edição que vou fazer vai remover o exhausted ExActions dos items que você me mandar, ai você vai ter que adicionar exhausted via script nos items que precisarem, ok?


 

 

 

Nós somos aquilo que fazemos repetidamente. Excelência, não é um modo de agir, mas um hábito.

                                                                                                                                                                                                                                        Aristóteles 

Share this post


Link to post
Share on other sites
12 horas atrás, You Know Nothing disse:

@WooX OK

 

Mais 1 coisa que esqueci de falar, isso não vai afetar o push de perto por ele ter delay, mas vai permitir o player puxar a distancia, mover items, abrir loot, etc enquanto estiver usando potion e outros items. Me envia os IDs de todos items que você quer que não afete essas ações.


 

 

 

Nós somos aquilo que fazemos repetidamente. Excelência, não é um modo de agir, mas um hábito.

                                                                                                                                                                                                                                        Aristóteles 

Share this post


Link to post
Share on other sites

@WooX O push a distancia, já funciona assim como eu quero, o problema é o push de perto que é impossivel de faze, me da só o exemplo de como fazer com 1 id que o resto eu adiciono, pra voce nao ter muito trabalho.

Share this post


Link to post
Share on other sites
9 horas atrás, You Know Nothing disse:

@WooX O push a distancia, já funciona assim como eu quero, o problema é o push de perto que é impossivel de faze, me da só o exemplo de como fazer com 1 id que o resto eu adiciono, pra voce nao ter muito trabalho.

 

Impossível não é, mas acredito que não seja uma tarefa fácil. Como falei antes, minha alteração não vai afetar o push de perto (a não ser que você deixe ele sem delay), então acho que seria inútil pra você.


 

 

 

Nós somos aquilo que fazemos repetidamente. Excelência, não é um modo de agir, mas um hábito.

                                                                                                                                                                                                                                        Aristóteles 

Share this post


Link to post
Share on other sites
Em 30/03/2019 em 08:43, WooX disse:

Impossível não é, mas acredito que não seja uma tarefa fácil. Como falei antes, minha alteração não vai afetar o push de perto (a não ser que você deixe ele sem delay), então acho que seria inútil pra você.

 

estou seguindo o topico e interessante!!!!

Share this post


Link to post
Share on other sites
Em 28/03/2019 em 21:40, WooX disse:

Preciso deixar você ciente, a edição que vou fazer vai remover o exhausted ExActions dos items que você me mandar, ai você vai ter que adicionar exhausted via script nos items que precisarem, ok?

Qual é a tal mudança? Eu preciso fazer isso também e já estou com os IDS dos items.... Por favor, concluam o tópico @WooX

Share this post


Link to post
Share on other sites
20 horas atrás, Mecianosz disse:

Qual é a tal mudança? Eu preciso fazer isso também e já estou com os IDS dos items.... Por favor, concluam o tópico @WooX

 


 

 

 

Nós somos aquilo que fazemos repetidamente. Excelência, não é um modo de agir, mas um hábito.

                                                                                                                                                                                                                                        Aristóteles 

Share this post


Link to post
Share on other sites
42 minutos atrás, Mecianosz disse:

Eu ia te dar REP, mas não posso mais hoje.. Vou tentar lembrar de te dar REP amanhã. Obrigadão, amigo.

Conseguiu compilar sem erro bro?

Poderia dar uma ajuda no outro topico?

Agradeço muito.

Share this post


Link to post
Share on other sites
Agora, Guizek69 disse:

Conseguiu compilar sem erro bro?

Poderia dar uma ajuda no outro topico?

Agradeço muito.

Ainda não consegui compilar, estou tentando. Qual tópico?

Share this post


Link to post
Share on other sites
2 minutos atrás, Mecianosz disse:

Ainda não consegui compilar, estou tentando. Qual tópico?

Eu tambem nao.
O topico que o @WooX te direcionou com a resposta.

Share this post


Link to post
Share on other sites
Em 29/06/2020 em 11:48, WooX disse:

 

Caro @WooX, tenho duas perguntas:

1. O que eu preciso modificar nos scripts desses items para compensar o exhaust removido da source?

2. Meu config.lua apresenta algumas linhas e gostaria de saber se não dá para mexer por aqui:

     timeBetweenActions = 200

     timeBetweenExActions = 1000

     timeBetweenCustomActions = 500

 

Prometo que vou te dar 1 REP por dia porque está me ajudando bastante kkk.. Valeuu

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Similar Content

    • By Lisbeky
      .Qual servidor ou website você utiliza como base? 
      0.36
       
      Boa noite pessoal!
       
      Então, mais uma vez venho pedir ajuda... pesquisei bastante aqui no fórum e encontrei um script, testei e não deu certo, mas estarei postando aqui para quem sabe alguém solucionar o problema.
       
      o script ele faz um monstro X ao chegar aos 50% de life , ele se transforma em outro monstro Y, mas também queria ele dando storage para todos os players que atacarem ele...
       
      o que esta errado? 
      então não da erro na distro, nem quando ligo o servidor e nem quando mato o boss. mas o problema esta quando chega na metade da vida do primeiro boss, ele não aparece o outro, logo, não esta dando a storage também.
       
      obs: já pedi um suporte de um script que os playrs matam o boss e recebem a storage, esta corretíssimo funcionando, mas esse aqui é diferente, então atenção, não estou pedindo a mesma coisa :D
       
      então o script esta assim...
       
       function onStatsChange(cid, attacker, type, combat, value) local storage = 47000 local stor = 354867 -- n mexa local monster = "Phanta" -- Monstro que irá atingir o 50% e sumir local monstro = "Demo" -- Monstro que irá ser invocado local msg = "Enough playing. I am the Divinity of this house." -- Mensagem quando o monstro for sumir if not isMonster(cid) then return true end if type == STATSCHANGE_HEALTHLOSS and getCreatureName(cid):lower() == monster:lower() then local monsterPercent = 100/(getCreatureMaxHealth(cid)/getCreatureHealth(cid)) if monsterPercent <= 50 and monsterPercent >= 49 then if getGlobalStorageValue(stor) - os.time() <= 0 then doCreatureSay(cid, msg, 1) setGlobalStorageValue(stor, os.time() + 120) addEvent(doCreateMonster, 1000, monstro, getCreaturePosition(cid)) addEvent(doRemoveCreature, 1000, cid) for _, check in pairs(deathList) do if isPlayer(check) then setPlayerStorageValue(check, storage, 5) end end end end end return true end  
       
       
    • By Doidodepeda
      Entao galera, tenho esse script de top level que fica aparecendo na tela do player.
      queria saber se alguem pode modificar pra aparacer os resetes no lugar do level.
       
      Script:

      function onThink(interval, lastExecution)
          local max, query = 5, db.getResult("SELECT `name`, `level` FROM `players` WHERE `id` > 6 AND `group_id` < 2 ORDER BY `level` DESC, `name` ASC;")
          local str = "TOP Rank Level do Server:\n"
          if (query:getID() ~= -1) then 
              k = 1 
              while true do
                  str = str .. "\n " .. k .. " - "..query:getDataString("name").." - ["..query:getDataInt("level").."]"
                  k = k + 1
                  if not(query:next()) or k > max then
                      break 
                  end 
              end 
              query:free()
          end
          doBroadcastMessage(str, 22)
          return true
      end
       
       
       
      Sistema de resete que uso:
       
       
    • By Senju uchira
      ola gostaria de tira uma duvida e fazer um pedido ao mesmo tempo-se possivel;
      e possivel o sumon x usa a spell com um comando, exemplo ; eu faço ele usa a spell com o comando X etals. como faço
       
    • By shanden4502
      Boa noite, então eu tenho esse codigo:
       
      local STORAGE_SKILL_LEVEL = 10009 local STORAGE_SKILL_TRY = 10007 local config = { levels = { {level = {0,9}, quant = {1,1}, percent = 5}, {level = {10,19}, quant = {1,1}, percent = 10}, {level = {20,29}, quant = {1,1}, percent = 15}, {level = {30,39}, quant = {1,1}, percent = 20}, {level = {40,49}, quant = {1,1}, percent = 25}, {level = {50,59}, quant = {1,1}, percent = 30}, {level = {60,69}, quant = {1,1}, percent = 30}, {level = {70,79}, quant = {1,1}, percent = 35}, {level = {80,89}, quant = {1,1}, percent = 35}, {level = {90,99}, quant = {1,1}, percent = 40}, {level = {100}, quant = {1,1}, percent = 50} }, rocks = {5092}, -- Id das rochas que podem ser quebradas rocks2 = {5093}, rocks3 = {5094}, rocks4 = {5095}, stones = {5097}, -- Modelo = {rock_id, rock_id} stones2 = {5099}, stones3 = {5100}, stones4 = {5098}, rock_delay = 60, -- Tempo de volta da rocha (Em segundos) bonus_chance = 3, -- Chance (em porcentagem) de se conseguir um bonus de exp bonus_exp = 1 -- Bonus extra } ------------------------------------ -- END Configurations --- ------------------------------------ function getCuttingLevel(cid) return getPlayerStorageValue(cid, STORAGE_SKILL_LEVEL) end function setPlayerCuttingLevel(cid, n) setPlayerStorageValue(cid, STORAGE_SKILL_LEVEL, n) end function addCuttingLevel(cid, n) setPlayerCuttingLevel(cid, getCuttingLevel(cid) + (isNumber(n) and n or 1)) setCuttingTry(cid, 0) end function getCuttingInfo(cid) for i = 1, #config.levels do min = config.levels[i].level[1]; max = config.levels[i].level[2] if (getCuttingLevel(cid) >= min and getCuttingLevel(cid) <= max) then return {quantity = {min = config.levels[i].quant[1], max = config.levels[i].quant[2]}, chance = config.levels[i].percent} end end end function getStoneByRock(rockid) for i = 1, #config.stones do if (config.stones[2] == rockid) then return config.stones[1] elseif (config.stones2[3] == rockid2) then return config.stones2[4] end end end function getCuttingTries(cid) return getPlayerStorageValue(cid, STORAGE_SKILL_TRY) end function setCuttingTry(cid, n) setPlayerStorageValue(cid, STORAGE_SKILL_TRY, n) end function addCuttingTry(cid, bonus) setCuttingTry(cid, getCuttingTries(cid) + 1 + (bonus and config.bonus_exp or 0)) if (getCuttingTries(cid) >= getCuttingExpTo(getCuttingLevel(cid))) then -- Up doPlayerSendTextMessage(cid, 22, "You advanced from level " .. getCuttingLevel(cid) .. " to level ".. (getCuttingLevel(cid) + 1) .." in miner.") if ((getCuttingLevel(cid)+1) == getCuttingMaxLevel()) then doPlayerSendTextMessage(cid, 22, "Max level reached in miner.") end addCuttingLevel(cid) doSendMagicEffect(getCreaturePosition(cid), math.random(28,30)) setCuttingTry(cid, 0) end end function getCuttingExpTo(level) return ((level*1.5)+((level+1)*7)) end function getCuttingMaxLevel() return config.levels[#config.levels].level[#config.levels[#config.levels].level] end --------------------------- function onUse(cid, item, fromPosition, itemEx, toPosition) rock = { id = itemEx.itemid, uid = itemEx.uid, position = toPosition } player = { position = getCreaturePosition(cid) } if (getCuttingLevel(cid) < 0) then setPlayerCuttingLevel(cid, 0) end if (isInArray(config.rocks, rocks2, rocks3, rocks4, rock.id, rock.id2, rock.id3, rock.id4)) then addCuttingTry(cid) if (math.random(1,100) <= getCuttingInfo(cid).chance) then local collected = math.random(getCuttingInfo(cid).quantity.min, getCuttingInfo(cid).quantity.max) doPlayerAddItem(cid, getStoneByRock(rock.id), collected) doPlayerSendTextMessage(cid, 22, "You got " .. collected .. " brass" .. (collected > 1 and "s" or "") .. " ore.") if (math.random(1,100) <= config.bonus_chance) then -- Bonus calc addCuttingTry(cid, true) doSendAnimatedText(player.position, "Bonus!", COLOR_ORANGE) end event_rockCut(rock) else if (math.random(0,100) <= (0-getCuttingInfo(cid).chance/0)) then doPlayerSendTextMessage(cid, 22, "You got nothing.") event_rockCut(rock) else doSendMagicEffect(rock.position, 3) doSendAnimatedText(rock.position, "Poff!", COLOR_GREEN) end end else doPlayerSendCancel(cid, "This can't be cut.") end end function event_rockCut(rock) addEvent(event_rockGrow, config.rock_delay * 1000, rock.position, rock.id) doTransformItem(rock.uid, 5104) doSendMagicEffect(rock.position, 3) doSendAnimatedText(rock.position, "Tack!", COLOR_GREEN) doItemSetAttribute(rock.uid, "name", "A trunk of " .. getItemNameById(rock.id)) end function event_rockGrow(rockPos, old_id) local rock = getThingFromPos(rockPos).uid doTransformItem(rock, old_id) doItemSetAttribute(rock, "name", getItemNameById(old_id)) doSendMagicEffect(rockPos, 3) end eu estou tentando editar para que dependendo da pedra, exemplo, 5092, venha o minerio 5097 e somente ele, eu tentei:
       
      if (config.stones[2] == rockid) then return config.stones[1] elseif (config.stones2[3] == rockid2) then return config.stones2[4] end mas não estou tendo resultado nenhum, nem erro, alguem poderia me dar uma luz?
    • By Lisbeky
      Boa noite galera! 
       
      Postei cedo sobre esse script, a duvida foi sanada, mas surgiu outro problema depois que teste.
       
      esse script serve para setar uma storage e criar um tp de saída para quando o boss for morto e isso esta acontecendo certinho, mas existe um problema, ele esta setando somente para o player que mata o boss e não para o time inteiro.
       
      Então gostaria de pedir o suporte a vocês. Será que da para por o storage para setar para todos os players dentro de uma determinada área?
       
      por exemplo usar, frompos e topos da área e fazer com que todos os players dentro desta posição , após matar o boss todos setarem a storage (46000, 5)
       
      Meus sinceros agradecimentos a todos do TibiaKing!
       
      local tps = { ["hyaena"] = {pos = {x=349, y=1103, z=15}, toPos = {x = 518, y = 840, z = 7}, time = 10, storage = 46000}, } local storage = 46000 local function removeTp(tp) local t = getTileItemById(tp.pos, 5023).uid return t > 0 and doRemoveItem(t) and doSendMagicEffect(tp.pos, CONST_ME_POFF) end function onKill(cid, target) local tp = tps[getCreatureName(target)] if tp then setPlayerStorageValue(cid, tp.storage, 5) doCreateTeleport(5023, tp.toPos, tp.pos) doCreatureSay(target, "O teleport irá sumir em "..tp.time.." segundos.", TALKTYPE_ORANGE_1) addEvent(removeTp, tp.time*1000, tp) end return true end   
       
       
  • Recently Browsing   0 members

    No registered users viewing this page.


Open Tibia Server

Quer aprender a criar seu próprio servidor de Tibia? Então está no lugar certo, aqui você encontrará milhares de tutorias, scripts, códigos, mapas e utilitários para que você possa fazer o seu próprio servidor de Tibia começando do zero.

Redes Sociais

Anuncie no Tibia King

Precisa de mais visibilidade em seus projetos? Quer fazer um plano publicitário para o seu servidor? Anuncie no Tibia King e faça sua divulgação, possuímos centenas de acessos simultâneos e milhares diários, com certeza será a sua solução!

Tibia King Recomenda

DokeHost - Soluções em Hospedagem

VPS Windows
VPS Linux
Servidor VPS
×
×
  • Create New...