Ir para conteúdo
  • Cadastre-se

Posts Recomendados

12 minutos atrás, Heyron disse:

Isso é assim mesmo, no RME os monstros olham para o norte.

3333.thumb.png.516d824fbcac6cef279c11ea63d6ee67.png

 

Sim, Tlg !No RME tem a opção de qual para o sentindo o monstro vai nascer. Porem ele n fica na posição solicitada. Por isso eu acho que deve ser na SCR

Editado por Doidodepeda (veja o histórico de edições)
Link para o post
Compartilhar em outros sites
3 horas atrás, Doidodepeda disse:

3333.thumb.png.516d824fbcac6cef279c11ea63d6ee67.png

 

Sim, Tlg !No RME tem a opção de qual para o sentindo o monstro vai nascer. Porem ele n fica na posição solicitada. Por isso eu acho que deve ser na SCR

 

Tem como resolver isso se você fazer uma sala de hunts, no qual após os player entrar no local, eles tenha que ir andando sentido pra baixo, aí vai meio que fazer sentido os monstros estarem olhando pra cima.

 

Tipo um corredor grande com os monstros divididos nos dois lados, o player vai descendo, sacou?

Dark Souls Bonfire GIF - Dark Souls Bonfire Rest - Discover & Share GIFs

Link para o post
Compartilhar em outros sites
7 horas atrás, Heyron disse:

 

Tem como resolver isso se você fazer uma sala de hunts, no qual após os player entrar no local, eles tenha que ir andando sentido pra baixo, aí vai meio que fazer sentido os monstros estarem olhando pra cima.

 

Tipo um corredor grande com os monstros divididos nos dois lados, o player vai descendo, sacou?

Saquei!!!

Mas o objetivo é fazer os bichos nascerem para baixo. Mas vllw ae man!
Vou aguardar pra vê se alguém manja sobre o assunto

Link para o post
Compartilhar em outros sites

////////////////////////////////////////////////////////////////////////
// OpenTibia - an opensource roleplaying game
////////////////////////////////////////////////////////////////////////
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
////////////////////////////////////////////////////////////////////////
#include "otpch.h"
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>

#include "spawn.h"
#include "tools.h"

#include "player.h"
#include "npc.h"

#include "configmanager.h"
#include "game.h"

extern ConfigManager g_config;
extern Monsters g_monsters;
extern Game g_game;

#define MINSPAWN_INTERVAL 1000
#define DEFAULTSPAWN_INTERVAL 60000

Spawns::Spawns()
{
    loaded = started = false;
}

Spawns::~Spawns()
{
    if(started)
        clear();
}

bool Spawns::loadFromXml(const std::string& _filename)
{
    if(isLoaded())
        return true;

    filename = _filename;
    xmlDocPtr doc = xmlParseFile(filename.c_str());
    if(!doc)
    {
        std::clog << "[Warning - Spawns::loadFromXml] Cannot open spawns file." << std::endl;
        std::clog << getLastXMLError() << std::endl;
        return false;
    }

    xmlNodePtr spawnNode, root = xmlDocGetRootElement(doc);
    if(xmlStrcmp(root->name,(const xmlChar*)"spawns"))
    {
        std::clog << "[Error - Spawns::loadFromXml] Malformed spawns file." << std::endl;
        xmlFreeDoc(doc);
        return false;
    }

    for(spawnNode = root->children; spawnNode; spawnNode = spawnNode->next)
        parseSpawnNode(spawnNode, false);

    xmlFreeDoc(doc);
    loaded = true;
    return true;
}

