Função onSpawn(cid) para TFS 0.3.6

lSainty
em Linguagens de Programação
  • 1
  • 2

lSainty

xd
avatar
Conde
Conde

INFOS

Grupo: CondeRegistrado: 30/10/11Posts: 509Gênero: Masculino

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

re2JIBH.jpg

Beeki

Ex-Coordenador XDev
avatar
Herói
Herói

INFOS

Grupo: HeróiRegistrado: 12/03/11Posts: 1900Gênero: MasculinoChar no Tibia: Nokte

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

Fabio Augustus - Infraestrutura

Skype: guhsvasc

caotic

Afinal de contas,sou um mordomo e tanto
avatar
Infante
Infante

INFOS

Grupo: InfanteRegistrado: 04/03/11Posts: 1599Char no Tibia: No Have

Opa colega so ta faltando o registro do evento.

 

Sendo assim o creatureevent nunca sera chamado.

lSainty

xd
avatar
Conde
Conde

INFOS

Grupo: CondeRegistrado: 30/10/11Posts: 509Gênero: Masculino

ó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 :/

re2JIBH.jpg

Stigal

don't ever stop...
avatar
Herói
Herói

INFOS

Grupo: HeróiRegistrado: 28/11/10Posts: 3402Gênero: Masculino

Estou comentando em algo relacionado a tibia, então nem preciso dizer o que achei.

Parabéns!

VI6MDIG.png

 

"O fracasso é a oportunidade de se começar de novo inteligentemente"

Minhas Redes Sociais: Youtube | Página & Grupo | Steam  | Discord Xtibia | Skype: @mrooger

 

OTpanel

lSainty

xd
avatar
Conde
Conde

INFOS

Grupo: CondeRegistrado: 30/10/11Posts: 509Gênero: Masculino

Estou comentando em algo relacionado a tibia, então nem preciso dizer o que achei.

Parabéns!

vqz7.jpgi536.jpg20e1.jpg

re2JIBH.jpg

Strogman

avatar
Visconde
Visconde

INFOS

Grupo: ViscondeRegistrado: 04/11/12Posts: 464Gênero: MasculinoChar no Tibia: Lysty Of Death

lol parou de nascer respaw quando mata o monstro ele não nasce mais por que?

 

                                 logo_full_1600.png.f8d0c5d8ba71c660bad630b327c3e64d.png

                                                              htps://www.facebook.com/PokemonOnlineSVKE

                                                                                                                       PokeSvke

Slicer

Insanity
avatar
Príncipe
Príncipe

INFOS

Grupo: PríncipeRegistrado: 19/08/10Posts: 4014Gênero: Masculino

/\ 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

"Só a beira do abismo que os seres humanos acham forças para mudar."... E isso me da nojo... ¬¬

"Insanity is doing the exact... same fucking thing... over and over again expecting... shit to change... That. Is. Crazy." -Vass/Einstein

 

Strogman

avatar
Visconde
Visconde

INFOS

Grupo: ViscondeRegistrado: 04/11/12Posts: 464Gênero: MasculinoChar no Tibia: Lysty Of Death

como assim um else?

 

                                 logo_full_1600.png.f8d0c5d8ba71c660bad630b327c3e64d.png

                                                              htps://www.facebook.com/PokemonOnlineSVKE

                                                                                                                       PokeSvke

nociam

avatar
Conde
Conde

INFOS

Grupo: CondeRegistrado: 04/02/13Posts: 541Gênero: Masculino

como assim um else?

Queria saber tb como?

Slicer

Insanity
avatar
Príncipe
Príncipe

INFOS

Grupo: PríncipeRegistrado: 19/08/10Posts: 4014Gênero: Masculino

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...-

"Só a beira do abismo que os seres humanos acham forças para mudar."... E isso me da nojo... ¬¬

"Insanity is doing the exact... same fucking thing... over and over again expecting... shit to change... That. Is. Crazy." -Vass/Einstein

 

Strogman

avatar
Visconde
Visconde

INFOS

Grupo: ViscondeRegistrado: 04/11/12Posts: 464Gênero: MasculinoChar no Tibia: Lysty Of Death

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

 

                                 logo_full_1600.png.f8d0c5d8ba71c660bad630b327c3e64d.png

                                                              htps://www.facebook.com/PokemonOnlineSVKE

                                                                                                                       PokeSvke

lSainty

xd
avatar
Conde
Conde

INFOS

Grupo: CondeRegistrado: 30/10/11Posts: 509Gênero: Masculino

Tópico atualizado :b

re2JIBH.jpg

nociam

avatar
Conde
Conde

INFOS

Grupo: CondeRegistrado: 04/02/13Posts: 541Gênero: Masculino

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.

lSainty

xd
avatar
Conde
Conde

INFOS

Grupo: CondeRegistrado: 30/10/11Posts: 509Gênero: Masculino

 

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

re2JIBH.jpg

  • 1
  • 2