Ir para conteúdo
  • Cadastre-se

Posts Recomendados

Em 22/07/2014 ás 08:58, luanluciano93 disse:

Olá pessoal, eu estava ajudando um amigo em um script de Tibia Naruto, e me deparei com a necessidade de usar uma função para trocar o nome de um summon, mas isso teria que ser inGame, e depois de procurar um pouco achei a função setCreatureName, que faz exatamente o que eu precisava.

O que ela faz?
Como eu expliquei acima, ela muda o nome da Creature inGame, podendo ser bastante útil (dependendo da sua criatividade).

Como instalar? 
A instalação é feita inteiramente nas sources, então vamos lá .. 

1 - No arquivo monster.h encontre esse trecho: 


class Monster : public Creature
{
	private:
		Monster(MonsterType* _mType);

	public: 

E adicione isso abaixo de public::


std::string name, nameDescription;

2 - Ainda em monster.h procure por:


virtual const std::string& getName() const {return mType->name;}

E substitua por isso:


virtual const std::string& getName() const {return name;}

3 - Ainda em monster.h procure por:


virtual const std::string& getNameDescription() const {return mType->nameDescription;}

E substitua por isso:


virtual const std::string& getNameDescription() const {return nameDescription;}

4 - Ainda em monster.h procure por:


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

E substitua por isso:


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

5 - Agora em monster.cpp procure por:


Monster::Monster(MonsterType* _mType):

Nas linhas abaixo tem a linha: raid = NULL; , adicione isso logo abaixo: 


name = _mType->name;
nameDescription = _mType->nameDescription;

 

 

Conteúdo Oculto

 

 

 

6 - Agora em luascript.h adicione isso perto das linhas semelhantes:


static int32_t luaSetCreatureName(lua_State* L);

7 - Agora em luascript.cpp adicione isso perto das linhas semelhantes:


//setCreatureName(cid, name, description)
lua_register(m_luaState, "setCreatureName", LuaInterface::luaSetCreatureName);

8 - Ainda em luascript.cpp adicione isso perto das linhas semelhantes: 


int32_t LuaInterface::luaSetCreatureName(lua_State* L)
{
    // setCreatureName(cid, newName, newDescription)
    std::string newDesc = popString(L);
    std::string newName = popString(L);
    ScriptEnviroment* env = getEnv();
    
	Creature* creature;
    if (creature = env->getCreatureByUID(popNumber(L)))
	{
        Monster* monster = (Monster*)creature;
        monster->name = newName;
        monster->nameDescription = newDesc;
        lua_pushboolean(L, true);
    }
    else
	{
        errorEx(getError(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushboolean(L, false);
    }
    
	return 1;
} 

Pelo fato de algumas diferenças no modo de escrever a função entre as TFS, pode ocorrer erros, e então substitua as seguintes linhas dos 2 passos anteriores:
 

 

Conteúdo Oculto

 

 

 

Créditos: Scarlet Ayeid

 

 

É isso pessoal ... um exemplo de uso dentro de alguma função é assim basicamente:


local pos = {x = 10, y = 10, z = 7}
local Teste = doCreateMonster("Rat", pos)
setCreatureName(Teste, ""..getCreatureName(cid).."", "a "..getCreatureName(cid).."")

Espero ter ajudado pessoal, até mais.

o Nome so aparece no look mas continua o nome do summon , sabe porque??

Link para o post
Compartilhar em outros sites
  • 1 year later...
  • Respostas 74
  • Created
  • Última resposta

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

Olá pessoal, eu estava ajudando um amigo em um script de Tibia Naruto, e me deparei com a necessidade de usar uma função para trocar o nome de um summon, mas isso teria que ser inGame, e depois de pro

Não modifique tudo roriscrave, mude apenas "mType->nameDescription" para "nameDescription"

vlw deu tudo certo, estou usando 8.54 vlw

Posted Images

  • Moderador
Em 07/01/2017 em 15:28, Gustavo Ntos disse:

o Nome so aparece no look mas continua o nome do summon , sabe porque??

     local pos = {x = 10, y = 10, z = 7}
     local teste = doSummonCreature("Rat",pos)
     setCreatureName(pos, "Fake Rat", "a fake rat")

ou

     local pos = {x = 10, y = 10, z = 7}
     local teste = doCreateMonster("Rat",pos)
     setCreatureName(pos, "Fake Rat", "a fake rat")

 

5 horas atrás, H3ITORR disse:

a minha source e 0.4 e esta dando erro na hora de copilar me ajuda plis!

pode ser que isso é diferente na sua 

 

LuaScriptInterface:

para

LuaInterface:

altere todos

 

20230912_034613.png.cf49b650c34dd7d7b1f79bd49c70f53c.png

Eu sou um entusiasta da programação apaixonado por ajudar a comunidade open source a crescer. Sempre em busca de novos desafios e oportunidades para contribuir com meu código.  #OpenSource #Programação #Contribuição

 

Link para o post
Compartilhar em outros sites
6 minutos atrás, L3K0T disse:

     local pos = {x = 10, y = 10, z = 7}
     local teste = doSummonCreature("Rat",pos)
     setCreatureName(pos, "Fake Rat", "a fake rat")

ou


     local pos = {x = 10, y = 10, z = 7}
     local teste = doCreateMonster("Rat",pos)
     setCreatureName(pos, "Fake Rat", "a fake rat")

 

pode ser que isso é diferente na sua 

 


LuaScriptInterface:

para


LuaInterface:

altere todos

os meus sao todos luainterface preciso mudar todos para luascriptinterface?

por que e nesse luascriptinterface que ta dando erro!

Link para o post
Compartilhar em outros sites
  • Moderador
Agora, H3ITORR disse:

os meus sao todos luainterface preciso mudar todos para luascriptinterface?

por que e nesse luascriptinterface que ta dando erro!

todos

 

20230912_034613.png.cf49b650c34dd7d7b1f79bd49c70f53c.png

Eu sou um entusiasta da programação apaixonado por ajudar a comunidade open source a crescer. Sempre em busca de novos desafios e oportunidades para contribuir com meu código.  #OpenSource #Programação #Contribuição

 

Link para o post
Compartilhar em outros sites
  • Moderador
1 minuto atrás, H3ITORR disse:

mas os meus sao luainterface dai coloco luascriptinterface?

não se o seu for 

LuaInterface::

tem que ser assim todos, 

LuaScriptInterface::

é de tfs 0.3.6

2 minutos atrás, H3ITORR disse:

mas os meus sao luainterface dai coloco luascriptinterface?

manda o erro com o print

 

20230912_034613.png.cf49b650c34dd7d7b1f79bd49c70f53c.png

Eu sou um entusiasta da programação apaixonado por ajudar a comunidade open source a crescer. Sempre em busca de novos desafios e oportunidades para contribuir com meu código.  #OpenSource #Programação #Contribuição

 

Link para o post
Compartilhar em outros sites
  • Moderador
1 minuto atrás, H3ITORR disse:

minha tfs e 0.4

manda o print com o erro

 

20230912_034613.png.cf49b650c34dd7d7b1f79bd49c70f53c.png

Eu sou um entusiasta da programação apaixonado por ajudar a comunidade open source a crescer. Sempre em busca de novos desafios e oportunidades para contribuir com meu código.  #OpenSource #Programação #Contribuição

 

Link para o post
Compartilhar em outros sites

ele fica em vermelho nessa linha 

//setCreatureName(cid, name, description)
    lua_register(m_luaState, "setCreatureName", LuaScriptInterface::luaSetCreatureName);

int32_t LuaScriptInterface::luaSetCreatureName(lua_State* L)

dai se eu coloco ali nos LuaScriptInterface para LuaInterface copila sereno mas o meu tfs 0.4 todos sao luaInterface

Link para o post
Compartilhar em outros sites
  • Moderador
2 minutos atrás, H3ITORR disse:

ele fica em vermelho nessa linha 


//setCreatureName(cid, name, description)
    lua_register(m_luaState, "setCreatureName", LuaScriptInterface::luaSetCreatureName);


int32_t LuaScriptInterface::luaSetCreatureName(lua_State* L)

dai se eu coloco ali nos LuaScriptInterface para LuaInterface copila sereno mas o meu tfs 0.4 todos sao luaInterface

se está dando erro então é pra ser assim

 

int32_t LuaInterface::luaSetCreatureName(lua_State* L)

lua_register(m_luaState, "setCreatureName", LuaInterface::luaSetCreatureName);

 

 

20230912_034613.png.cf49b650c34dd7d7b1f79bd49c70f53c.png

Eu sou um entusiasta da programação apaixonado por ajudar a comunidade open source a crescer. Sempre em busca de novos desafios e oportunidades para contribuir com meu código.  #OpenSource #Programação #Contribuição

 

Link para o post
Compartilhar em outros sites

ja coloquei assim L3K0T mas quando uso bunshin no jutsu com naruto ele cria o clone mas os clone nao usa o mesmo nick e tbm nao usa o buff!

Link para o post
Compartilhar em outros sites
  • Moderador
2 minutos atrás, H3ITORR disse:

ja coloquei assim L3K0T mas quando uso bunshin no jutsu com naruto ele cria o clone mas os clone nao usa o mesmo nick e tbm nao usa o buff!

     local pos = {x = 10, y = 10, z = 7}
     local teste = doSummonCreature("Rat",pos)
     setCreatureName(pos, "Fake Rat", "a fake rat")

ou

     local pos = {x = 10, y = 10, z = 7}
     local teste = doCreateMonster("Rat",pos)
     setCreatureName(pos, "Fake Rat", "a fake rat")

já tentou assim?? tbm tente recompilar no modo Rebuilder

 

20230912_034613.png.cf49b650c34dd7d7b1f79bd49c70f53c.png

Eu sou um entusiasta da programação apaixonado por ajudar a comunidade open source a crescer. Sempre em busca de novos desafios e oportunidades para contribuir com meu código.  #OpenSource #Programação #Contribuição

 

Link para o post
Compartilhar em outros sites
  • 6 months later...

minhas sources não tem:
 

Monster::Monster(MonsterType* _mType):
	Creature()
{
	isIdle = true;
	isMasterInRange = false;
	teleportToMaster = false;
	mType = _mType;
	spawn = NULL;
	raid = NULL;
	name = mType->name;
	nameDescription = mType->nameDescription; 

oq eu faço ?

 

monster.cpp:
 

Spoiler

////////////////////////////////////////////////////////////////////////
// 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 "monsters.h"
#include "tools.h"
#include "monster.h"

#include "luascript.h"
#include "container.h"
#include "weapons.h"

#include "spells.h"
#include "combat.h"

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

extern Game g_game;
extern Spells* g_spells;
extern Monsters g_monsters;
extern ConfigManager g_config;

void MonsterType::reset()
{
    canPushItems = canPushCreatures = isSummonable = isIllusionable = isConvinceable = isLureable = isWalkable = hideName = hideHealth = false;
    pushable = isAttackable = isHostile = true;

    outfit.lookHead = outfit.lookBody = outfit.lookLegs = outfit.lookFeet = outfit.lookType = outfit.lookTypeEx = outfit.lookAddons = 0;
    runAwayHealth = manaCost = lightLevel = lightColor = yellSpeedTicks = yellChance = changeTargetSpeed = changeTargetChance = 0;
    experience = defense = armor = lookCorpse = corpseUnique = corpseAction = conditionImmunities = damageImmunities = 0;

    maxSummons = -1;
    targetDistance = 1;
    staticAttackChance = 95;
    health = healthMax = 100;
    baseSpeed = 200;

    race = RACE_BLOOD;
    skull = SKULL_NONE;
    partyShield = SHIELD_NONE;
    guildEmblem = EMBLEM_NONE;
    lootMessage = LOOTMSG_IGNORE;

    for(SpellList::iterator it = spellAttackList.begin(); it != spellAttackList.end(); ++it)
    {
        if(!it->combatSpell)
            continue;

        delete it->spell;
        it->spell = NULL;
    }

    spellAttackList.clear();
    for(SpellList::iterator it = spellDefenseList.begin(); it != spellDefenseList.end(); ++it)
    {
        if(!it->combatSpell)
            continue;

        delete it->spell;
        it->spell = NULL;
    }

    spellDefenseList.clear();
    summonList.clear();
    scriptList.clear();

    voiceVector.clear();
    lootItems.clear();
    elementMap.clear();
}

uint16_t Monsters::getLootRandom()
{
    return (uint16_t)std::ceil((double)random_range(0, MAX_LOOTCHANCE) / g_config.getDouble(ConfigManager::RATE_LOOT));
}

void MonsterType::dropLoot(Container* corpse)
{
    Item* tmpItem = NULL;
    for(LootItems::const_iterator it = lootItems.begin(); it != lootItems.end() && !corpse->full(); ++it)
    {
        if((tmpItem = createLoot(*it)))
        {
            if(Container* container = tmpItem->getContainer())
            {
                if(createChildLoot(container, (*it)))
                    corpse->__internalAddThing(tmpItem);
                else
                    delete container;
            }
            else
                corpse->__internalAddThing(tmpItem);
        }
    }

    corpse->__startDecaying();
    uint32_t ownerId = corpse->getCorpseOwner();
    if(!ownerId)
        return;

    Player* owner = g_game.getPlayerByGuid(ownerId);
    if(!owner)
        return;

    LootMessage_t message = lootMessage;
    if(message == LOOTMSG_IGNORE)
        message = (LootMessage_t)g_config.getNumber(ConfigManager::LOOT_MESSAGE);

    if(message < LOOTMSG_PLAYER)
        return;

    std::stringstream ss;
    ss << "Loot of " << nameDescription << ": " << corpse->getContentDescription() << ".";
    if(owner->getParty() && message > LOOTMSG_PLAYER)
        owner->getParty()->broadcastMessage((MessageClasses)g_config.getNumber(ConfigManager::LOOT_MESSAGE_TYPE), ss.str());
    else if(message == LOOTMSG_PLAYER || message == LOOTMSG_BOTH)
        owner->sendTextMessage((MessageClasses)g_config.getNumber(ConfigManager::LOOT_MESSAGE_TYPE), ss.str());
}

Item* MonsterType::createLoot(const LootBlock& lootBlock)
{
    uint16_t item = lootBlock.ids[0], random = Monsters::getLootRandom();
    if(lootBlock.ids.size() > 1)
        item = lootBlock.ids[random_range((size_t)0, lootBlock.ids.size() - 1)];

    Item* tmpItem = NULL;
    if(Item::items[item].stackable)
    {
        if(random < lootBlock.chance)
            tmpItem = Item::CreateItem(item, (random % lootBlock.count + 1));
    }
    else if(random < lootBlock.chance)
        tmpItem = Item::CreateItem(item, 0);

    if(!tmpItem)
        return NULL;

    if(lootBlock.subType != -1)
        tmpItem->setSubType(lootBlock.subType);

    if(lootBlock.actionId != -1)
        tmpItem->setActionId(lootBlock.actionId, false);

    if(lootBlock.uniqueId != -1)
        tmpItem->setUniqueId(lootBlock.uniqueId);

    if(!lootBlock.text.empty())
        tmpItem->setText(lootBlock.text);

    return tmpItem;
}

bool MonsterType::createChildLoot(Container* parent, const LootBlock& lootBlock)
{
    LootItems::const_iterator it = lootBlock.childLoot.begin();
    if(it == lootBlock.childLoot.end())
        return true;

    Item* tmpItem = NULL;
    for(; it != lootBlock.childLoot.end() && !parent->full(); ++it)
    {
        if((tmpItem = createLoot(*it)))
        {
            if(Container* container = tmpItem->getContainer())
            {
                if(createChildLoot(container, (*it)))
                    parent->__internalAddThing(container);
                else
                    delete container;
            }
            else
                parent->__internalAddThing(tmpItem);
        }
    }

    return !parent->empty();
}

bool Monsters::loadFromXml(bool reloading /*= false*/)
{
    loaded = false;
    xmlDocPtr doc = xmlParseFile(getFilePath(FILE_TYPE_OTHER, "monster/monsters.xml").c_str());
    if(!doc)
    {
        std::clog << "[Warning - Monsters::loadFromXml] Cannot load monsters file." << std::endl;
        std::clog << getLastXMLError() << std::endl;
        return false;
    }

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

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

        if(xmlStrcmp(p->name, (const xmlChar*)"monster"))
        {
            std::clog << "[Warning - Monsters::loadFromXml] Unknown node name (" << p->name << ")." << std::endl;
            p = p->next;
            continue;
        }

        std::string file, name;
        if(readXMLString(p, "file", file) && readXMLString(p, "name", name))
        {
            file = getFilePath(FILE_TYPE_OTHER, "monster/" + file);
            loadMonster(file, name, reloading);
        }

        p = p->next;
    }

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

ConditionDamage* Monsters::getDamageCondition(ConditionType_t conditionType,
    int32_t maxDamage, int32_t minDamage, int32_t startDamage, uint32_t tickInterval)
{
    if(ConditionDamage* condition = dynamic_cast<ConditionDamage*>(Condition::createCondition(CONDITIONID_COMBAT, conditionType, 0)))
    {
        condition->setParam(CONDITIONPARAM_TICKINTERVAL, tickInterval);
        condition->setParam(CONDITIONPARAM_MINVALUE, minDamage);
        condition->setParam(CONDITIONPARAM_MAXVALUE, maxDamage);
        condition->setParam(CONDITIONPARAM_STARTVALUE, startDamage);
        condition->setParam(CONDITIONPARAM_DELAYED, 1);
        return condition;
    }

    return NULL;
}

bool Monsters::deserializeSpell(xmlNodePtr node, spellBlock_t& sb, const std::string& description)
{
    sb.range = sb.minCombatValue = sb.maxCombatValue = 0;
    sb.combatSpell = sb.isMelee = false;
    sb.chance = 100;
    sb.speed = 2000;

    std::string name, scriptName;
    bool isScripted = false;
    if(readXMLString(node, "script", scriptName))
        isScripted = true;
    else if(!readXMLString(node, "name", name))
        return false;

    int32_t intValue;
    std::string strValue;
    if(readXMLInteger(node, "speed", intValue) || readXMLInteger(node, "interval", intValue))
        sb.speed = std::max(1, intValue);

    if(readXMLInteger(node, "chance", intValue))
    {
        if(intValue < 0 || intValue > 100)
            intValue = 100;

        sb.chance = intValue;
    }

    if(readXMLInteger(node, "range", intValue))
    {
        if(intValue < 0)
            intValue = 0;

        if(intValue > Map::maxViewportX * 2)
            intValue = Map::maxViewportX * 2;

        sb.range = intValue;
    }

    if(readXMLInteger(node, "min", intValue))
        sb.minCombatValue = intValue;

    if(readXMLInteger(node, "max", intValue))
        sb.maxCombatValue = intValue;

    //normalize values
    if(std::abs(sb.minCombatValue) > std::abs(sb.maxCombatValue))
        std::swap(sb.minCombatValue, sb.maxCombatValue);

    if((sb.spell = g_spells->getSpellByName(name)))
        return true;

    CombatSpell* combatSpell = NULL;
    bool needTarget = false, needDirection = false;
    if(isScripted)
    {
        if(readXMLString(node, "direction", strValue))
            needDirection = booleanString(strValue);

        if(readXMLString(node, "target", strValue))
            needTarget = booleanString(strValue);

        combatSpell = new CombatSpell(NULL, needTarget, needDirection);
        if(!combatSpell->loadScript(getFilePath(FILE_TYPE_OTHER, g_spells->getScriptBaseName() + "/scripts/" + scriptName), true))
        {
            delete combatSpell;
            return false;
        }

        if(!combatSpell->loadScriptCombat())
        {
            delete combatSpell;
            return false;

        }

        combatSpell->getCombat()->setPlayerCombatValues(FORMULA_VALUE, sb.minCombatValue, 0, sb.maxCombatValue, 0, 0, 0, 0, 0, 0, 0);
    }
    else
    {
        Combat* combat = new Combat;
        sb.combatSpell = true;
        if(readXMLInteger(node, "length", intValue))
        {
            int32_t length = intValue;
            if(length > 0)
            {
                int32_t spread = 3;
                //need direction spell
                if(readXMLInteger(node, "spread", intValue))
                    spread = std::max(0, intValue);

                CombatArea* area = new CombatArea();
                area->setupArea(length, spread);

                combat->setArea(area);
                needDirection = true;
            }
        }

        if(readXMLInteger(node, "radius", intValue))
        {
            int32_t radius = intValue;
            //target spell
            if(readXMLInteger(node, "target", intValue))
                needTarget = (intValue != 0);

            CombatArea* area = new CombatArea();
            area->setupArea(radius);
            combat->setArea(area);
        }

        std::string tmpName = asLowerCaseString(name);
        if(tmpName == "melee" || tmpName == "distance")
        {
            int32_t attack = 0, skill = 0;
            if(readXMLInteger(node, "attack", attack) && readXMLInteger(node, "skill", skill))
            {
                sb.minCombatValue = 0;
                sb.maxCombatValue = -Weapons::getMaxMeleeDamage(skill, attack);
            }

            uint32_t tickInterval = 10000;
            ConditionType_t conditionType = CONDITION_NONE;
            if(readXMLInteger(node, "physical", intValue))
                conditionType = CONDITION_PHYSICAL;
            else if(readXMLInteger(node, "fire", intValue))
                conditionType = CONDITION_FIRE;
            else if(readXMLInteger(node, "energy", intValue))
                conditionType = CONDITION_ENERGY;
            else if(readXMLInteger(node, "earth", intValue))
                conditionType = CONDITION_POISON;
            else if(readXMLInteger(node, "freeze", intValue))
                conditionType = CONDITION_FREEZING;
            else if(readXMLInteger(node, "dazzle", intValue))
                conditionType = CONDITION_DAZZLED;
            else if(readXMLInteger(node, "curse", intValue))
                conditionType = CONDITION_CURSED;
            else if(readXMLInteger(node, "drown", intValue))
            {
                conditionType = CONDITION_DROWN;
                tickInterval = 5000;
            }
            else if(readXMLInteger(node, "poison", intValue))
            {
                conditionType = CONDITION_POISON;
                tickInterval = 5000;
            }

            uint32_t damage = std::abs(intValue);
            if(readXMLInteger(node, "tick", intValue) && intValue > 0)
                tickInterval = intValue;

            if(conditionType != CONDITION_NONE)
            {
                Condition* condition = getDamageCondition(conditionType, damage, damage, 0, tickInterval);
                if(condition)
                    combat->setCondition(condition);
            }

            sb.isMelee = true;
            sb.range = 1;

            combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_PHYSICALDAMAGE);
            combat->setParam(COMBATPARAM_BLOCKEDBYSHIELD, 1);
            combat->setParam(COMBATPARAM_BLOCKEDBYARMOR, 1);
        }
        else if(tmpName == "physical")
        {
            combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_PHYSICALDAMAGE);
            combat->setParam(COMBATPARAM_BLOCKEDBYARMOR, 1);
        }
        else if(tmpName == "drown")
            combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_DROWNDAMAGE);
        else if(tmpName == "fire")
            combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_FIREDAMAGE);
        else if(tmpName == "energy")
            combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_ENERGYDAMAGE);
        else if(tmpName == "poison" || tmpName == "earth")
            combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_EARTHDAMAGE);
        else if(tmpName == "ice")
            combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_ICEDAMAGE);
        else if(tmpName == "holy")
            combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_HOLYDAMAGE);
        else if(tmpName == "death")
            combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_DEATHDAMAGE);
        else if(tmpName == "lifedrain")
            combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_LIFEDRAIN);
        else if(tmpName == "manadrain")
            combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_MANADRAIN);
        else if(tmpName == "healing")
        {
            bool aggressive = false;
            if(readXMLInteger(node, "self", intValue))
                aggressive = intValue;

            combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_HEALING);
            combat->setParam(COMBATPARAM_AGGRESSIVE, aggressive);
        }
        else if(tmpName == "undefined")
            combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_UNDEFINEDDAMAGE);
        else if(tmpName == "speed")
        {
            int32_t speedChange = 0, duration = 10000;
            if(readXMLInteger(node, "duration", intValue))
                duration = intValue;

            enum Aggressive {
                NO,
                YES,
                AUTO
            } aggressive = AUTO;
            if(readXMLInteger(node, "self", intValue))
                aggressive = (Aggressive)intValue;

            if(readXMLInteger(node, "speedchange", intValue))
                speedChange = std::max(-1000, intValue); //cant be slower than 100%

            std::vector<Outfit_t> outfits;
            for(xmlNodePtr tmpNode = node->children; tmpNode; tmpNode = tmpNode->next)
            {
                if(xmlStrcmp(tmpNode->name,(const xmlChar*)"outfit"))
                    continue;

                if(readXMLInteger(tmpNode, "type", intValue))
                {
                    Outfit_t outfit;
                    outfit.lookType = intValue;
                    if(readXMLInteger(tmpNode, "head", intValue))
                        outfit.lookHead = intValue;

                    if(readXMLInteger(tmpNode, "body", intValue))
                        outfit.lookBody = intValue;

                    if(readXMLInteger(tmpNode, "legs", intValue))
                        outfit.lookLegs = intValue;

                    if(readXMLInteger(tmpNode, "feet", intValue))
                        outfit.lookFeet = intValue;

                    if(readXMLInteger(tmpNode, "addons", intValue))
                        outfit.lookAddons = intValue;

                    outfits.push_back(outfit);
                }

                if(readXMLInteger(tmpNode, "typeex", intValue) || readXMLInteger(tmpNode, "item", intValue))
                {
                    Outfit_t outfit;
                    outfit.lookTypeEx = intValue;
                    outfits.push_back(outfit);
                }

                if(readXMLString(tmpNode, "monster", strValue))
                {
                    if(MonsterType* mType = g_monsters.getMonsterType(strValue))
                        outfits.push_back(mType->outfit);
                }
            }

            ConditionType_t conditionType = CONDITION_PARALYZE;
            if(speedChange > 0)
            {
                conditionType = CONDITION_HASTE;
                if(aggressive == AUTO)
                    aggressive = NO;
            }
            else if(aggressive == AUTO)
                aggressive = YES;

            if(ConditionSpeed* condition = dynamic_cast<ConditionSpeed*>(Condition::createCondition(
                CONDITIONID_COMBAT, conditionType, duration)))
            {
                condition->setFormulaVars((speedChange / 1000.), 0, (speedChange / 1000.), 0);
                if(!outfits.empty())
                    condition->setOutfits(outfits);

                combat->setCondition(condition);
                combat->setParam(COMBATPARAM_AGGRESSIVE, aggressive);
            }
        }
        else if(tmpName == "outfit")
        {
            std::vector<Outfit_t> outfits;
            for(xmlNodePtr tmpNode = node->children; tmpNode; tmpNode = tmpNode->next)
            {
                if(xmlStrcmp(tmpNode->name,(const xmlChar*)"outfit"))
                    continue;

                if(readXMLInteger(tmpNode, "type", intValue))
                {
                    Outfit_t outfit;
                    outfit.lookType = intValue;
                    if(readXMLInteger(tmpNode, "head", intValue))
                        outfit.lookHead = intValue;

                    if(readXMLInteger(tmpNode, "body", intValue))
                        outfit.lookBody = intValue;

                    if(readXMLInteger(tmpNode, "legs", intValue))
                        outfit.lookLegs = intValue;

                    if(readXMLInteger(tmpNode, "feet", intValue))
                        outfit.lookFeet = intValue;

                    if(readXMLInteger(tmpNode, "addons", intValue))
                        outfit.lookAddons = intValue;

                    outfits.push_back(outfit);
                }

                if(readXMLInteger(tmpNode, "typeex", intValue) || readXMLInteger(tmpNode, "item", intValue))
                {
                    Outfit_t outfit;
                    outfit.lookTypeEx = intValue;
                    outfits.push_back(outfit);
                }

                if(readXMLString(tmpNode, "monster", strValue))
                {
                    if(MonsterType* mType = g_monsters.getMonsterType(strValue))
                        outfits.push_back(mType->outfit);
                }
            }

            if(outfits.empty())
            {
                if(readXMLInteger(node, "type", intValue))
                {
                    Outfit_t outfit;
                    outfit.lookType = intValue;
                    if(readXMLInteger(node, "head", intValue))
                        outfit.lookHead = intValue;

                    if(readXMLInteger(node, "body", intValue))
                        outfit.lookBody = intValue;

                    if(readXMLInteger(node, "legs", intValue))
                        outfit.lookLegs = intValue;

                    if(readXMLInteger(node, "feet", intValue))
                        outfit.lookFeet = intValue;

                    if(readXMLInteger(node, "addons", intValue))
                        outfit.lookAddons = intValue;

                    outfits.push_back(outfit);
                }

                if(readXMLInteger(node, "typeex", intValue) || readXMLInteger(node, "item", intValue))
                {
                    Outfit_t outfit;
                    outfit.lookTypeEx = intValue;
                    outfits.push_back(outfit);
                }

                if(readXMLString(node, "monster", strValue))
                {
                    if(MonsterType* mType = g_monsters.getMonsterType(strValue))
                        outfits.push_back(mType->outfit);
                }
            }

            if(!outfits.empty())
            {
                int32_t duration = 10000;
                if(readXMLInteger(node, "duration", intValue))
                    duration = intValue;

                bool aggressive = false;
                if(readXMLInteger(node, "self", intValue))
                    aggressive = intValue;

                if(ConditionOutfit* condition = dynamic_cast<ConditionOutfit*>(Condition::createCondition(
                    CONDITIONID_COMBAT, CONDITION_OUTFIT, duration)))
                {
                    condition->setOutfits(outfits);
                    combat->setCondition(condition);
                    combat->setParam(COMBATPARAM_AGGRESSIVE, aggressive);
                }
            }
        }
        else if(tmpName == "invisible")
        {
            int32_t duration = 10000;
            if(readXMLInteger(node, "duration", intValue))
                duration = intValue;

            bool aggressive = false;
            if(readXMLInteger(node, "self", intValue))
                aggressive = intValue;

            if(Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_INVISIBLE, duration))
            {
                combat->setParam(COMBATPARAM_AGGRESSIVE, aggressive);
                combat->setCondition(condition);
            }
        }
        else if(tmpName == "drunk")
        {
            int32_t duration = 10000;
            if(readXMLInteger(node, "duration", intValue))
                duration = intValue;

            if(Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_DRUNK, duration))
                combat->setCondition(condition);
        }
        else if(tmpName == "skills" || tmpName == "attributes")
        {
            uint32_t duration = 10000, subId = 0;
            if(readXMLInteger(node, "duration", intValue))
                duration = intValue;

            if(readXMLInteger(node, "subid", intValue))
                subId = intValue;

            intValue = 0;
            ConditionParam_t param = CONDITIONPARAM_BUFF; //to know was it loaded
            if(readXMLInteger(node, "melee", intValue))
                param = CONDITIONPARAM_SKILL_MELEE;
            else if(readXMLInteger(node, "fist", intValue))
                param = CONDITIONPARAM_SKILL_FIST;
            else if(readXMLInteger(node, "club", intValue))
                param = CONDITIONPARAM_SKILL_CLUB;
            else if(readXMLInteger(node, "axe", intValue))
                param = CONDITIONPARAM_SKILL_AXE;
            else if(readXMLInteger(node, "sword", intValue))
                param = CONDITIONPARAM_SKILL_SWORD;
            else if(readXMLInteger(node, "distance", intValue) || readXMLInteger(node, "dist", intValue))
                param = CONDITIONPARAM_SKILL_DISTANCE;
            else if(readXMLInteger(node, "shielding", intValue) || readXMLInteger(node, "shield", intValue))
                param = CONDITIONPARAM_SKILL_SHIELD;
            else if(readXMLInteger(node, "fishing", intValue) || readXMLInteger(node, "fish", intValue))
                param = CONDITIONPARAM_SKILL_FISHING;
            else if(readXMLInteger(node, "meleePercent", intValue))
                param = CONDITIONPARAM_SKILL_MELEEPERCENT;
            else if(readXMLInteger(node, "fistPercent", intValue))
                param = CONDITIONPARAM_SKILL_FISTPERCENT;
            else if(readXMLInteger(node, "clubPercent", intValue))
                param = CONDITIONPARAM_SKILL_CLUBPERCENT;
            else if(readXMLInteger(node, "axePercent", intValue))
                param = CONDITIONPARAM_SKILL_AXEPERCENT;
            else if(readXMLInteger(node, "swordPercent", intValue))
                param = CONDITIONPARAM_SKILL_SWORDPERCENT;
            else if(readXMLInteger(node, "distancePercent", intValue) || readXMLInteger(node, "distPercent", intValue))
                param = CONDITIONPARAM_SKILL_DISTANCEPERCENT;
            else if(readXMLInteger(node, "shieldingPercent", intValue) || readXMLInteger(node, "shieldPercent", intValue))
                param = CONDITIONPARAM_SKILL_SHIELDPERCENT;
            else if(readXMLInteger(node, "fishingPercent", intValue) || readXMLInteger(node, "fishPercent", intValue))
                param = CONDITIONPARAM_SKILL_FISHINGPERCENT;
            else if(readXMLInteger(node, "maxhealth", intValue))
                param = CONDITIONPARAM_STAT_MAXHEALTHPERCENT;
            else if(readXMLInteger(node, "maxmana", intValue))
                param = CONDITIONPARAM_STAT_MAXMANAPERCENT;
            else if(readXMLInteger(node, "soul", intValue))
                param = CONDITIONPARAM_STAT_SOULPERCENT;
            else if(readXMLInteger(node, "magiclevel", intValue) || readXMLInteger(node, "maglevel", intValue))
                param = CONDITIONPARAM_STAT_MAGICLEVELPERCENT;
            else if(readXMLInteger(node, "maxhealthPercent", intValue))
                param = CONDITIONPARAM_STAT_MAXHEALTHPERCENT;
            else if(readXMLInteger(node, "maxmanaPercent", intValue))
                param = CONDITIONPARAM_STAT_MAXMANAPERCENT;
            else if(readXMLInteger(node, "soulPercent", intValue))
                param = CONDITIONPARAM_STAT_SOULPERCENT;
            else if(readXMLInteger(node, "magiclevelPercent", intValue) || readXMLInteger(node, "maglevelPercent", intValue))
                param = CONDITIONPARAM_STAT_MAGICLEVELPERCENT;

            if(param != CONDITIONPARAM_BUFF)
            {
                if(ConditionAttributes* condition = dynamic_cast<ConditionAttributes*>(Condition::createCondition(
                    CONDITIONID_COMBAT, CONDITION_ATTRIBUTES, duration, false, subId)))
                {
                    condition->setParam(param, intValue);
                    combat->setCondition(condition);
                }
            }
        }
        else if(tmpName == "firefield")
            combat->setParam(COMBATPARAM_CREATEITEM, 1492);
        else if(tmpName == "poisonfield")
            combat->setParam(COMBATPARAM_CREATEITEM, 1496);
        else if(tmpName == "energyfield")
            combat->setParam(COMBATPARAM_CREATEITEM, 1495);
        else if(tmpName == "firecondition" || tmpName == "energycondition" || tmpName == "drowncondition" ||
            tmpName == "poisoncondition" || tmpName == "earthcondition" || tmpName == "freezecondition" ||
            tmpName == "cursecondition" || tmpName == "dazzlecondition")
        {
            ConditionType_t conditionType = CONDITION_NONE;
            uint32_t tickInterval = 2000;
            if(tmpName == "physicalcondition")
            {
                conditionType = CONDITION_PHYSICAL;
                tickInterval = 5000;
            }
            else if(tmpName == "firecondition")
            {
                conditionType = CONDITION_FIRE;
                tickInterval = 10000;
            }
            else if(tmpName == "energycondition")
            {
                conditionType = CONDITION_ENERGY;
                tickInterval = 10000;
            }
            else if(tmpName == "earthcondition")
            {
                conditionType = CONDITION_POISON;
                tickInterval = 10000;
            }
            else if(tmpName == "freezecondition")
            {
                conditionType = CONDITION_FREEZING;
                tickInterval = 10000;
            }
            else if(tmpName == "cursecondition")
            {
                conditionType = CONDITION_CURSED;
                tickInterval = 10000;
            }
            else if(tmpName == "dazzlecondition")
            {
                conditionType = CONDITION_DAZZLED;
                tickInterval = 10000;
            }
            else if(tmpName == "drowncondition")
            {
                conditionType = CONDITION_DROWN;
                tickInterval = 5000;
            }
            else if(tmpName == "poisoncondition")
            {
                conditionType = CONDITION_POISON;
                tickInterval = 5000;
            }

            if(readXMLInteger(node, "tick", intValue) && intValue > 0)
                tickInterval = intValue;

            int32_t startDamage = 0, minDamage = std::abs(sb.minCombatValue), maxDamage = std::abs(sb.maxCombatValue);
            if(readXMLInteger(node, "start", intValue))
                startDamage = std::max(std::abs(intValue), minDamage);

            if(Condition* condition = getDamageCondition(conditionType, maxDamage, minDamage, startDamage, tickInterval))
                combat->setCondition(condition);
        }
        else if(tmpName == "strength")
        {
            //TODO: monster extra strength
        }
        else if(tmpName == "effect")
            {/*show some effect and bye bye!*/}
        else
        {
            delete combat;
            std::clog << "[Error - Monsters::deserializeSpell] " << description << " - Unknown spell name: " << name << std::endl;
            return false;
        }

        combat->setPlayerCombatValues(FORMULA_VALUE, sb.minCombatValue, 0, sb.maxCombatValue, 0, 0, 0, 0, 0, 0, 0);
        combatSpell = new CombatSpell(combat, needTarget, needDirection);

        xmlNodePtr attributeNode = node->children;
        while(attributeNode)
        {
            if(!xmlStrcmp(attributeNode->name, (const xmlChar*)"attribute"))
            {
                if(readXMLString(attributeNode, "key", strValue))
                {
                    std::string tmpStrValue = asLowerCaseString(strValue);
                    if(tmpStrValue == "shooteffect")
                    {
                        if(readXMLString(attributeNode, "value", strValue))
                        {
                            ShootEffect_t shoot = getShootType(strValue);
                            if(shoot != SHOOT_EFFECT_UNKNOWN)
                                combat->setParam(COMBATPARAM_DISTANCEEFFECT, shoot);
                            else
                                std::clog << "[Warning - Monsters::deserializeSpell] " << description << " - Unknown shootEffect: " << strValue << std::endl;
                        }
                    }
                    else if(tmpStrValue == "areaeffect")
                    {
                        if(readXMLString(attributeNode, "value", strValue))
                        {
                            MagicEffect_t effect = getMagicEffect(strValue);
                            if(effect != MAGIC_EFFECT_UNKNOWN)
                                combat->setParam(COMBATPARAM_EFFECT, effect);
                            else
                                std::clog << "[Warning - Monsters::deserializeSpell] " << description << " - Unknown areaEffect: " << strValue << std::endl;
                        }
                    }
                    else
                        std::clog << "[Warning - Monsters::deserializeSpells] Effect type \"" << strValue << "\" does not exist." << std::endl;
                }
            }
            attributeNode = attributeNode->next;
        }
    }

    sb.spell = combatSpell;
    return true;
}

