Ir para conteúdo

onDropLoot(cid, item)


caotic

Posts Recomendados

Ola galera xtibianaaa.

Event droploot acontece quando um monstro ou player dropa 1 item.

 

Vamos la:

 

Vá em creatureevent.cpp e procure:

bool CreatureEvents::playerLogin(Player* player)
{
//fire global event if is registered
bool result = true;
for(CreatureEventList::iterator it = m_creatureEvents.begin(); it != m_creatureEvents.end(); ++it)
{
if(it->second->getEventType() == CREATURE_EVENT_LOGIN &&
!it->second->executeLogin(player) && result)
result = false;
}


return result;
}

Logo em seguida coloque:

bool CreatureEvents::dropLoot(Creature* creature, Item* item)
{
bool result = true;
for(CreatureEventList::iterator it = m_creatureEvents.begin(); it != m_creatureEvents.end(); ++it)
{
if(it->second->getEventType() == CREATURE_EVENT_DROPLOOT &&
!it->second->executeDropLoot(creature, item))
result = false;
}


return result;
}

Procure:

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

Coloque em seguida:

else if(tmpStr == "droploot")
m_type = CREATURE_EVENT_DROPLOOT;

Logo apos procure:

case CREATURE_EVENT_PREPAREDEATH:
return "onPrepareDeath";

Coloque abaixo:

case CREATURE_EVENT_DROPLOOT:
return "onDropLoot";

Procure:

case CREATURE_EVENT_PREPAREDEATH:
return "cid, deathList";

Coloque embaixo:

case CREATURE_EVENT_DROPLOOT:
return "cid, item";

Procure:

uint32_t CreatureEvent::executeLogout(Player* player, bool forceLogout)
{
//onLogout(cid, forceLogout)
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;
scriptstream << "local forceLogout = " << (forceLogout ? "true" : "false") << 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", player->getName().c_str());
env->setEventDesc(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));
lua_pushboolean(L, forceLogout);


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

Coloque logo apos:

uint32_t CreatureEvent::executeDropLoot(Creature* creature, Item* item)
{
//onDropLoot(cid, item)
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;
            env->streamThing(scriptstream, "item", item, env->addThing(item));
  
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", player->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));
LuaScriptInterface::pushThing(L, item, env->addThing(item));          
bool result = m_interface->callFunction(2);
m_interface->releaseEnv();
return result;
}
}
else
{
std::cout << "[Error - CreatureEvent::executeDropLoot] Call stack overflow." << std::endl;
return 0;
}
}

Vá em creatureevent.h e procure:CREATURE_EVENT_PREPAREDEATH,

Coloque abaixo:

CREATURE_EVENT_DROPLOOT

Procure:

uint32_t executeTarget(Creature* creature, Creature* target);

Coloque abaixo:

uint32_t executeDropLoot(Creature* creature, Item* item);

Vá em player.h na função:

void Player::dropLoot(Container* corpse)

Troque por esta função:

void Player::dropLoot(Container* corpse)
{
if(!corpse || lootDrop != LOOT_DROP_FULL)
return;


uint32_t start = g_config.getNumber(ConfigManager::BLESS_REDUCTION_BASE), loss = lossPercent[LOSS_CONTAINERS], bless = getBlessings();
while(bless > 0 && loss > 0)
{
loss -= start;
start -= g_config.getNumber(ConfigManager::BLESS_REDUCTION_DECREAMENT);
bless--;
}


uint32_t itemLoss = (uint32_t)std::floor((5. + loss) * lossPercent[LOSS_ITEMS] / 1000.);
for(int32_t i = SLOT_FIRST; i < SLOT_LAST; ++i)
{            
Item* item = inventory[i];
if(!item)
continue;

Creature* creature = NULL;
    bool deny = false;item    creature = g_game.getCreatureByID(getID());
CreatureEventList droploot = getCreatureEvents(CREATURE_EVENT_DROPLOOT);
for(CreatureEventList::iterator it = droploot.begin(); it != droploot.end(); ++it)
{
if(!(*it)->executeDropLoot(this, item))
deny = true;
}
       if(!deny) {
  uint32_t rand = random_range(1, 100);
if(skull > SKULL_WHITE || (item->getContainer() && rand < loss) || (!item->getContainer() && rand < itemLoss))
{
g_game.internalMoveItem(NULL, this, corpse, INDEX_WHEREEVER, item, item->getItemCount(), 0);
sendRemoveInventoryItem((slots_t)i, inventory[(slots_t)i]);
     }
   }           
    }
}

Vá em monster.cpp e procure:

