What's new

-Tibia 8.70 + onDropEvent - wykonuje si? podczas 'tworzenia' dropu

Status
Not open for further replies.

Lopus

Advanced User
Joined
Jun 17, 2011
Messages
206
Reaction score
9
Witam,
Tym razem mam dla Was ciekawy i przydatny kod.
Jest to nowy event do creaturescripts wykonuj?cy si? przy tworzeniu dropu z potwora.
Otwieramy plik monster.cpp i zamieniamy ca?? funkcj?

PHP:
    void Monster::dropLoot(Container* corpse)
na:
PHP:
    void Monster::dropLoot(Container* corpse)
    {
        bool status = true;
        CreatureEventList dropLootEvents = getCreatureEvents(CREATURE_EVENT_DROP_LOOT);
        for(CreatureEventList::iterator it = dropLootEvents.begin(); it != dropLootEvents.end(); ++it)
    			if(!(*it)->executeDropLoot(this, corpse) && status) status = false;
        if(!status) return;
    	if(corpse && lootDrop == LOOT_DROP_FULL)
    		mType->dropLoot(corpse);
    }
Dalej otwieramy player.cpp, szukamy:
PHP:
    void Player::dropLoot(Container* corpse)
    {
    	if(!corpse || lootDrop != LOOT_DROP_FULL)
    		return;
i pod tym doklejamy:
PHP:
bool status = true;
	CreatureEventList dropLootEvents = getCreatureEvents(CREATURE_EVENT_DROP_LOOT);
    for(CreatureEventList::iterator it = dropLootEvents.begin(); it != dropLootEvents.end(); ++it)
			if(!(*it)->executeDropLoot(this, corpse) && status) status = false;
    if(!status) return;
Otwieramy creatureevent.h
Szukamy: CREATURE_EVENT_KILL, i pod tym doklejamy: CREATURE_EVENT_DROP_LOOT,
Szukamy:
PHP:
uint32_t executeKill(Creature* creature, Creature* target, const DeathEntry& entry);
I pod tym doklejamy:
PHP:
uint32_t executeDropLoot(Creature* creature, Container* corpse);
Otwieramy creatureevent.cpp i szukamy:
PHP:
uint32_t CreatureEvent::executeKill(Creature* creature, Creature* target, const DeathEntry& entry)
i pod ca?ym blokiem tej funkcji doklejamy:
PHP:
uint32_t CreatureEvent::executeDropLoot(Creature* creature, Container* corpse)
{
	//onDropLoot(cid, corpse)
	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 corpse = " << env->addThing(corpse) << 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__
			std::stringstream desc;
			desc << player->getName();
			env->setEventDesc(desc.str());
			#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_pushnumber(L, env->addThing(corpse));
			bool result = m_interface->callFunction(2);
			m_interface->releaseEnv();
			return result;
		}
	}
	else
	{
		std::cout << "[Error - CreatureEvent::executeDropLoot] Call stack overflow." << std::endl;
		return 0;
	}
}
Szukamy:
PHP:
    else if(tmpStr == "kill")
    		m_type = CREATURE_EVENT_KILL;
i pod tym doklejamy:
PHP:
else if(tmpStr == "droploot")
        m_type = CREATURE_EVENT_DROP_LOOT;
Szukamy:
PHP:
    case CREATURE_EVENT_KILL:
    			return "onKill";
Doklejamy:
PHP:
    case CREATURE_EVENT_DROP_LOOT:
                return "onDropLoot";
Szukamy:
PHP:
    case CREATURE_EVENT_LOGIN:
    			return "cid";
Doklejamy:
PHP:
    case CREATURE_EVENT_DROP_LOOT:
                return "cid, corpse";
Zapisujemy i kompilujemy i to na tyle :)
Przyk?adowe u?ycie:
Do data/creaturescripts/scripts dodajemy plik onDropLoot.lua
PHP:
    function onDropLoot(cid, corpse)
    	if(getCreatureName(cid):lower() == "demon" and isMonster(cid)) then
    		if(math.random(1,5) == 1) then 
    			doAddContainerItem(corpse, 9932) -- add firewalker boots to loot
    		end
    	end
    	return true
    end
Plik data/creaturescripts/creaturescripts.xml:
PHP:
<creatureevent type="droploot" name="onDropLoot" event="script" value="onDropLoot.lua"/>
Plik data/creaturescripts/scripts/kill.lua po function onKill() doklejamy:
PHP:
registerCreatureEvent(target, "onDropLoot")
Skrypt sprawi, ?e je?li zabijemy demca to mamy 20% szansy, ?e do loota doda nam firewalker boots.
Wiem, ?e si? zaraz zapytacie, po co to skoro mo?na ustawi? szanse w pliku xml monstera.
Odpowied?:
A no po to, ?e dzi?ki temu mo?emy te? ustawia?, losowe statystyki dla loota, oraz loci? przedmioty z okre?lonym aid (np. klucze xD).
PS. w skrypcie LUA return false spowoduje, ?e nie pojawi si? nawet cia?o po zgonie wi?c radz? uwa?a? :)

TESTOWANE NA TFS 0.4_DEV.r4086!
 
Status
Not open for further replies.
Top