Ir para conteúdo

Featured Replies

Postado
  • Este é um post popular.

Notei que alguns membros precisavam desse creature event pra desenvolver alguns sistemas, então eu resolvi compartilhá-lo com vocês.



Na source, em creatureevent.cpp



Abaixo de:

else if(tmpStr == "preparedeath")
    m_type = CREATURE_EVENT_PREPAREDEATH;


 

Adicione:

else if(tmpStr == "moveitem")
    m_type = CREATURE_EVENT_MOVEITEM;


 

Abaixo de:

case CREATURE_EVENT_PREPAREDEATH:
    return "onPrepareDeath";


 

Adicione:

case CREATURE_EVENT_MOVEITEM:
    return "onMoveItem";


 

Abaixo de:

case CREATURE_EVENT_PREPAREDEATH:
    return "cid, deathList";


 

Adicione:

case CREATURE_EVENT_MOVEITEM:
	return "cid, item, count, toContainer, fromContainer, fromPos, toPos";


 

Antes de:

bool CreatureEvents::playerLogout(Player* player, bool forceLogout)


 

Adicione:

uint32_t CreatureEvent::executeMoveItem(Player* player, Item* item, uint8_t count, const Position& fromPos, const Position& toPos, Item* toContainer, Item* fromContainer, int16_t fstack)
{
    //onMoveItem(cid, item, count, toContainer, fromContainer, fromPos, toPos)
    if(m_interface->reserveEnv())
    {
        ScriptEnviroment* env = m_interface->getEnv();
        if(m_scripted == EVENT_SCRIPT_BUFFER)
        {
            env->setRealPos(player->getPosition());
            std::stringstream scriptstream;
            scriptstream << "local cid = " << env->addThing(player) << std::endl;

            env->streamThing(scriptstream, "item", item, env->addThing(item));
            scriptstream << "local count = " << count << std::endl;
            env->streamThing(scriptstream, "toContainer", toContainer, env->addThing(toContainer));
            env->streamThing(scriptstream, "fromContainer", fromContainer, env->addThing(fromContainer));
            env->streamPosition(scriptstream, "fromPos", fromPos, fstack);
            env->streamPosition(scriptstream, "toPos", toPos, 0);


            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__
            char desc[30];
            sprintf(desc, "%s", player->getName().c_str());
            env->setEvent(desc);
            #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));
            lua_pushnumber(L, count);
            LuaInterface::pushThing(L, toContainer, env->addThing(toContainer));
            LuaInterface::pushThing(L, fromContainer, env->addThing(fromContainer));
            LuaInterface::pushPosition(L, fromPos, fstack);
                        LuaInterface::pushPosition(L, toPos, 0);

            bool result = m_interface->callFunction(7);
            m_interface->releaseEnv();
            return result;
        }
    }
    else
    {
        std::clog << "[Error - CreatureEvent::executeMoveItem] Call stack overflow." << std::endl;
        return 0;
    }
}



 

Agora, em creatureevent.h


Abaixo de:

uint32_t executePrepareDeath(Creature* creature, DeathList deathList);


 

Adicione:

uint32_t executeMoveItem(Player* player, Item* item, uint8_t count, const Position& fromPos, const Position& toPos, Item* toContainer, Item* fromContainer, int16_t fstack);


 

Procure por:

CREATURE_EVENT_PREPAREDEATH


 

Substitua por:

CREATURE_EVENT_PREPAREDEATH,
CREATURE_EVENT_MOVEITEM



 

E em game.cpp


Depois de:

if(!canThrowObjectTo(mapFromPos, mapToPos) && !player->hasCustomFlag(PlayerCustomFlag_CanThrowAnywhere))
{
    player->sendCancelMessage(RET_CANNOTTHROW);
    return false;
}


 

Adicione:

bool success = true;
CreatureEventList moveitemEvents = player->getCreatureEvents(CREATURE_EVENT_MOVEITEM);
for(CreatureEventList::iterator it = moveitemEvents.begin(); it != moveitemEvents.end(); ++it)
{
    Item* toContainer = toCylinder->getItem();
    Item* fromContainer = fromCylinder->getItem();
    if(!(*it)->executeMoveItem(player, item, count, fromPos, toPos, (toContainer ? toContainer : 0), (fromContainer ? fromContainer : 0), fromStackpos) && success)
        success = false;
}

if(!success)
    return false;



 

Um exemplo BEM simples do uso desse creature event:



Tag:

<event type="moveitem" name="MoveItem" event="script" value="moveitem.lua"/>



 

moveitem.lua

function onMoveItem(cid, item, count, toContainer, fromContainer, fromPos, toPos)
    local item = 12345
    if item.itemid == item and getPlayerAccess(cid) < 4 then
        return doPlayerSendCancel(cid, 'You are not allowed to move this item.') and false
    end
    
    return true
end

Nessa estrutura de controle, se o item for o de ID 12345 e o cid tiver acesso menor do que 4, retornará false e ele não poderá mover o item.
Se não for o caso, a checagem feita será false e retornará true, então o cid poderá mover o item.




Esse callback registra creature event?
Sim:

registerCreatureEvent(cid, "MoveItem")

 

Créditos: Summ.

Editado por Suicide (veja o histórico de edições)

The corrupt fear us.

The honest support us.

The heroic join us.

  • Respostas 9
  • Visualizações 4.1k
  • Created
  • Última resposta

Top Posters In This Topic

Most Popular Posts

  • @Noynac Se for TFS 1.0+ você pode fazer isso em "data/events/scripts/player" no evento onMoveItem.

Postado

Bem interessante seu sistema, Então caso seja falto o player não pode mover o item? mesmo tentando mover dentro da própria backpack ?

O mesmo BananaFight, mais com um novo Nick.

 

 
Abra sua mente, sangue suga não vive sem um hospedeiro, Não faça script para os outros, ensine-os a fazer.
Postado

então, fiz tudo bonitinho como ta ai, compilou tudo certinho, e agora, alguem consegue me ajudar com um script para que a bp com id XXXX só receba potions e empty potions?

Eu que não fumo, queria um cigarro
Eu que não amo você
Envelheci dez anos ou mais
Nesse último mês
Eu que não bebo, pedi um conhaque
Pra enfrentar o inverno
Que entra pela porta
Que você deixou aberta ao sair
avatar_1218.gif

Participe da conversa

Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.

Visitante
Responder

Quem Está Navegando 0

  • Nenhum usuário registrado visualizando esta página.

Estatísticas dos Fóruns

  • Tópicos 96.9k
  • Posts 519.6k

Informação Importante

Confirmação de Termo