bool Spawns::parseSpawnNode(xmlNodePtr p, bool checkDuplicate)
{
    if(xmlStrcmp(p->name, (const xmlChar*)"spawn"))
        return false;

    int32_t intValue;
    std::string strValue;

    Position centerPos;
    if(!readXMLString(p, "centerpos", strValue))
    {
        if(!readXMLInteger(p, "centerx", intValue))
            return false;

        centerPos.x = intValue;
        if(!readXMLInteger(p, "centery", intValue))
            return false;

        centerPos.y = intValue;
        if(!readXMLInteger(p, "centerz", intValue))
            return false;

        centerPos.z = intValue;
    }
    else
    {
        IntegerVec posVec = vectorAtoi(explodeString(strValue, ","));
        if(posVec.size() < 3)
            return false;

        centerPos = Position(posVec[0], posVec[1], posVec[2]);
    }

    if(!readXMLInteger(p, "radius", intValue))
        return false;

    int32_t radius = intValue;
    Spawn* spawn = new Spawn(centerPos, radius);
    if(checkDuplicate)
    {
        for(SpawnList::iterator it = spawnList.begin(); it != spawnList.end(); ++it)
        {
            if((*it)->getPosition() == centerPos)
                delete *it;
        }
    }

    spawnList.push_back(spawn);
    for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next)
    {
        if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"monster"))
        {
            if(!readXMLString(tmpNode, "name", strValue))
                continue;

            std::string name = strValue;
            int32_t interval = MINSPAWN_INTERVAL / 1000;
            if(readXMLInteger(tmpNode, "spawntime", intValue) || readXMLInteger(tmpNode, "interval", intValue))
            {
                if(intValue <= interval)
                {
                    std::clog << "[Warning - Spawns::loadFromXml] " << name << " " << centerPos << " spawntime cannot"
                        << " be less than " << interval << " seconds." << std::endl;
                    continue;
                }

                interval = intValue;
            }

            interval *= 1000;
            Position placePos = centerPos;
            if(readXMLInteger(tmpNode, "x", intValue))
                placePos.x += intValue;

            if(readXMLInteger(tmpNode, "y", intValue))
                placePos.y += intValue;

            if(readXMLInteger(tmpNode, "z", intValue))
                placePos.z /*+*/= intValue;

            Direction direction = NORTH;
            if(readXMLInteger(tmpNode, "direction", intValue) && direction >= EAST && direction <= WEST)
                direction = (Direction)intValue;

            spawn->addMonster(name, placePos, direction, interval);
        }
        else if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"npc"))
        {
            if(!readXMLString(tmpNode, "name", strValue))
                continue;

            std::string name = strValue;
            Position placePos = centerPos;
            if(readXMLInteger(tmpNode, "x", intValue))
                placePos.x += intValue;

            if(readXMLInteger(tmpNode, "y", intValue))
                placePos.y += intValue;

            if(readXMLInteger(tmpNode, "z", intValue))
                placePos.z /*+*/= intValue;

            Direction direction = NORTH;
            if(readXMLInteger(tmpNode, "direction", intValue) && direction >= EAST && direction <= WEST)
                direction = (Direction)intValue;

            Npc* npc = Npc::createNpc(name);
            if(!npc)
                continue;

            npc->setMasterPosition(placePos, radius);
            npc->setDirection(direction);
            npcList.push_back(npc);
        }
    }

    return true;
}

void Spawns::startup()
{
    if(!isLoaded() || isStarted())
        return;

    for(NpcList::iterator it = npcList.begin(); it != npcList.end(); ++it)
        g_game.placeCreature((*it), (*it)->getMasterPosition(), false, true);

    npcList.clear();
    for(SpawnList::iterator it = spawnList.begin(); it != spawnList.end(); ++it)
        (*it)->startup();

    started = true;
}

void Spawns::clear()
{
    started = false;
    for(SpawnList::iterator it = spawnList.begin(); it != spawnList.end(); ++it)
        delete (*it);

    spawnList.clear();
    loaded = false;
    filename = std::string();
}

bool Spawns::isInZone(const Position& centerPos, int32_t radius, const Position& pos)
{
    if(radius == -1)
        return true;

    return ((pos.x >= centerPos.x - radius) && (pos.x <= centerPos.x + radius) &&
        (pos.y >= centerPos.y - radius) && (pos.y <= centerPos.y + radius));
}

void Spawn::startEvent()
{
    if(!checkSpawnEvent)
        checkSpawnEvent = Scheduler::getInstance().addEvent(createSchedulerTask(getInterval(), boost::bind(&Spawn::checkSpawn, this)));
}

Spawn::Spawn(const Position& _pos, int32_t _radius)
{
    centerPos = _pos;
    radius = _radius;
    interval = DEFAULTSPAWN_INTERVAL;
    checkSpawnEvent = 0;
}

Spawn::~Spawn()
{
    stopEvent();
    Monster* monster = NULL;
    for(SpawnedMap::iterator it = spawnedMap.begin(); it != spawnedMap.end(); ++it)
    {
        if(!(monster = it->second))
            continue;

        monster->setSpawn(NULL);
        if(!monster->isRemoved())
            g_game.freeThing(monster);
    }

    spawnedMap.clear();
    spawnMap.clear();
}

bool Spawn::findPlayer(const Position& pos)
{

    SpectatorVec list;
    g_game.getSpectators(list, pos);

    Player* tmpPlayer = NULL;
    for(SpectatorVec::iterator it = list.begin(); it != list.end(); ++it)
    {
        if((tmpPlayer = (*it)->getPlayer()) && !tmpPlayer->hasFlag(PlayerFlag_IgnoredByMonsters))
            return false;
    }

    return false;
}

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->setMasterPosition(pos, radius);
    monster->setDirection(dir);

    monster->addRef();
    spawnedMap.insert(SpawnedPair(spawnId, monster));
    spawnMap[spawnId].lastSpawn = OTSYS_TIME();
    return true;
}

