Ir para conteúdo

Posts Recomendados

Monster Level

Boa noite,

 

Você deve ter visto este tópico e ficado interessado na feature, afinal, seria legal monstros terem também level, não é? O sistema que desenvolvi é bem funcional, o monstro passa a ter level e ganha mais HP, dá mais dano, tem mais defesa, dependendo dele.

 

Como é feito em C++, a configuração é feita totalmente no XML do monstro, ficando tudo mais organizado. Há um extra no código, onde você pode manipular o level do summon do jogador, alterando o valor do storage 'monster_level'.

 

Bom, é isso aí, para instalar, siga os passos a seguir atentamente.

 

O sistema foi desenvolvido com base no The Forgotten Server 0.4_SVN r3777, não testei na versão 0.3.6, você tem a total liberdade para fazer isso.

 

 

monsters.h

 

Procure por:

bool isSummonable, isIllusionable, isConvinceable, isAttackable, isHostile, isLureable,
	isWalkable, canPushItems, canPushCreatures, pushable, hideName, hideHealth;

Substitua por:

bool isSummonable, isIllusionable, isConvinceable, isAttackable, isHostile, isLureable,
	isWalkable, canPushItems, canPushCreatures, pushable, hideName, hideHealth, hideLevel; 

Procure por:

int32_t defense, armor, health, healthMax, baseSpeed, lookCorpse, corpseUnique, corpseAction,
	maxSummons, targetDistance, runAwayHealth, conditionImmunities, damageImmunities,
	lightLevel, lightColor, changeTargetSpeed, changeTargetChance;

Substitua por:

int32_t defense, armor, health, healthMax, baseSpeed, lookCorpse, corpseUnique, corpseAction,
	maxSummons, targetDistance, runAwayHealth, conditionImmunities, damageImmunities,
	lightLevel, lightColor, changeTargetSpeed, changeTargetChance, levelMin, levelMax;

monsters.cpp

 

Procure por:

canPushItems = canPushCreatures = isSummonable = isIllusionable = isConvinceable = isLureable = isWalkable = hideName = hideHealth = false;

Substitua por:

canPushItems = canPushCreatures = isSummonable = isIllusionable = isConvinceable = isLureable = isWalkable = hideName = hideHealth = hideLevel = false;

Procure por:

baseSpeed = 200;

Logo abaixo, adicione:

levelMin = levelMax = 1;

Localize:

bool Monsters::loadMonster

Dentro da função, procure por:

	for(xmlNodePtr p = root->children; p; p = p->next)
	{
		if(p->type != XML_ELEMENT_NODE)
			continue;

		if(!xmlStrcmp(p->name, (const xmlChar*)"health"))
		{
			if(!readXMLInteger(p, "max", intValue))
			{
				SHOW_XML_ERROR("Missing health.max");
				monsterLoad = false;
				break;
			}

			mType->healthMax = intValue;
			if(!readXMLInteger(p, "now", intValue))
				mType->health = mType->healthMax;
			else
				mType->health = intValue;
		} 

Logo abaixo, adicione:

        else if(!xmlStrcmp(p->name, (const xmlChar*)"level"))
        {
            if(!readXMLInteger(p, "max", intValue))
                mType->levelMax = 1;
            else
                mType->levelMax = intValue;

            if(!readXMLInteger(p, "min", intValue))
                mType->levelMin = mType->levelMax;
            else
                mType->levelMin = intValue;
        }

Procure por:

if(readXMLString(tmpNode, "emblem", strValue))
	mType->guildEmblem = getEmblems(strValue);

Logo abaixo, adicione:

if(readXMLString(tmpNode, "hidelevel", strValue))
        mType->hideLevel = booleanString(strValue);

 

monster.h

 

Localize:

class Monster : public Creature
{

Logo abaixo de:

	public:
#ifdef __ENABLE_SERVER_DIAGNOSTIC__
		static uint32_t monsterCount;
#endif
		virtual ~Monster();

Adicione:

std::string name, nameDescription;
int32_t level;
double bonusAttack, bonusDefense;

Substitua:

virtual const std::string& getName() const {return mType->name;}
virtual const std::string& getNameDescription() const {return mType->nameDescription;}
virtual std::string getDescription(int32_t) const {return mType->nameDescription + ".";}

Por:

virtual const std::string& getName() const {return name;}
virtual const std::string& getNameDescription() const {return nameDescription;}
virtual std::string getDescription(int32_t) const {return nameDescription + ".";}

monster.cpp

 

Procure por:

Monster::Monster(MonsterType* _mType):

Logo abaixo de:

isIdle = true;

Adicione:

name = _mType->name;
nameDescription = _mType->nameDescription;
level = (int32_t)random_range(_mType->levelMin, _mType->levelMax, DISTRO_NORMAL);
bonusAttack = 1.0;
bonusDefense = 1.0;

Procure por:

Monster::onCreatureAppear

Substitua toda a função 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())
		{
            std::string value;
            this->master->getStorage((std::string)"monster_level", value);

            uint8_t intValue = atoi(value.c_str());
            if(intValue || value == "0")
                level = intValue;
            else
                level = 1;
			isMasterInRange = canSee(master->getPosition());
		}

        if(g_config.getBool(ConfigManager::MONSTER_HAS_LEVEL))
        {
            this->healthMax = std::floor(this->getMaxHealth() * (1. + (0.1 * (level - 1))));
            this->health = this->healthMax;

            this->bonusAttack += (0.01 * (level - 1));
            this->bonusDefense += (0.005 * (level - 1));
        }



		updateTargetList();
		updateIdleStatus();
	}
	else
		onCreatureEnter(const_cast<Creature*>(creature));
}