#define SHOW_XML_WARNING(desc) std::clog << "[Warning - Monsters::loadMonster] " << desc << ". (" << file << ")" << std::endl;
#define SHOW_XML_ERROR(desc) std::clog << "[Error - Monsters::loadMonster] " << desc << ". (" << file << ")" << std::endl;

bool Monsters::loadMonster(const std::string& file, const std::string& monsterName, bool reloading/* = false*/)
{
    if(getIdByName(monsterName) && !reloading)
    {
        std::clog << "[Warning - Monsters::loadMonster] Duplicate registered monster with name: " << monsterName << std::endl;
        return true;
    }

    bool monsterLoad, new_mType = true;
    MonsterType* mType = NULL;
    if(reloading)
    {
        uint32_t id = getIdByName(monsterName);
        if(id != 0)
        {
            mType = getMonsterType(id);
            if(mType != NULL)
            {
                new_mType = false;
                mType->reset();
            }
        }
    }

    if(new_mType)
        mType = new MonsterType();

    xmlDocPtr doc = xmlParseFile(file.c_str());
    if(!doc)
    {
        std::clog << "[Warning - Monsters::loadMonster] Cannot load monster (" << monsterName << ") file (" << file << ")." << std::endl;
        std::clog << getLastXMLError() << std::endl;
        return false;
    }

    monsterLoad = true;
    xmlNodePtr p, root = xmlDocGetRootElement(doc);
    if(xmlStrcmp(root->name,(const xmlChar*)"monster"))
    {
        std::clog << "[Error - Monsters::loadMonster] Malformed monster (" << monsterName << ") file (" << file << ")." << std::endl;
        xmlFreeDoc(doc);
        return false;
    }

    int32_t intValue;
    std::string strValue;
    if(readXMLString(root, "name", strValue))
        mType->name = strValue;
    else
        monsterLoad = false;

    if(readXMLString(root, "nameDescription", strValue))
        mType->nameDescription = strValue;
    else
    {
        mType->nameDescription = "a " + mType->name;
        toLowerCaseString(mType->nameDescription);
    }

    if(readXMLString(root, "race", strValue))
    {
        std::string tmpStrValue = asLowerCaseString(strValue);
        if(tmpStrValue == "venom" || atoi(strValue.c_str()) == 1)
            mType->race = RACE_VENOM;
        else if(tmpStrValue == "blood" || atoi(strValue.c_str()) == 2)
            mType->race = RACE_BLOOD;
        else if(tmpStrValue == "undead" || atoi(strValue.c_str()) == 3)
            mType->race = RACE_UNDEAD;
        else if(tmpStrValue == "fire" || atoi(strValue.c_str()) == 4)
            mType->race = RACE_FIRE;
        else if(tmpStrValue == "energy" || atoi(strValue.c_str()) == 5)
            mType->race = RACE_ENERGY;
        else
            SHOW_XML_WARNING("Unknown race type " << strValue);
    }

    if(readXMLInteger(root, "experience", intValue))
        mType->experience = intValue;

    if(readXMLInteger(root, "speed", intValue))
        mType->baseSpeed = intValue;

    if(readXMLInteger(root, "manacost", intValue))
        mType->manaCost = intValue;

    if(readXMLString(root, "skull", strValue))
        mType->skull = getSkulls(strValue);

    if(readXMLString(root, "shield", strValue))
        mType->partyShield = getShields(strValue);

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

    p = root->children;
    while(p && monsterLoad)
    {
        if(p->type != XML_ELEMENT_NODE)
        {
            p = p->next;
            continue;
        }

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

            if(readXMLInteger(p, "max", intValue))
                mType->healthMax = intValue;
            else
            {
                SHOW_XML_ERROR("Missing health.max");
                monsterLoad = false;
            }
        }
        else if(!xmlStrcmp(p->name, (const xmlChar*)"flags"))
        {
            xmlNodePtr tmpNode = p->children;
            while(tmpNode)
            {
                if(xmlStrcmp(tmpNode->name, (const xmlChar*)"flag") == 0)
                {
                    if(readXMLString(tmpNode, "summonable", strValue))
                        mType->isSummonable = booleanString(strValue);

                    if(readXMLString(tmpNode, "attackable", strValue))
                        mType->isAttackable = booleanString(strValue);

                    if(readXMLString(tmpNode, "hostile", strValue))
                        mType->isHostile = booleanString(strValue);

                    if(readXMLString(tmpNode, "illusionable", strValue))
                        mType->isIllusionable = booleanString(strValue);

                    if(readXMLString(tmpNode, "convinceable", strValue))
                        mType->isConvinceable = booleanString(strValue);

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

                    if(readXMLString(tmpNode, "canpushitems", strValue))
                        mType->canPushItems = booleanString(strValue);

                    if(readXMLString(tmpNode, "canpushcreatures", strValue))
                        mType->canPushCreatures = booleanString(strValue);

                    if(readXMLString(tmpNode, "hidename", strValue))
                        mType->hideName = booleanString(strValue);

                    if(readXMLString(tmpNode, "hidehealth", strValue))
                        mType->hideHealth = booleanString(strValue);

                    if(readXMLInteger(tmpNode, "lootmessage", intValue))
                        mType->lootMessage = (LootMessage_t)intValue;

                    if(readXMLInteger(tmpNode, "staticattack", intValue))
                    {
                        if(intValue < 0 || intValue > 100)
                        {
                            SHOW_XML_WARNING("staticattack lower than 0 or greater than 100");
                            intValue = 0;
                        }

                        mType->staticAttackChance = intValue;
                    }

                    if(readXMLInteger(tmpNode, "lightlevel", intValue))
                        mType->lightLevel = intValue;

                    if(readXMLInteger(tmpNode, "lightcolor", intValue))
                        mType->lightColor = intValue;

                    if(readXMLInteger(tmpNode, "targetdistance", intValue))
                    {
                        if(intValue > Map::maxViewportX)
                            SHOW_XML_WARNING("targetdistance greater than maxViewportX");

                        mType->targetDistance = std::max(1, intValue);
                    }

                    if(readXMLInteger(tmpNode, "runonhealth", intValue))
                        mType->runAwayHealth = intValue;

                    if(readXMLString(tmpNode, "lureable", strValue))
                        mType->isLureable = booleanString(strValue);

                    if(readXMLString(tmpNode, "walkable", strValue))
                        mType->isWalkable = booleanString(strValue);

                    if(readXMLString(tmpNode, "skull", strValue))
                        mType->skull = getSkulls(strValue);

                    if(readXMLString(tmpNode, "shield", strValue))
                        mType->partyShield = getShields(strValue);

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

                tmpNode = tmpNode->next;
            }

            //if a monster can push creatures, it should not be pushable
            if(mType->canPushCreatures && mType->pushable)
                mType->pushable = false;
        }
        else if(!xmlStrcmp(p->name, (const xmlChar*)"targetchange"))
        {
            if(readXMLInteger(p, "speed", intValue) || readXMLInteger(p, "interval", intValue))
                mType->changeTargetSpeed = std::max(1, intValue);
            else
                SHOW_XML_WARNING("Missing targetchange.speed");

            if(readXMLInteger(p, "chance", intValue))
                mType->changeTargetChance = intValue;
            else
                SHOW_XML_WARNING("Missing targetchange.chance");
        }
        else if(!xmlStrcmp(p->name, (const xmlChar*)"strategy"))
        {
            if(readXMLInteger(p, "attack", intValue)) {}
                //mType->attackStrength = intValue;

            if(readXMLInteger(p, "defense", intValue)) {}
                //mType->defenseStrength = intValue;
        }
        else if(!xmlStrcmp(p->name, (const xmlChar*)"look"))
        {
            if(readXMLInteger(p, "type", intValue))
            {
                mType->outfit.lookType = intValue;
                if(readXMLInteger(p, "head", intValue))
                    mType->outfit.lookHead = intValue;

                if(readXMLInteger(p, "body", intValue))
                    mType->outfit.lookBody = intValue;

                if(readXMLInteger(p, "legs", intValue))
                    mType->outfit.lookLegs = intValue;

                if(readXMLInteger(p, "feet", intValue))
                    mType->outfit.lookFeet = intValue;

                if(readXMLInteger(p, "addons", intValue))
                    mType->outfit.lookAddons = intValue;
            }
            else if(readXMLInteger(p, "typeex", intValue))
                mType->outfit.lookTypeEx = intValue;
            else
                SHOW_XML_WARNING("Missing look type/typeex");

            if(readXMLInteger(p, "corpse", intValue))
                mType->lookCorpse = intValue;

            if(readXMLInteger(p, "corpseUniqueId", intValue) || readXMLInteger(p, "corpseUid", intValue))
                mType->corpseUnique = intValue;

            if(readXMLInteger(p, "corpseActionId", intValue) || readXMLInteger(p, "corpseAid", intValue))
                mType->corpseAction = intValue;
        }
        else if(!xmlStrcmp(p->name, (const xmlChar*)"attacks"))
        {
            xmlNodePtr tmpNode = p->children;
            while(tmpNode)
            {
                if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"attack"))
                {
                    spellBlock_t sb;
                    if(deserializeSpell(tmpNode, sb, monsterName))
                        mType->spellAttackList.push_back(sb);
                    else
                        SHOW_XML_WARNING("Cant load spell");
                }

                tmpNode = tmpNode->next;
            }
        }
        else if(!xmlStrcmp(p->name, (const xmlChar*)"defenses"))
        {
            if(readXMLInteger(p, "defense", intValue))
                mType->defense = intValue;

            if(readXMLInteger(p, "armor", intValue))
                mType->armor = intValue;

            xmlNodePtr tmpNode = p->children;
            while(tmpNode)
            {
                if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"defense"))
                {
                    spellBlock_t sb;
                    if(deserializeSpell(tmpNode, sb, monsterName))
                        mType->spellDefenseList.push_back(sb);
                    else
                        SHOW_XML_WARNING("Cant load spell");
                }

                tmpNode = tmpNode->next;
            }
        }
        else if(!xmlStrcmp(p->name, (const xmlChar*)"immunities"))
        {
            xmlNodePtr tmpNode = p->children;
            while(tmpNode)
            {
                if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"immunity"))
                {
                    if(readXMLString(tmpNode, "name", strValue))
                    {
                        std::string tmpStrValue = asLowerCaseString(strValue);
                        if(tmpStrValue == "physical")
                        {
                            mType->damageImmunities |= COMBAT_PHYSICALDAMAGE;
                            mType->conditionImmunities |= CONDITION_PHYSICAL;
                        }
                        else if(tmpStrValue == "energy")
                        {
                            mType->damageImmunities |= COMBAT_ENERGYDAMAGE;
                            mType->conditionImmunities |= CONDITION_ENERGY;
                        }
                        else if(tmpStrValue == "fire")
                        {
                            mType->damageImmunities |= COMBAT_FIREDAMAGE;
                            mType->conditionImmunities |= CONDITION_FIRE;
                        }
                        else if(tmpStrValue == "poison" || tmpStrValue == "earth")
                        {
                            mType->damageImmunities |= COMBAT_EARTHDAMAGE;
                            mType->conditionImmunities |= CONDITION_POISON;
                        }
                        else if(tmpStrValue == "ice")
                        {
                            mType->damageImmunities |= COMBAT_ICEDAMAGE;
                            mType->conditionImmunities |= CONDITION_FREEZING;
                        }
                        else if(tmpStrValue == "holy")
                        {
                            mType->damageImmunities |= COMBAT_HOLYDAMAGE;
                            mType->conditionImmunities |= CONDITION_DAZZLED;
                        }
                        else if(tmpStrValue == "death")
                        {
                            mType->damageImmunities |= COMBAT_DEATHDAMAGE;
                            mType->conditionImmunities |= CONDITION_CURSED;
                        }
                        else if(tmpStrValue == "drown")
                        {
                            mType->damageImmunities |= COMBAT_DROWNDAMAGE;
                            mType->conditionImmunities |= CONDITION_DROWN;
                        }
                        else if(tmpStrValue == "lifedrain")
                            mType->damageImmunities |= COMBAT_LIFEDRAIN;
                        else if(tmpStrValue == "manadrain")
                            mType->damageImmunities |= COMBAT_MANADRAIN;
                        else if(tmpStrValue == "paralyze")
                            mType->conditionImmunities |= CONDITION_PARALYZE;
                        else if(tmpStrValue == "outfit")
                            mType->conditionImmunities |= CONDITION_OUTFIT;
                        else if(tmpStrValue == "drunk")
                            mType->conditionImmunities |= CONDITION_DRUNK;
                        else if(tmpStrValue == "invisible")
                            mType->conditionImmunities |= CONDITION_INVISIBLE;
                        else
                            SHOW_XML_WARNING("Unknown immunity name " << strValue);
                    }
                    else if(readXMLString(tmpNode, "physical", strValue) && booleanString(strValue))
                    {
                        mType->damageImmunities |= COMBAT_PHYSICALDAMAGE;
                        //mType->conditionImmunities |= CONDITION_PHYSICAL;
                    }
                    else if(readXMLString(tmpNode, "energy", strValue) && booleanString(strValue))
                    {
                        mType->damageImmunities |= COMBAT_ENERGYDAMAGE;
                        mType->conditionImmunities |= CONDITION_ENERGY;
                    }
                    else if(readXMLString(tmpNode, "fire", strValue) && booleanString(strValue))
                    {
                        mType->damageImmunities |= COMBAT_FIREDAMAGE;
                        mType->conditionImmunities |= CONDITION_FIRE;
                    }
                    else if((readXMLString(tmpNode, "poison", strValue) || readXMLString(tmpNode, "earth", strValue))
                        && booleanString(strValue))
                    {
                        mType->damageImmunities |= COMBAT_EARTHDAMAGE;
                        mType->conditionImmunities |= CONDITION_POISON;
                    }
                    else if(readXMLString(tmpNode, "drown", strValue) && booleanString(strValue))
                    {
                        mType->damageImmunities |= COMBAT_DROWNDAMAGE;
                        mType->conditionImmunities |= CONDITION_DROWN;
                    }
                    else if(readXMLString(tmpNode, "ice", strValue) && booleanString(strValue))
                    {
                        mType->damageImmunities |= COMBAT_ICEDAMAGE;
                        mType->conditionImmunities |= CONDITION_FREEZING;
                    }
                    else if(readXMLString(tmpNode, "holy", strValue) && booleanString(strValue))
                    {
                        mType->damageImmunities |= COMBAT_HOLYDAMAGE;
                        mType->conditionImmunities |= CONDITION_DAZZLED;
                    }
                    else if(readXMLString(tmpNode, "death", strValue) && booleanString(strValue))
                    {
                        mType->damageImmunities |= COMBAT_DEATHDAMAGE;
                        mType->conditionImmunities |= CONDITION_CURSED;
                    }
                    else if(readXMLString(tmpNode, "lifedrain", strValue) && booleanString(strValue))
                        mType->damageImmunities |= COMBAT_LIFEDRAIN;
                    else if(readXMLString(tmpNode, "manadrain", strValue) && booleanString(strValue))
                        mType->damageImmunities |= COMBAT_LIFEDRAIN;
                    else if(readXMLString(tmpNode, "paralyze", strValue) && booleanString(strValue))
                        mType->conditionImmunities |= CONDITION_PARALYZE;
                    else if(readXMLString(tmpNode, "outfit", strValue) && booleanString(strValue))
                        mType->conditionImmunities |= CONDITION_OUTFIT;
                    else if(readXMLString(tmpNode, "drunk", strValue) && booleanString(strValue))
                        mType->conditionImmunities |= CONDITION_DRUNK;
                    else if(readXMLString(tmpNode, "invisible", strValue) && booleanString(strValue))
                        mType->conditionImmunities |= CONDITION_INVISIBLE;
                }

                tmpNode = tmpNode->next;
            }
        }
        else if(!xmlStrcmp(p->name, (const xmlChar*)"voices"))
        {
            if(readXMLInteger(p, "speed", intValue) || readXMLInteger(p, "interval", intValue))
                mType->yellSpeedTicks = intValue;
            else
                SHOW_XML_WARNING("Missing voices.speed");

            if(readXMLInteger(p, "chance", intValue))
                mType->yellChance = intValue;
            else
                SHOW_XML_WARNING("Missing voices.chance");

            xmlNodePtr tmpNode = p->children;
            while(tmpNode)
            {
                if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"voice"))
                {
                    voiceBlock_t vb;
                    vb.text = "";
                    vb.yellText = false;

                    if(readXMLString(tmpNode, "sentence", strValue))
                        vb.text = strValue;
                    else
                        SHOW_XML_WARNING("Missing voice.sentence");

                    if(readXMLString(tmpNode, "yell", strValue))
                        vb.yellText = booleanString(strValue);

                    mType->voiceVector.push_back(vb);
                }

                tmpNode = tmpNode->next;
            }
        }
        else if(!xmlStrcmp(p->name, (const xmlChar*)"loot"))
        {
            xmlNodePtr tmpNode = p->children;
            while(tmpNode)
            {
                if(tmpNode->type != XML_ELEMENT_NODE)
                {
                    tmpNode = tmpNode->next;
                    continue;
                }

                LootBlock rootBlock;
                if(loadLoot(tmpNode, rootBlock))
                    mType->lootItems.push_back(rootBlock);
                else
                    SHOW_XML_WARNING("Cant load loot");

                tmpNode = tmpNode->next;
            }
        }
        else if(!xmlStrcmp(p->name, (const xmlChar*)"elements"))
        {
            xmlNodePtr tmpNode = p->children;
            while(tmpNode)
            {
                if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"element"))
                {
                    if(readXMLInteger(tmpNode, "firePercent", intValue))
                        mType->elementMap[COMBAT_FIREDAMAGE] = intValue;
                    else if(readXMLInteger(tmpNode, "energyPercent", intValue))
                        mType->elementMap[COMBAT_ENERGYDAMAGE] = intValue;
                    else if(readXMLInteger(tmpNode, "icePercent", intValue))
                        mType->elementMap[COMBAT_ICEDAMAGE] = intValue;
                    else if(readXMLInteger(tmpNode, "poisonPercent", intValue) || readXMLInteger(tmpNode, "earthPercent", intValue))
                        mType->elementMap[COMBAT_EARTHDAMAGE] = intValue;
                    else if(readXMLInteger(tmpNode, "holyPercent", intValue))
                        mType->elementMap[COMBAT_HOLYDAMAGE] = intValue;
                    else if(readXMLInteger(tmpNode, "deathPercent", intValue))
                        mType->elementMap[COMBAT_DEATHDAMAGE] = intValue;
                    else if(readXMLInteger(tmpNode, "drownPercent", intValue))
                        mType->elementMap[COMBAT_DROWNDAMAGE] = intValue;
                    else if(readXMLInteger(tmpNode, "physicalPercent", intValue))
                        mType->elementMap[COMBAT_PHYSICALDAMAGE] = intValue;
                    else if(readXMLInteger(tmpNode, "lifeDrainPercent", intValue))
                        mType->elementMap[COMBAT_LIFEDRAIN] = intValue;
                    else if(readXMLInteger(tmpNode, "manaDrainPercent", intValue))
                        mType->elementMap[COMBAT_MANADRAIN] = intValue;
                    else if(readXMLInteger(tmpNode, "healingPercent", intValue))
                        mType->elementMap[COMBAT_HEALING] = intValue;
                    else if(readXMLInteger(tmpNode, "undefinedPercent", intValue))
                        mType->elementMap[COMBAT_UNDEFINEDDAMAGE] = intValue;
                }

                tmpNode = tmpNode->next;
            }
        }
        else if(!xmlStrcmp(p->name, (const xmlChar*)"summons"))
        {
            if(readXMLInteger(p, "maxSummons", intValue) || readXMLInteger(p, "max", intValue))
                mType->maxSummons = intValue;

            xmlNodePtr tmpNode = p->children;
            while(tmpNode)
            {
                if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"summon"))
                {
                    uint32_t chance = 100, interval = 1000, amount = 1;
                    if(readXMLInteger(tmpNode, "speed", intValue) || readXMLInteger(tmpNode, "interval", intValue))
                        interval = intValue;

                    if(readXMLInteger(tmpNode, "chance", intValue))
                        chance = intValue;

                    if(readXMLInteger(tmpNode, "amount", intValue) || readXMLInteger(tmpNode, "max", intValue))
                        amount = intValue;

                    if(readXMLString(tmpNode, "name", strValue))
                    {
                        summonBlock_t sb;
                        sb.name = strValue;
                        sb.interval = interval;
                        sb.chance = chance;
                        sb.amount = amount;

                        mType->summonList.push_back(sb);
                    }
                    else
                        SHOW_XML_WARNING("Missing summon.name");
                }

                tmpNode = tmpNode->next;
            }
        }
        else if(!xmlStrcmp(p->name, (const xmlChar*)"script"))
        {
            xmlNodePtr tmpNode = p->children;
            while(tmpNode)
            {
                if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"event"))
                {
                    if(readXMLString(tmpNode, "name", strValue))
                        mType->scriptList.push_back(strValue);
                    else
                        SHOW_XML_WARNING("Missing name for script event");
                }

                tmpNode = tmpNode->next;
            }
        }
        else
            SHOW_XML_WARNING("Unknown attribute type - " << p->name);

        p = p->next;
    }

    xmlFreeDoc(doc);
    if(monsterLoad)
    {
        static uint32_t id = 0;
        if(new_mType)
        {
            id++;
            monsterNames[asLowerCaseString(monsterName)] = id;
            monsters[id] = mType;
        }

        return true;
    }

    if(new_mType)
        delete mType;

    return false;
}