void Spawn::startup()
{
    for(SpawnMap::iterator it = spawnMap.begin(); it != spawnMap.end(); ++it)
    {
        spawnBlock_t& sb = it->second;
        spawnMonster(it->first, sb.mType, sb.pos, sb.direction, true);
    }
}

void Spawn::checkSpawn()
{
#ifdef __DEBUG_SPAWN__
    std::clog << "[Notice] Spawn::checkSpawn " << this << std::endl;
#endif
    Monster* monster;
    uint32_t spawnId;

    checkSpawnEvent = 0;
    for(SpawnedMap::iterator it = spawnedMap.begin(); it != spawnedMap.end();)
    {
        spawnId = it->first;
        monster = it->second;
        if(monster->isRemoved())
        {
            if(spawnId)
                spawnMap[spawnId].lastSpawn = OTSYS_TIME();

            monster->unRef();
            spawnedMap.erase(it++);
        }
        else
        {
            /*if(spawnId && !isInSpawnZone(monster->getPosition()) && monster->getIdleStatus())
                g_game.internalTeleport(monster, monster->getMasterPosition(), true);

            */++it;
        }
    }

    uint32_t spawnCount = 0;
    for(SpawnMap::iterator it = spawnMap.begin(); it != spawnMap.end(); ++it)
    {
        spawnId = it->first;
        spawnBlock_t& sb = it->second;
        if(spawnedMap.count(spawnId))
            continue;

        if(OTSYS_TIME() < sb.lastSpawn + sb.interval)
            continue;

        if(findPlayer(sb.pos))
        {
            sb.lastSpawn = OTSYS_TIME();
            continue;
        }

        spawnMonster(spawnId, sb.mType, sb.pos, sb.direction);
        ++spawnCount;
        if(spawnCount >= (uint32_t)g_config.getNumber(ConfigManager::RATE_SPAWN))
            break;
    }

    if(spawnedMap.size() < spawnMap.size())
        checkSpawnEvent = Scheduler::getInstance().addEvent(createSchedulerTask(getInterval(), boost::bind(&Spawn::checkSpawn, this)));
#ifdef __DEBUG_SPAWN__
    else
        std::clog << "[Notice] Spawn::checkSpawn stopped " << this << std::endl;
#endif
}

bool Spawn::addMonster(const std::string& _name, const Position& _pos, Direction _dir, uint32_t _interval)
{
    if(!g_game.getTile(_pos))
    {
        std::clog << "[Spawn::addMonster] NULL tile at spawn position (" << _pos << ")" << std::endl;
        return false;
    }

    MonsterType* mType = g_monsters.getMonsterType(_name);
    if(!mType)
    {
        std::clog << "[Spawn::addMonster] Cannot find \"" << _name << "\"" << std::endl;
        return false;
    }

    if(_interval < interval)
        interval = _interval;

    spawnBlock_t sb;
    sb.mType = mType;
    sb.pos = _pos;
    sb.direction = _dir;
    sb.interval = _interval;
    sb.lastSpawn = 0;

    uint32_t spawnId = (int32_t)spawnMap.size() + 1;
    spawnMap[spawnId] = sb;
    return true;
}

void Spawn::removeMonster(Monster* monster)
{
    for(SpawnedMap::iterator it = spawnedMap.begin(); it != spawnedMap.end(); ++it)
    {
        if(it->second != monster)
            continue;

        monster->unRef();
        spawnedMap.erase(it);
        break;
    }
}

void Spawn::stopEvent()
{
    if(!checkSpawnEvent)
        return;

    Scheduler::getInstance().stopEvent(checkSpawnEvent);
    checkSpawnEvent = 0;
}
 

Editado por Doidodepeda (veja o histórico de edições)
Link para o post
Compartilhar em outros sites
18 horas atrás, Doidodepeda disse:

3333.thumb.png.516d824fbcac6cef279c11ea63d6ee67.png

 

Sim, Tlg !No RME tem a opção de qual para o sentindo o monstro vai nascer. Porem ele n fica na posição solicitada. Por isso eu acho que deve ser na SCR

Se no proprio RME não está funcionando a troca de direção. Você pode tentar mudar manualmente na pasta world no arquivo spawn.xml

Procure o nome e na tag é só fazer a modificação

Um exemplo de:

<npc name="Yama" x="1" y="0" z="6" spawntime="60"/>

Para:

<npc name="Yama" x="1" y="0" z="6" spawntime="60" direction="2"/>

 

2 = SUL

 

OBS: Creio que a forma que o Toruk disse funcione, deve padronizar.

Editado por Yan Liima (veja o histórico de edições)

════ҳ̸Ҳ̸ҳஜ۩۞۩ஜҳ̸Ҳ̸ҳ═══╗

