Ele basicamente oferece todas as informações que você precisa e é mais avançado que o onThrow padrão ().
Vamos Começar:
Em Creatureevent.cpp:
Procure por:
else if(tmpStr == "preparedeath") m_type = CREATURE_EVENT_PREPAREDEATH;
Adicione abaxio:
else if(tmpStr == "moveitem") m_type = CREATURE_EVENT_MOVEITEM;
Procure por:
case CREATURE_EVENT_PREPAREDEATH: return "onPrepareDeath";
Adicione abaixo:
case CREATURE_EVENT_MOVEITEM: return "onMoveItem";
Procure por:
case CREATURE_EVENT_PREPAREDEATH: return "cid, deathList";
Adicione abaixo:
case CREATURE_EVENT_MOVEITEM: return "cid, item, count, toContainer, fromContainer, fromPos, toPos";
Procure por:
uint32_t CreatureEvent::executePrepareDeath(Creature* creature, DeathList deathList)
{
//onPrepareDeath(cid, deathList)
if(m_interface->reserveEnv())
{
ScriptEnviroment* env = m_interface->getEnv();
if(m_scripted == EVENT_SCRIPT_BUFFER)
{
env->setRealPos(creature->getPosition());
std::stringstream scriptstream;
scriptstream << "local cid = " << env->addThing(creature) << std::endl;
scriptstream << "local deathList = {}" << std::endl;
for(DeathList::iterator it = deathList.begin(); it != deathList.end(); ++it)
{
scriptstream << "deathList:insert(";
if(it->isCreatureKill())
scriptstream << env->addThing(it->getKillerCreature());
else
scriptstream << it->getKillerName();
scriptstream << ")" << std::endl;
}
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[35];
sprintf(desc, "%s", creature->getName().c_str());
env->setEventDesc(desc);
#endif
env->setScriptId(m_scriptId, m_interface);
env->setRealPos(creature->getPosition());
lua_State* L = m_interface->getState();
m_interface->pushFunction(m_scriptId);
lua_pushnumber(L, env->addThing(creature));
lua_newtable(L);
DeathList::iterator it = deathList.begin();
for(int32_t i = 1; it != deathList.end(); ++it, ++i)
{
lua_pushnumber(L, i);
if(it->isCreatureKill())
lua_pushnumber(L, env->addThing(it->getKillerCreature()));
else
lua_pushstring(L, it->getKillerName().c_str());
lua_settable(L, -3);
}
bool result = m_interface->callFunction(2);
m_interface->releaseEnv();
return result;
}
}
else
{
std::cout << "[Error - CreatureEvent::executePrepareDeath] Excesso de pilha de chamadas." << std::endl;
return 0;
}
}
Adicione abaixo:
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)); m_interface->pushThing(L, item, env->addThing(item)); lua_pushnumber(L, count); m_interface->pushThing(L, toContainer, env->addThing(toContainer)); m_interface->pushThing(L, fromContainer, env->addThing(fromContainer)); m_interface->pushPosition(L, fromPos, fstack); m_interface->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; } }
Em creatureevent.h
Procure por:
uint32_t executePrepareDeath(Creature* creature, DeathList deathList);
Adicione abaixo:
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
Adicione:
CREATURE_EVENT_PREPAREDEATH, CREATURE_EVENT_MOVEITEM
Em game.cpp
Procure por:
if(!canThrowObjectTo(mapFromPos, mapToPos) && !player->hasCustomFlag(PlayerCustomFlag_CanThrowAnywhere)) { player->sendCancelMessage(RET_CANNOTTHROW); return false; }
Adicione abaixo:
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;
Exemplo de uso:
Em data/creaturescripts/creaturescripts.xml
Adicione:
<event type="moveitem" name="MoveItem" event="script" value="moveitem.lua"/>
Crie um script na pasta data/creaturescripts/scripts/
Chamado moveitem.lua
Adicione:
function onMoveItem(cid, item, count, toContainer, fromContainer, fromPos, toPos) if item.actionid == 1000 then return false end return true end
Em data/creaturescripts/scripts/login.lua:
Adicione:
registerCreatureEvent(cid, "MoveItem")
-> Bloquear itens com actionid 1000 de serem movidos (exemplo realmente simples)