bool Monsters::loadLoot(xmlNodePtr node, LootBlock& lootBlock)
{
    std::string strValue;
    if(readXMLString(node, "id", strValue) || readXMLString(node, "ids", strValue))
    {
        IntegerVec idsVec;
        parseIntegerVec(strValue, idsVec);
        for(IntegerVec::iterator it = idsVec.begin(); it != idsVec.end(); ++it)
        {
            lootBlock.ids.push_back(*it);
            if(Item::items[(*it)].isContainer())
                loadChildLoot(node, lootBlock);
        }
    }
    else if(readXMLString(node, "name", strValue) || readXMLString(node, "names", strValue))
    {
        StringVec names = explodeString(strValue, ";");
        for(StringVec::iterator it = names.begin(); it != names.end(); ++it)
        {
            uint16_t tmp = Item::items.getItemIdByName(strValue);
            if(!tmp)
                continue;

            lootBlock.ids.push_back(tmp);
            if(Item::items[tmp].isContainer())
                loadChildLoot(node, lootBlock);
        }
    }

    if(lootBlock.ids.empty())
        return false;

    int32_t intValue;
    if(readXMLInteger(node, "count", intValue) || readXMLInteger(node, "countmax", intValue))
        lootBlock.count = std::max(1, std::min(100, intValue));
    else
        lootBlock.count = 1;

    if(readXMLInteger(node, "chance", intValue) || readXMLInteger(node, "chance1", intValue))
        lootBlock.chance = std::min(MAX_LOOTCHANCE, intValue);
    else
        lootBlock.chance = MAX_LOOTCHANCE;

    if(readXMLInteger(node, "subtype", intValue) || readXMLInteger(node, "subType", intValue))
        lootBlock.subType = intValue;

    if(readXMLInteger(node, "actionId", intValue) || readXMLInteger(node, "actionid", intValue)
        || readXMLInteger(node, "aid", intValue))
        lootBlock.actionId = intValue;

    if(readXMLInteger(node, "uniqueId", intValue) || readXMLInteger(node, "uniqueid", intValue)
        || readXMLInteger(node, "uid", intValue))
        lootBlock.uniqueId = intValue;

    if(readXMLString(node, "text", strValue))
        lootBlock.text = strValue;

    return true;
}

