Ir para conteúdo

Função onSpawn(cid) para TFS 0.3.6


lSainty

Posts Recomendados

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 :D

 

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 :D

 

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

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

ótimo conteúdo, tem como explicar/exemplificar de como usa-lo?

Essa função é executada sempre que o monstro da respawn, em um poketibia por exemplo ela pode ser usada para ter uma chanse de o pokemon nascer shiny, ou até mesmo mandar uma mensagem quando o monstro nascer:

 

function onSpawn(cid)
doBroadcastMessage("Monster ".. getCreatureName(cid).." was created.")
return true

end

Entendeu? :D

Opa colega so ta faltando o registro do evento.

 

Sendo assim o creatureevent nunca sera chamado.

Corrigido, eu tinha esquecido uma parte do código :/

Link para o comentário
Compartilhar em outros sites

  • 3 weeks later...

/\ provavelmente tu fez 'caca' ali na hora de apagar a parte do spawn.cpp... na real, apagar aquela parte n eh a melhor opçao... eu colocaria um else ali.. ;p

Link para o comentário
Compartilhar em outros sites

eu tinha feito aki no serv q eu tinha começado do zero, mas parece q quando formatei o pc eu acabei salvando uma versao antiga das sources e dai n tenhu mais essa ediçao aki... mas se n me engano eu fiz assim...

 

 

 

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;
}

 

 

 

realmente n eh preciso checar se tem player por perto pra mandar os eventos quando o serv ta iniciando... entao o melhor jeito de fazer essa ediçao eh esse ae, pelo menos pra mim, executando soh o evento no proprio monstro... com isso, vai disparar o onSpawn... -em tese, n lembro se foi assim q fiz antes...-

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

eu tinha feito aki no serv q eu tinha começado do zero, mas parece q quando formatei o pc eu acabei salvando uma versao antiga das sources e dai n tenhu mais essa ediçao aki... mas se n me engano eu fiz assim...

 

 

 

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;
}

 

 

 

realmente n eh preciso checar se tem player por perto pra mandar os eventos quando o serv ta iniciando... entao o melhor jeito de fazer essa ediçao eh esse ae, pelo menos pra mim, executando soh o evento no proprio monstro... com isso, vai disparar o onSpawn... -em tese, n lembro se foi assim q fiz antes...-

 

vlw deu certo

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

eu tinha feito aki no serv q eu tinha começado do zero, mas parece q quando formatei o pc eu acabei salvando uma versao antiga das sources e dai n tenhu mais essa ediçao aki... mas se n me engano eu fiz assim...

 

 

 

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;
}

 

 

 

realmente n eh preciso checar se tem player por perto pra mandar os eventos quando o serv ta iniciando... entao o melhor jeito de fazer essa ediçao eh esse ae, pelo menos pra mim, executando soh o evento no proprio monstro... com isso, vai disparar o onSpawn... -em tese, n lembro se foi assim q fiz antes...-

No meu servidor quanto o servidor inicia nao funciona vai saber.

Link para o comentário
Compartilhar em outros sites

 

eu tinha feito aki no serv q eu tinha começado do zero, mas parece q quando formatei o pc eu acabei salvando uma versao antiga das sources e dai n tenhu mais essa ediçao aki... mas se n me engano eu fiz assim...

 

 

 

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;
}

 

 

 

realmente n eh preciso checar se tem player por perto pra mandar os eventos quando o serv ta iniciando... entao o melhor jeito de fazer essa ediçao eh esse ae, pelo menos pra mim, executando soh o evento no proprio monstro... com isso, vai disparar o onSpawn... -em tese, n lembro se foi assim q fiz antes...-

No meu servidor quanto o servidor inicia nao funciona vai saber.

 

Tentou das duas formas? Comigo as duas funcionaram o.O

Link para o comentário
Compartilhar em outros sites

×
×
  • Criar Novo...