Te Ajudei? Rep + e ficamos Quits

166420979_logoyanliimaornight.png.33f822b8970081a5b3646e85dbfd5934.png

Precisando de ajuda?

discord.png.1ecd188791d0141f74d99db371a2e0a4.png.890d5a38d7bcde75543c72b624a65de1.pngDiscord: Yan Liima #3702

Programador Júnior de LUA, PHP e JavaScript

Juntos somos lendas, separados somos Mitos!

╚══════════════════════════ҳ̸Ҳ̸ҳஜ۩۞۩ஜҳ̸Ҳ̸ҳ═════════════════════════════╝

Link para o post
Compartilhar em outros sites

Participe da conversa

Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.

Visitante
Responder

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emojis são permitidos.

×   Seu link foi automaticamente incorporado.   Mostrar como link

×   Seu conteúdo anterior foi restaurado.   Limpar o editor

×   Não é possível colar imagens diretamente. Carregar ou inserir imagens do URL.

  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.


  • Conteúdo Similar

    • Por braianlomas
      Como faço para corrigir esse problema para meu cliente, eu uso o tfs 0.3.6  
      Quero resolver esse problema que tenho no meu cliente, como e onde posso resolver?  
      Eu uso o tfs 0.3.6, não tenho as fontes do cliente, se você puder me dar eu vou amá-las para sempre  
       

       
    • Por A.Mokk
      Ola pessoal, estou tentando compilar o TFS 1.5 Downgrade para 8.60 atraves do MSVC 2022, ao tentar compilar da o seguinte erro:
       
       
      Fiz o download do MSVC, GitDash, TFS-SDK-3.2, e de varios boosts que tentei, ao fazer o seguinte procedimento no GitDash:
       
      Ao chegar em ./bootstrap-vcpkg.bat o GitDash nao consegue realizar o procedimento corretamente, alguem poderia me ajudar ?

      Tentei de diversas formas mas o mesmo erro sempre persiste, atualmente meu servidor utiliza TFS 0.4, consigo compilar sem nenhum problema no MSVC 2010, porem, as limitações do TFS 0.4 estão me fazendo precisar atualizar, se alguem souber como corrigir esses erros eu agradeço !

      Tutoriais utilizados :
      Compiling on Windows (vcpkg) · otland/forgottenserver Wiki · GitHub
      Compiling on Windows · otland/forgottenserver Wiki · GitHub
      Compilando TFS 1.3 com vídeo-aula - Tutoriais Infraestrutura & Proteção - Tibia King - Tudo sobre Tibia, OTServ e Bots!
      Compilar TFS 1.3 Vcpkg - Tutoriais Infraestrutura & Proteção - Tibia King - Tudo sobre Tibia, OTServ e Bots!
       
      O que acontece no Powershell:
       
    • Por thunmin
      .Qual servidor ou website você utiliza como base? 
      Canary 2.3.6
      Qual o motivo deste tópico? 
      Queria fazer com que os players não pudessem mexer no aleta sio, pois, agora os mesmos estão conseguindo mexer nos itens
      Está surgindo algum erro? Se sim coloque-o aqui. 
       
      Você tem o código disponível? Se tiver publique-o aqui: 
         
      Você tem alguma imagem que possa auxiliar no problema? Se sim, coloque-a aqui. 
       
    • Por thunmin
      .Qual servidor ou website você utiliza como base? 
      canary para o cliente 13.16
      Qual o motivo deste tópico? 
      Não consigo encontrar onde ajusta
      to com o problema no 13.16  o exausted, por exemplo os kinas era pra combar exori, erori gran e exori min, porém não ta indo ta dando exausted o char ta soltando magia ou runa e não consegue usar as potions
      Está surgindo algum erro? Se sim coloque-o aqui. 
       
      Você tem o código disponível? Se tiver publique-o aqui: 
         
      Você tem alguma imagem que possa auxiliar no problema? Se sim, coloque-a aqui. 
       
    • Por Andersontatuador
      Olá galera da TK, me chamo Anderson estou procurando alguém profissional em otservs e site.
      Já tenho um servidor o site e o cliente preciso só de uma pessoal competente, que esteja empenhado a trabalhar,
      não quero nada de graça, pois nessa onda fui mais roubado do quer eu pagar um profissional.
      caso alguém se interesse entrar em contato comigo através do whatsapp
      82 9 9304-9462
       
      Está surgindo algum erro? Se sim coloque-o aqui. 
       
      Você tem o código disponível? Se tiver publique-o aqui: 
         
      Você tem alguma imagem que possa auxiliar no problema? Se sim, coloque-a aqui. 
       
×
×
  • Criar Novo...

Informação Importante

Confirmação de Termo