Substitua todos:

g_config.getDouble(ConfigManager::RATE_MONSTER_DEFENSE)

Por:

g_config.getDouble(ConfigManager::RATE_MONSTER_DEFENSE) * bonusDefense

Substitua todos:

g_config.getDouble(ConfigManager::RATE_MONSTER_ATTACK)

Por:

g_config.getDouble(ConfigManager::RATE_MONSTER_ATTACK) * bonusAttack

map.cpp

 

Procure por:

#include "game.h"

Adicione:

#include "configmanager.h" 

Procure por:

extern Game g_game;

Adicione abaixo:

extern ConfigManager g_config;

Procure pela função:

bool Map::placeCreature
{

Adicione logo depois:

    Monster* monster = creature->getMonster();
    if(monster && g_config.getBool(ConfigManager::MONSTER_HAS_LEVEL))
    {
        uint8_t level;
        if(!monster->getMonsterType()->hideLevel)
        {
            if(monster->isSummon())
            {
                std::string value;
                monster->getMaster()->getStorage((std::string)"monster_level", value);

                uint8_t intValue = atoi(value.c_str());
                if(intValue || value == "0")
                    level = intValue;
                else
                    level = 1;
            }
            else
                level = monster->level;

            char buffer [10];
            monster->name = monster->getName() + " [" + itoa(level, buffer, 10) + "]";
        }
    }

configmanager.h

 

Procure por:

MONSTER_SPAWN_WALKBACK,

E adicione abaixo:

MONSTER_HAS_LEVEL,

configmanager.cpp

 

Procure por:

m_loaded = true;

Adicione um pouco antes:

m_confBool[MONSTER_HAS_LEVEL] = getGlobalBool("monsterHasLevel", true);

config.lua

monsterHasLevel = true

 

Acabou, ufa, né?

 

São muitas modificações para fazer, mas o resultado é garantido e é uma funcionalidade a mais para seu servidor.

Como está programado, a cada level, monstros ganham 10% de HP, 1% de dano e 0.5% de defesa.

 

Para configurar level mínimo e máximo, é só adicionar no XML do monstro:

<level min="1" max="10"/>

E alterar a seu gosto.

 

 

trunk.r3777 (com Monster Level)

 

Espero que gostem, qualquer erro, só postar no tópico.

 

Grande abraço.

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

Muito bom o código, obrigado mesmo, uma sugestão, seria legal você fazer o Race System, seria útil para muitos membros.

 

 

Obrigado novamente, REP+

 

Beeki XTibia.

Link para o comentário
Compartilhar em outros sites

Muito bom o código, obrigado mesmo, uma sugestão, seria legal você fazer o Race System, seria útil para muitos membros.

 

 

Obrigado novamente, REP+

 

Beeki XTibia.

 

Como funcionaria esse Race System? Pode passar mais detalhes por PM? rs

 

Abraços.

Link para o comentário
Compartilhar em outros sites

Ficou bem legal o código, com certeza no 0.3.6 não ira funcionar, pois tem alguns detalhes que precisarão ser mudados, como string do storage para integer entre outras pequenas coisas, mas nada complicado, rep+.

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

 

Muito bom o código, obrigado mesmo, uma sugestão, seria legal você fazer o Race System, seria útil para muitos membros.

 

 

Obrigado novamente, REP+

 

Beeki XTibia.

 

Como funcionaria esse Race System? Pode passar mais detalhes por PM? rs

 

Abraços.

 

 

Estilo Ragnarok, já ouviu falar?

Link para o comentário
Compartilhar em outros sites

E como funciona ,o monstro passa de level ou o monstro nasce com level apenas? Tipo dá respaw e nasce com level 5. Ou da respaw com um level,e se ele mata algum player e tal,ele evolui de level ou não?

De qualquer forma NICE isso!

Link para o comentário
Compartilhar em outros sites

E como funciona ,o monstro passa de level ou o monstro nasce com level apenas? Tipo dá respaw e nasce com level 5. Ou da respaw com um level,e se ele mata algum player e tal,ele evolui de level ou não?

De qualquer forma NICE isso!

 

Nasce com um level aleatório.

 

Grande abraço.

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

Adorei cara ira ajudar muita gente, REP+

 

(não tem limite de level ?)

 

Então, declarei as duas variáveis que controlam o level mínimo e máximo como int32_t, isso significa um valor máximo possível igual a 2147483647. rs

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

funciona no tfs 0.3.6pl1, e tfs 0.3.6?

 

otimo codigo, vlw UmTiro, rep+.

 

Ficou bem legal o código, com certeza no 0.3.6 não ira funcionar, pois tem alguns detalhes que precisarão ser mudados, como string do storage para integer entre outras pequenas coisas, mas nada complicado, rep+.

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novos posts.
×
×
  • Criar Novo...