bool Monsters::loadChildLoot(xmlNodePtr node, LootBlock& parentBlock)
{
    if(!node)
        return false;

    xmlNodePtr p = node->children, insideNode;
    while(p)
    {
        if(!xmlStrcmp(p->name, (const xmlChar*)"inside"))
        {
            insideNode = p->children;
            while(insideNode)
            {
                LootBlock childBlock;
                if(loadLoot(insideNode, childBlock))
                    parentBlock.childLoot.push_back(childBlock);

                insideNode = insideNode->next;
            }

            p = p->next;
            continue;
        }

        LootBlock childBlock;
        if(loadLoot(p, childBlock))
            parentBlock.childLoot.push_back(childBlock);

        p = p->next;
    }

    return true;
}

MonsterType* Monsters::getMonsterType(const std::string& name)
{
    uint32_t mId = getIdByName(name);
    if(mId != 0)
        return getMonsterType(mId);

    return NULL;
}

MonsterType* Monsters::getMonsterType(uint32_t mid)
{
    MonsterMap::iterator it = monsters.find(mid);
    if(it != monsters.end())
        return it->second;

    return NULL;
}

uint32_t Monsters::getIdByName(const std::string& name)
{
    std::string tmp = name;
    MonsterNameMap::iterator it = monsterNames.find(asLowerCaseString(tmp));
    if(it != monsterNames.end())
        return it->second;

    return 0;
}