void MonsterType::dropLoot(Container* corpse)
{
Item* tmpItem = NULL;
for(LootItems::const_iterator it = lootItems.begin(); it != lootItems.end() && !corpse->full(); ++it)
{
uint32_t owner = corpse->getCorpseOwner();
    Creature* creature = g_game.getCreatureByID(owner);
if((tmpItem = createLoot(*it)) && g_creatureEvents->dropLoot(creature, tmpItem))
{
if(Container* container = tmpItem->getContainer())
{
if(createChildLoot(container, (*it)))
corpse->__internalAddThing(tmpItem);
else
delete container;
}
else
corpse->__internalAddThing(tmpItem);
}
}


corpse->__startDecaying();
uint32_t ownerId = corpse->getCorpseOwner();
if(!ownerId)
return;


Player* owner = g_game.getPlayerByID(ownerId);
if(!owner)
return;


LootMessage_t message = lootMessage;
if(message == LOOTMSG_IGNORE)
message = (LootMessage_t)g_config.getNumber(ConfigManager::LOOT_MESSAGE);


if(message < LOOTMSG_PLAYER)
return;


std::stringstream ss;
ss << "Loot of " << nameDescription << ": " << corpse->getContentDescription() << ".";
if(owner->getParty() && message > LOOTMSG_PLAYER)
owner->getParty()->broadcastMessage((MessageClasses)g_config.getNumber(ConfigManager::LOOT_MESSAGE_TYPE), ss.str());
else if(message == LOOTMSG_PLAYER || message == LOOTMSG_BOTH)
owner->sendTextMessage((MessageClasses)g_config.getNumber(ConfigManager::LOOT_MESSAGE_TYPE), ss.str());
}

Evento em uso:

function onDropLoot(cid, item)
local block = {2221, 1221, 2922}
for i=1, #block do
if item.itemid == block[i] then
return false
end
end

return true
end

 

 

 

Editado por caotic
Link para o comentário
Compartilhar em outros sites

 

Uma Dúvida, o que isso Exatamente faz?

 

Você pode usar isso por exemplo em 1 poketibia para avisar quando dropa 1 stone enviando 1 efeito para o personagem.

 

hmm, vlw

@topic

ótimo conteúdo, obrigado por trazerao xtibia.

 

@banana

pensei a mesma coisa

Link para o comentário
Compartilhar em outros sites

Só uma dúvida, isso não funciona em sources para poketibia não, certo?

eu tentei aqui mas da erro, e algumas das linhas que você pede pra procurar, nem existem nas sources do poketibia

Editado por xmaster0
Link para o comentário
Compartilhar em outros sites

Muito bom caotic. Acho que seria uma boa passar mais um parâmetro indicando de que creature o loot dropou.

Só funciona com creatures? Ou com players mortos também executa?

Ai eu te pergunto, porque diabos um gênio desses esta como "Assistente"...

Porque não sabe indentar kakakakak

 

 

Acho que daria para fazer um AutoLoot com essa função, enfim belo código :)

 

Exatamente, ou bloquear alguns itens em eventos especificos, ou trabalhar com a stamina por scripts e não pelas sources... inúmeras possibilidades :)

Link para o comentário
Compartilhar em outros sites

 

Acho que daria para fazer um AutoLoot com essa função, enfim belo código :)

 

 

Sim, com essa função e possivel facilmente se fazer um AutoLoot como citado.

Link para o comentário
Compartilhar em outros sites

  • 1 year later...

Nessa parte:

"

Vá em monster.cpp e procure:


void MonsterType::dropLoot(Container* corpse)
{
Item* tmpItem = NULL;
for(LootItems::const_iterator it = lootItems.begin(); it != lootItems.end() && !corpse->full(); ++it)
{
uint32_t owner = corpse->getCorpseOwner();
    Creature* creature = g_game.getCreatureByID(owner);
if((tmpItem = createLoot(*it)) && g_creatureEvents->dropLoot(creature, tmpItem))
{
if(Container* container = tmpItem->getContainer())
{
if(createChildLoot(container, (*it)))
corpse->__internalAddThing(tmpItem);
else
delete container;
}
else
corpse->__internalAddThing(tmpItem);
}
}


corpse->__startDecaying();
uint32_t ownerId = corpse->getCorpseOwner();
if(!ownerId)
return;


Player* owner = g_game.getPlayerByID(ownerId);
if(!owner)
return;


LootMessage_t message = lootMessage;
if(message == LOOTMSG_IGNORE)
message = (LootMessage_t)g_config.getNumber(ConfigManager::LOOT_MESSAGE);


if(message < LOOTMSG_PLAYER)
return;


std::stringstream ss;
ss << "Loot of " << nameDescription << ": " << corpse->getContentDescription() << ".";
if(owner->getParty() && message > LOOTMSG_PLAYER)
owner->getParty()->broadcastMessage((MessageClasses)g_config.getNumber(ConfigManager::LOOT_MESSAGE_TYPE), ss.str());
else if(message == LOOTMSG_PLAYER || message == LOOTMSG_BOTH)
owner->sendTextMessage((MessageClasses)g_config.getNumber(ConfigManager::LOOT_MESSAGE_TYPE), ss.str());
}

"

faz o que aq? precisa add algo? depois disso


Aqui deu error:

 no `bool CreatureEvents::dropLoot(Creature*, Item*)' member function declared in class `CreatureEvents' 

Alguem sabe arrumar?

deu isso..


@UP

Link para o comentário
Compartilhar em outros sites

×
×
  • Criar Novo...