Eae galera, estava passando aqui por essa seção e vi que só havia a função onSpawn para TFS 0.4, então resolvi trazer para 0.3.6
Primeiramente, va em Creatureevent.h e procure por:
uint32_t executePrepareDeath(Creature* creature, DeathList deathList);
E cole embaixo:
uint32_t executeOnSpawn(Creature* creature);
Procure por:
CREATURE_EVENT_DEATH,
E cole isso por cima da linha de baixo:
CREATURE_EVENT_PREPAREDEATH, CREATURE_EVENT_SPAWN
Agora va em creatureevent.cpp e procure por:
else if(tmpStr == "preparedeath") m_type = CREATURE_EVENT_PREPAREDEATH;
E cole embaixo:
else if(tmpStr == "spawn") m_type = CREATURE_EVENT_SPAWN;
Procure por:
case CREATURE_EVENT_PREPAREDEATH: return "onPrepareDeath";
E cole embaixo:
case CREATURE_EVENT_SPAWN: return "onSpawn";
Procure por:
case CREATURE_EVENT_PREPAREDEATH: return "cid, deathList";
E cole embaixo:
case CREATURE_EVENT_SPAWN: return "cid";
Va ao fim do arquivo e cole isso:
uint32_t CreatureEvent::executeOnSpawn(Creature* creature) { //onSpawn(cid) 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 << 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 << creature->getName(); env->setEvent(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)); bool result = m_interface->callFunction(1); m_interface->releaseEnv(); return result; } } else { std::clog << "[Error - CreatureEvent::executeCast] Call stack overflow." << std::endl; return 0; } }
Va em monster.cpp e procure por:
void Monster::onCreatureAppear(const Creature* creature) { Creature::onCreatureAppear(creature); if(creature == this) { //We just spawned lets look around to see who is there. if(isSummon()) isMasterInRange = canSee(master->getPosition());
Embaixo pressione enter 2x e cole:
CreatureEventList spawn = getCreatureEvents(CREATURE_EVENT_SPAWN); for(CreatureEventList::iterator it = spawn.begin(); it != spawn.end(); ++it) (*it)->executeOnSpawn(this);
E pronto, basta compilar agora
Exemplos de como usar essa função:
Em um servidor de tibia, você pode usa-la para quando um boss der respawn, exemplo:
function onSpawn(cid) doBroadcastMessage("Monster ".. getCreatureName(cid).." was created.") return true end
E até mesmo em um servidor de poketibia você pode fazer com que tenha uma chanse de o pokemon nascer shiny :b, resumindo, é possivel fazer varias coisas com essa função xD (Lembrando que ela só funciona quando o monstro da respawn, e não quando abre o servidor).
-- EDIT --
Para fazer com que o evento seja iniciado junto com o servidor ao invés de somente quando o monstro der RESPAWN, va em spawn.cpp e procure por:
bool Spawn::spawnMonster(uint32_t spawnId, MonsterType* mType, const Position& pos, Direction dir, bool startup /*= false*/) { Monster* monster = Monster::createMonster(mType); if(!monster) return false; if(startup) { //No need to send out events to the surrounding since there is no one out there to listen! if(!g_game.internalPlaceCreature(monster, pos, false, true)) { delete monster; return false; } } else { if(!g_game.placeCreature(monster, pos, false, true)) { delete monster; return false; } } monster->setSpawn(this); monster->addRef(); monster->setMasterPosition(pos, radius); monster->setDirection(dir); spawnedMap.insert(SpawnedPair(spawnId, monster)); spawnMap[spawnId].lastSpawn = OTSYS_TIME(); return true; }
e apague essa parte:
{ //No need to send out events to the surrounding since there is no one out there to listen! if(!g_game.internalPlaceCreature(monster, pos, false, true)) { delete monster; return false; } } else
Pronto, agora a função é executada assim que o servidor inicia
Se os monstros pararem de dar respawn, ao invés de apagarem a parte que citei acima, troquem isso:
bool Spawn::spawnMonster(uint32_t spawnId, MonsterType* mType, const Position& pos, Direction dir, bool startup /*= false*/) { Monster* monster = Monster::createMonster(mType); if(!monster) return false; if(startup) { //No need to send out events to the surrounding since there is no one out there to listen! if(!g_game.internalPlaceCreature(monster, pos, false, true)) { delete monster; return false; } } else { if(!g_game.placeCreature(monster, pos, false, true)) { delete monster; return false; } } monster->setSpawn(this); monster->addRef(); monster->setMasterPosition(pos, radius); monster->setDirection(dir); spawnedMap.insert(SpawnedPair(spawnId, monster)); spawnMap[spawnId].lastSpawn = OTSYS_TIME(); return true; }
Por isso:
bool Spawn::spawnMonster(uint32_t spawnId, MonsterType* mType, const Position& pos, Direction dir, bool startup /*= false*/) { Monster* monster = Monster::createMonster(mType); if(!monster) return false; if(startup) { //No need to send out events to the surrounding since there is no one out there to listen! if(!g_game.internalPlaceCreature(monster, pos, false, true)) { delete monster; return false; } else { monster->onCreatureAppear(monster); } } else { if(!g_game.placeCreature(monster, pos, false, true)) { delete monster; return false; } } monster->setSpawn(this); monster->addRef(); monster->setMasterPosition(pos, radius); monster->setDirection(dir); spawnedMap.insert(SpawnedPair(spawnId, monster)); spawnMap[spawnId].lastSpawn = OTSYS_TIME(); return true; }
Créditos: Doggynub por fazer a função (OTIlha)
ArkSeyonet por adaptar para 0.3.6 (OTIlha)
Eu por pequenas edições :3
Slicer