Monsters::~Monsters()
{
    loaded = false;
    for(MonsterMap::iterator it = monsters.begin(); it != monsters.end(); it++)
        delete it->second;
}
 

 

Editado por elielder
coloquei monster cpp (veja o histórico de edições)
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 Anderson Sacani
      Estou criando um servidor com base nos scripts de TFS 1.x e voltado ao público da america latina por causa do baixo ping na VPS... Argentina, Bolívia, Brasil, Chile, entre outros, portanto sei que falamos em português e nossos vizinhos em espanhol.
      Todos os sistemas do meu servidor são pensados para terem traduções e venho por meio deste tópico compartilhar à vocês algumas dessas funções:
       
      Antes de qualquer coisa, você precisará adicionar a seguinte variável em alguma biblioteca:
      USER_LANGUAGE = 1022118443  
      Agora que adicionou essa variável em alguma biblioteca, poderá adicionar as seguintes funções na mesma biblioteca, porém a baixo da variável USER_LANGUAGE.
       
      A primeira função serve para retornar qual idioma o player está usando:
      --[[ getLanguage, how to use: player:getLanguage() ]] function Player.getLanguage(self) if self:isPlayer() then if self:getStorageValue(USER_LANGUAGE) < 1 then return "portuguese" else return "spanish" end else print("getLanguage: Only works on players..") end end Um exemplo de como usar: player:getLanguage()
       
      A segunda função serve para alterar o idioma do player. O ideal é que seja usada na primeira vez em que o player loga no servidor:
      --[[ setLanguage, how to use: player:setLanguage("portuguese") ]] function Player.setLanguage(self, language) local value = 0 if self:isPlayer() then if language == "portuguese" then value = 0 elseif language == "spanish" then value = 1 else print("setLanguage: Only two options available. Choose one of them: 'portuguese' or 'spanish'.") end return self:setStorageValue(USER_LANGUAGE, value) else print("setLanguage: Only works on players..") end end Exemplos de como usar:
      player:setLanguage("portuguese")
      ou
      player:setLanguage("spanish")
       
      A terceira e não menos importante função, serve para mandar uma mensagem de texto ao jogador, porém ele receberá no idioma em que escolheu:
      --[[ sendLanguageTextMessage, how to use: local portugueseMessage = "Ola, tudo bom? Isto aqui é um algoritmo!" local spanishMessage = "Hola todo bien? Esto de aqui es un algoritmo!" player:sendLanguageTextMessage(MESSAGE_EVENT_ADVANCE, portugueseMessage,spanishMessage) ]] function Player.sendLanguageTextMessage(self, type, portugueseMessage, spanishMessage) if self:isPlayer() then if self:getStorageValue(USER_LANGUAGE) < 1 then return self:sendTextMessage(type, portugueseMessage) else return self:sendTextMessage(type, spanishMessage) end else print("sendLanguageTextMessage: Only works on players..") end end Um exemplo de como usar:
      player:sendLanguageTextMessage(MESSAGE_EVENT_ADVANCE, portugueseMessage, spanishMessage)
      O primeiro parâmetro é o tipo de mensagem, o segundo parâmetro será a mensagem em português e o terceiro parâmetro será em espanhol.
    • Por danielsort
      A minha poke ball nao esta funcionando como contador aonde consigo ageitar isso?
       
       

    • Por yurikil
      Saudações a todos, venho por meio deste tópico pedir uma ajuda no qual estou tentando fazer a muito tempo. Já vi alguns post aqui mesmo no TK, mas nenhum eu tive êxito. Por isso venho pedir um socorro de como eu consigo aumentar a quantidade de MagicEffects acima de 255 no meu NewClient OTC? Se alguém puder fortalecer ficarei muito grato!!
    • Por Vodkart
      Uma função que ao invés de usar o "cid" para pegar o valor de uma storage, usa o ip do jogador.
       
      baseado neste pedido:
       
       
       
       
      INSTALAÇÃO:
       
       
      Execute essa query:
       
      CREATE TABLE `ip_storages` (         `ip` int NOT NULL default 0,         `key` int NOT NULL default 0,         `value` varchar(255) NOT NULL default 0         )  
      funções para serem adicionadas na lib:
       
      function setIpStorageValue(ip, key, value) local func = db.executeQuery or db.query local query = db.getResult("SELECT `value` FROM `ip_storages` WHERE `key` = "..key.." AND `ip` = "..ip) if query:getID() == -1 then return func("INSERT INTO `ip_storages` (`ip`, `key`, `value`) VALUES ("..ip..", "..key..", "..value..")") end return func("UPDATE `ip_storages` SET `value` = "..value.." WHERE `key` = "..key.." AND `ip` = "..ip) end function getIpStorageValue(ip, key) local ret = db.getResult("SELECT `value` FROM `ip_storages` WHERE `ip` = "..ip.." AND `key` = "..key) if ret:getID() == -1 then return -1 end return ret:getDataInt("value") or ret:getDataString("value") end  
       
       
       
      exemplo de uso:
       
      pegar baú a cada X horas:
       
      function onUse(cid, item, fromPosition, itemEx, toPosition)     local storage, hours = 18000, 24     local ip = getPlayerIp(cid)     local item = 2160     if getIpStorageValue(ip, storage) - os.time() <= 0 then         doPlayerSendTextMessage(cid,22,"Tome seu prêmio.")         setIpStorageValue(ip, storage, os.time()+hours*3600)         doPlayerAddItem(cid, item, 100)          return true     end      return doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT,"Espere para pegar um novo item!") end  

      ou só podendo pegar 1x:
       
      function onUse(cid, item, fromPosition, itemEx, toPosition)     local storage, ip = 18000, getPlayerIp(cid)     local item = 2160     if getIpStorageValue(ip, storage) > 1 then     doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT,"voce ja pegou o item!") return true     end         doPlayerSendTextMessage(cid,22,"Tome seu prêmio.")         setIpStorageValue(ip, storage, 1)         doPlayerAddItem(cid, item, 100)          return true end
       
    • Por Endless
      Olá meus senhores, tem muita gente que pede serviços em relação a Gerar Outfits Animadas do seu cliente, o que muitos não sabem é que existe esse sistema de Gerar as Outfit animadas gratuitamente na internet e ele foi desenvolvido pelo Gesior.pl (Polones), então todo o crédito deste tutorial em relações a códigos vão para ele.

      Primeiro de tudo, o que é esse Sistema de Gerar Outfits Animadas?

      Basicamente é 1 Sistema Web que vai ler o teu tibia.spr / tibia.dat e seu items.otb e gerar todas suas outfit do seu cliente em forma de frames e na hora de exibir o sistema utiliza uma script em php que fica responsável por montar 1 gif utilizando esses frames.
      O resultado é algo como isto:



      Existe 2 formas de utilizar o sistema, eu vou ensinar a mais fácil, para quem quiser vou deixar o link do código fonte e vocês podem simplesmente estar clonando o repositório e fazer suas alterações a vontade. (Sim, ele é open source e.e).

      Código Fonte: https://github.com/gesior/open-tibia-library 

      Explicando como utilizar o sistema:

      1° acesse o link => https://outfit-images.ots.me/generator/

      Você deve visualizar algo como isto: 



      Percebam que ele vai pedir os seguintes dados: 
      -Client Version:
      -Sprite file:
      -Dat file:
      -Otb file:

      Antes de sair adicionando, precisamos configurar nosso cliente para que o sistema consiga reconhecer ele. Abra seu cliente no object builder. Agora vá na área de effects e apague todos os efeitos. Sim apague TODOS, agora vá até Tools->Spriter Otimizer



      Clique em start e você vai ter 1 retorno parecido com isto:



      Agora aperta CTRL+SHIFT+S, vamos salvar esse cliente em 1 pasta separada (você só vai usar ele pra esse sistema, então fique tranquilo, você não vai apagar o original). Na hora de salvar deixe desmarcado as 3 opções (Extended, Transparency, Improved Animations).



      Tendo feito isso, agora vamos voltar para o site. 
      Em Client Version você vai digitar a versão de seu cliente. Exemplo: Se for 8.60 digite 860
      Em sprite file você vai selecionar o tibia.spr do seu cliente que você exportou (esse sem efeitos)
      Em dat file você vai selecionar o tibia.dat do seu cliente que você exportou (esse sem efeitos)
      Em otb file você vai selecionar o items.otb do seu servidor.

      Agora clique em Load Files. Você deve ter 1 retorno parecido com isto:



      Agora clique em Generate Imagens e ele vai começar a gerar os frames das suas outfits.



      Ao terminar ele vai efetuar sozinho o download das outfits.




      Agora acesse este repositório no github e baixe os arquivos: https://github.com/gesior/open-tibia-library/tree/master/tools/colored-outfit-images-generator

      Tendo feito o download, você vai extrair a pasta outfits.zip que você baixo e extrair a pasta que você clonou o repositório. Ao extrair o arquivo outfits.zip você vai encontrar 1 pasta chamada outfits_anim, dentro dela você deve ter algo como isto:



      Cada pasta é referente a 1 looktype do seu cliente.
      Agora copie a pasta 'outfits_anim' que está dentro da pasta outfits que você extraiu e cole dentro da pasta do repositório que foi clonado. Ficando assim:



      Pronto, agora você somente precisa deixar essa pasta em 1 servidor web e utilizar a mesma via requisição. Exemplo:
      Se você for exibir uma outfit, você pode exibir da seguinte forma:
      <img src="http://seudominio.com/nomedapastaqueestaoosarquivos/animoutfit.php/?id=270">  
      Esse id será o looktype que você deseja. Lembrando que: Você pode colocar 1 script pra puxar a outfit de cada vocação e chamar esse diretório, ele vai exibir a imagem já com o diretório correto.
      Sugestão de uso: Para derivados de NTO/DBO e afins, você pode utilizar para exibir as outfits de transformações de cada Personagens, algo como isto:



       
      Outra opção é exibir na lista de Ranking no menu da direita (Normalmente Tibia Classico faz isso)
      A criatividade fica por conta de vocês.
       
      Créditos:
      Gesior.pl por todo o código e disponibilizar para a comunidade em 1 Forum Gringo
      A mim por disponibilizar o tutorial para a comunidade.

×
×
  • Criar Novo...

Informação Importante

Confirmação de Termo