Ir para conteúdo
  • Cadastre-se

Histórico de Edições

Please note that revisions older than 15 days are pruned and will no longer show here
Tryller

Tryller


Formatação

Tutorial: Adicionando Surprise Bags no Drop de Monstros

Código foi criado para uma versão 8.60 do Crystal Server. provavelmente funciona em TFS 0.4/0.3
Passo 1: Atualize o configmanager.cpp

No arquivo configmanager.cpp, adicione o seguinte código para permitir que a configuração de SURPRISE_BAGS seja ativada/desativada no config.lua:

	m_confBool[SURPRISE_BAGS] = getGlobalBool("dropSurpriseBagsFromMonsters", false);

 

Passo 2: Atualize o configmanager.h

No arquivo configmanager.h, defina a variável SURPRISE_BAGS na parte dos booleans:

			SURPRISE_BAGS,

 

Passo 3: Modifique o items.cpp

No arquivo items.cpp, na função bool Items::reload(), adicione a chamada para a nova função loadSurpriseBags() para carregar as configurações das Surprise Bags.

Coloque essa linha de código logo acima da função void Items::parseRandomizationBlock(...):

	if(!loadSurpriseBags())
		return false;

 

Passo 4: Crie a Função loadSurpriseBags

Ainda em items.cpp, adicione a implementação da função bool Items::loadSurpriseBags() para carregar as informações das bags a partir do XML:

bool Items::loadSurpriseBags()
{
	xmlDocPtr doc = xmlParseFile(getFilePath(FILE_TYPE_OTHER, "items/bags.xml").c_str());
	if(!doc)
	{
		std::clog << "[Warning - Items::loadBags] Cannot load bags file."
			<< std::endl << getLastXMLError() << std::endl;
		return false;
	}

	xmlNodePtr root = xmlDocGetRootElement(doc);
	if(xmlStrcmp(root->name,(const xmlChar*)"bags"))
	{
		xmlFreeDoc(doc);
		std::clog << "[Warning - Items::loadBags] Malformed bags file." << std::endl;
		return false;
	}

	std::string strValue;
	int32_t intValue;
	for(xmlNodePtr node = root->children; node; node = node->next)
	{
		if(xmlStrcmp(node->name, (const xmlChar*)"bag"))
			continue;

		uint16_t itemId = 0;
		std::string itemName;
		uint32_t chance = 0, minAmount = 1, maxAmount = 1;
		uint64_t minRange = 0, maxRange = 0;

		if(readXMLString(node, "name", strValue))
			itemName = strValue;

		if(readXMLInteger(node, "itemid", intValue))
			itemId = intValue;

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

		if(readXMLInteger(node, "minAmount", intValue))
			minAmount = intValue;

		if(readXMLInteger(node, "maxAmount", intValue))
			maxAmount = intValue;

		if(readXMLInteger(node, "minRange", intValue))
			minRange = intValue;

		if(readXMLInteger(node, "maxRange", intValue))
			maxRange = intValue;

		setItemBag(itemId, itemName, chance, minAmount, maxAmount, minRange, maxRange);
	}

	xmlFreeDoc(doc);
	return true;
}

 

Passo 5: Atualize o items.h

Em items.h, defina a estrutura BagItemInfo para armazenar as informações dos itens de bag:

		struct BagItemInfo
		{
			std::string name;
			uint16_t id;
			uint32_t chance;
			uint32_t minAmount;
			uint32_t maxAmount;
			uint64_t minRange;
			uint64_t maxRange;
		};

 

Adicione a função loadSurpriseBags() e métodos adicionais para gerenciar as Surprise Bags:

		bool loadSurpriseBags();

		std::vector<const BagItemInfo*> getAllBagItems() const
		{
			std::vector<const BagItemInfo*> allBagItems;
			for(std::map<int32_t, BagItemInfo>::const_iterator it = bagItems.begin(); it != bagItems.end(); ++it)
				allBagItems.push_back(&(it->second));

			return allBagItems;
		}

		void setItemBag(uint16_t itemId, const std::string &itemName, uint32_t chance, uint32_t minAmount, uint32_t maxAmount, uint64_t minRange, uint64_t maxRange)
		{
			BagItemInfo itemInfo;
			itemInfo.name = itemName;
			itemInfo.id = itemId;
			itemInfo.chance = chance;
			itemInfo.minAmount = minAmount;
			itemInfo.maxAmount = maxAmount;
			itemInfo.minRange = minRange;
			itemInfo.maxRange = maxRange;
			bagItems[itemId] = itemInfo;
		}

 

Adicione o mapa bagItems na classe Items abaixo de RandomizationMap randomizationMap;:

		std::map<int32_t, BagItemInfo> bagItems;

 

Passo 6: Modifique o otserv.cpp

Em otserv.cpp, adicione o carregamento das bags no início da execução, logo acima de std::clog << "Loading groups" << std::endl;:

	if(g_config.getBool(ConfigManager::SURPRISE_BAGS))
	{
		std::clog << "Loading surprise bags" << std::endl;
		if(!Item::items.loadSurpriseBags())
		{
			std::clog << "Unable to load surprise bags! Continue? (y/N)" << std::endl;
			char buffer = OTSYS_getch();
			if(buffer != 121 && buffer != 89)
				startupErrorMessage("Unable to load surprise bags!");
		}
	}

 

Passo 7: Atualize monsters.cpp

No arquivo monsters.cpp, na função void MonsterType::dropLoot(Container* corpse), adicione o código para verificar e adicionar as Surprise Bags ao loot. Coloque-o logo após o código abaixo
 

					Item* tmpItem = *iit;
					if(Container* container = tmpItem->getContainer())
					{
						if(createChildLoot(container, *it))
							corpse->__internalAddThing(tmpItem);
						else
							delete container;
					}
					else
						corpse->__internalAddThing(tmpItem);

 


Adicione

				if(g_config.getBool(ConfigManager::SURPRISE_BAGS))
				{
					const std::vector<const Items::BagItemInfo*> allBagItems = Item::items.getAllBagItems();
					std::vector<const Items::BagItemInfo*> validBagItems;
					for(std::vector<const Items::BagItemInfo*>::const_iterator it = allBagItems.begin(); it != allBagItems.end(); ++it)
					{
						const Items::BagItemInfo* bagItem = *it;
						if(bagItem->chance > 0)
							validBagItems.push_back(bagItem);
					}
		        
					if(!validBagItems.empty())
					{
						for(std::vector<const Items::BagItemInfo*>::const_iterator it = validBagItems.begin(); it != validBagItems.end(); ++it)
						{
							const Items::BagItemInfo* bagItem = *it;
							uint64_t minChance = bagItem->minRange;
							uint64_t maxChance = bagItem->maxRange;
		        
							if(random_range(minChance, maxChance) <= bagItem->chance)
							{
								uint16_t chosenBagId = bagItem->id;
								uint32_t minAmount = bagItem->minAmount;
								uint32_t maxAmount = bagItem->maxAmount;
								uint16_t dropAmount = static_cast<uint16_t>(random_range(minAmount, maxAmount, DISTRO_UNIFORM));
		        
								if(chosenBagId != 0)
								{
									Item* newItem = NULL;
									if(dropAmount > 1)
									{
										newItem = Item::CreateItem(chosenBagId, dropAmount);
										if(newItem)
										{
											if(g_game.internalAddItem(NULL, corpse, newItem) != RET_NOERROR)
												corpse->__internalAddThing(newItem);
										}
									}
									else
									{
										newItem = Item::CreateItem(chosenBagId, 1);
										if(newItem)
										{
											if(g_game.internalAddItem(NULL, corpse, newItem) != RET_NOERROR)
												corpse->__internalAddThing(newItem);
										}
									}
								}
							}
						}
					}
				}

Passo 8: Atualize o config.lua

Por fim, no arquivo config.lua, adicione a configuração que permite ativar ou desativar o drop das Surprise Bags:
 

	-- Surprise Bags
	-- NOTE: Set dropSurpriseBagsFromMonsters to false to disable surprise bag drops from monsters..
	dropSurpriseBagsFromMonsters = false


Para finalizar
va na pasta data/items e crie um arquivo bags.xml e cole isso dentro

 

<?xml version="1.0" encoding="UTF-8"?>
<bags>
    <!-- If chance and maxRange have the same value, the item will always drop. -->
    <bag name="Blue Surprise Bag" itemid="6570" chance="100" maxRange="10000"/>
    <bag name="Red Surprise Bag"  itemid="6571" chance="100" maxRange="1000"/>
</bags>

 
 

Explicação do Funcionamento

O sistema lê as informações de cada itens do arquivo XML bags.xml, que segue a seguinte estrutura acima:

Cada <bag> representa uma bag/item que pode ser dropada de monstros com as seguintes propriedades:

  • name: Nome descritivo da bag/item (opcional para identificação).
  • itemid: ID do item representando a bag/item no jogo.
  • chance: Chance de dropar a sacola. Valores mais altos aumentam a chance.
  • maxRange: Define o intervalo máximo de chance. Se chance for igual a maxRange, a sacola sempre será derrubada.
  • Quando menor o a distancia da chance para o range, mais fácil o item dropa.
     


Créditos:
Zorzin pela ideia do código na versão 7.9
Tryller: Criação do código do tópico

 

Tryller

Tryller


Formatação

Tutorial: Adicionando Surprise Bags no Drop de Monstros

Código foi criado para uma versão 8.60 do Crystal Server. provavelmente funciona em TFS 0.4/0.3
Passo 1: Atualize o configmanager.cpp

No arquivo configmanager.cpp, adicione o seguinte código para permitir que a configuração de SURPRISE_BAGS seja ativada/desativada no config.lua:

m_confBool[SURPRISE_BAGS] = getGlobalBool("dropSurpriseBagsFromMonsters", false);

 

Passo 2: Atualize o configmanager.h

No arquivo configmanager.h, defina a variável SURPRISE_BAGS:

SURPRISE_BAGS,

 

Passo 3: Modifique o items.cpp

No arquivo items.cpp, na função bool Items::reload(), adicione a chamada para a nova função loadSurpriseBags() para carregar as configurações das Surprise Bags.

Coloque essa linha de código logo acima da função void Items::parseRandomizationBlock(...):

if(!loadSurpriseBags())
return false;

 

Passo 4: Crie a Função loadSurpriseBags

Ainda em items.cpp, adicione a implementação da função bool Items::loadSurpriseBags() para carregar as informações das bags a partir do XML:

bool Items::loadSurpriseBags() {
    xmlDocPtr doc = xmlParseFile(getFilePath(FILE_TYPE_OTHER, "items/bags.xml").c_str());
    if(!doc) {
        std::clog << "[Warning - Items::loadBags] Cannot load bags file." << std::endl << getLastXMLError() << std::endl;
        return false;
    }

    xmlNodePtr root = xmlDocGetRootElement(doc);
    if(xmlStrcmp(root->name, (const xmlChar*)"bags")) {
        xmlFreeDoc(doc);
        std::clog << "[Warning - Items::loadBags] Malformed bags file." << std::endl;
        return false;
    }

    std::string strValue;
    int32_t intValue;
    for(xmlNodePtr node = root->children; node; node = node->next) {
        if(xmlStrcmp(node->name, (const xmlChar*)"bag"))
            continue;

        uint16_t itemId = 0;
        std::string itemName;
        uint32_t chance = 0, minAmount = 1, maxAmount = 1;
        uint64_t minRange = 0, maxRange = 0;

        if(readXMLString(node, "name", strValue))
            itemName = strValue;

        if(readXMLInteger(node, "itemid", intValue))
            itemId = intValue;

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

        if(readXMLInteger(node, "minAmount", intValue))
            minAmount = intValue;

        if(readXMLInteger(node, "maxAmount", intValue))
            maxAmount = intValue;

        if(readXMLInteger(node, "minRange", intValue))
            minRange = intValue;

        if(readXMLInteger(node, "maxRange", intValue))
            maxRange = intValue;

        setItemBag(itemId, itemName, chance, minAmount, maxAmount, minRange, maxRange);
    }

    xmlFreeDoc(doc);
    return true;
}

 

Passo 5: Atualize o items.h

Em items.h, defina a estrutura BagItemInfo para armazenar as informações dos itens de bag:

struct BagItemInfo {
    std::string name;
    uint16_t id;
    uint32_t chance;
    uint32_t minAmount;
    uint32_t maxAmount;
    uint64_t minRange;
    uint64_t maxRange;
};

 

Adicione a função loadSurpriseBags() e métodos adicionais para gerenciar as Surprise Bags:

bool loadSurpriseBags();
std::vector<const BagItemInfo*> getAllBagItems() const {
    std::vector<const BagItemInfo*> allBagItems;
    for(auto it = bagItems.begin(); it != bagItems.end(); ++it)
        allBagItems.push_back(&(it->second));
    return allBagItems;
}

void setItemBag(uint16_t itemId, const std::string &itemName, uint32_t chance, uint32_t minAmount, uint32_t maxAmount, uint64_t minRange, uint64_t maxRange) {
    BagItemInfo itemInfo;
    itemInfo.name = itemName;
    itemInfo.id = itemId;
    itemInfo.chance = chance;
    itemInfo.minAmount = minAmount;
    itemInfo.maxAmount = maxAmount;
    itemInfo.minRange = minRange;
    itemInfo.maxRange = maxRange;
    bagItems[itemId] = itemInfo;
}

 

Adicione o mapa bagItems na classe Items abaixo de RandomizationMap randomizationMap;:

std::map<int32_t, BagItemInfo> bagItems;

 

Passo 6: Modifique o otserv.cpp

Em otserv.cpp, adicione o carregamento das bags no início da execução, logo acima de std::clog << "Loading groups" << std::endl;:

if(g_config.getBool(ConfigManager::SURPRISE_BAGS)) {
    std::clog << "Loading surprise bags" << std::endl;
    if(!Item::items.loadSurpriseBags()) {
        std::clog << "Unable to load surprise bags! Continue? (y/N)" << std::endl;
        char buffer = OTSYS_getch();
        if(buffer != 121 && buffer != 89)
            startupErrorMessage("Unable to load surprise bags!");
    }
}

 

Passo 7: Atualize monsters.cpp

No arquivo monsters.cpp, na função void MonsterType::dropLoot(Container* corpse), adicione o código para verificar e adicionar as Surprise Bags ao loot. Coloque-o logo após o código abaixo
 

					Item* tmpItem = *iit;
					if(Container* container = tmpItem->getContainer())
					{
						if(createChildLoot(container, *it))
							corpse->__internalAddThing(tmpItem);
						else
							delete container;
					}
					else
						corpse->__internalAddThing(tmpItem);

 


Adicione

if(g_config.getBool(ConfigManager::SURPRISE_BAGS)) {
    const std::vector<const Items::BagItemInfo*> allBagItems = Item::items.getAllBagItems();
    std::vector<const Items::BagItemInfo*> validBagItems;
    for(const auto& bagItem : allBagItems) {
        if(bagItem->chance > 0)
            validBagItems.push_back(bagItem);
    }

    if(!validBagItems.empty()) {
        for(const auto& bagItem : validBagItems) {
            uint64_t minChance = bagItem->minRange;
            uint64_t maxChance = bagItem->maxRange;

            if(random_range(minChance, maxChance) <= bagItem->chance) {
                uint16_t chosenBagId = bagItem->id;
                uint32_t minAmount = bagItem->minAmount;
                uint32_t maxAmount = bagItem->maxAmount;
                uint16_t dropAmount = static_cast<uint16_t>(random_range(minAmount, maxAmount, DISTRO_UNIFORM));

                if(chosenBagId != 0) {
                    Item* newItem = Item::CreateItem(chosenBagId, dropAmount);
                    if(newItem) {
                        if(g_game.internalAddItem(NULL, corpse, newItem, false) != RET_NOERROR)
                            corpse->__internalAddThing(newItem);
                    }
                }
            }
        }
    }
}

Passo 8: Atualize o config.lua

Por fim, no arquivo config.lua, adicione a configuração que permite ativar ou desativar o drop das Surprise Bags:
 

-- Surprise Bags
-- NOTE: Set dropSurpriseBagsFromMonsters to false to disable surprise bag drops from monsters.
dropSurpriseBagsFromMonsters = false


Para finalizar
va na pasta data/items e crie um arquivo bags.xml e cole isso dentro

 

<?xml version="1.0" encoding="UTF-8"?>
<bags>
    <!-- If chance and maxRange have the same value, the item will always drop. -->
    <bag name="Blue Surprise Bag" itemid="6570" chance="100" maxRange="10000"/>
    <bag name="Red Surprise Bag"  itemid="6571" chance="100" maxRange="1000"/>
</bags>

 
 

Explicação do Funcionamento

O sistema lê as informações de cada itens do arquivo XML bags.xml, que segue a seguinte estrutura acima:

Cada <bag> representa uma bag/item que pode ser dropada de monstros com as seguintes propriedades:

  • name: Nome descritivo da bag/item (opcional para identificação).
  • itemid: ID do item representando a bag/item no jogo.
  • chance: Chance de dropar a sacola. Valores mais altos aumentam a chance.
  • maxRange: Define o intervalo máximo de chance. Se chance for igual a maxRange, a sacola sempre será derrubada.
  • Quando menor o a distancia da chance para o range, mais fácil o item dropa.
     


Créditos:
Zorzin pela ideia do código na versão 7.9
Tryller: Criação do código do tópico

 

Tryller

Tryller


Formatação

Tutorial: Adicionando Surprise Bags no Drop de Monstros

Código foi criado para uma versão 8.60 do Crystal Server. provavelmente funciona em TFS 0.4/0.3
Passo 1: Atualize o configmanager.cpp

No arquivo configmanager.cpp, adicione o seguinte código para permitir que a configuração de SURPRISE_BAGS seja ativada/desativada no config.lua:

m_confBool[SURPRISE_BAGS] = getGlobalBool("dropSurpriseBagsFromMonsters", false);

 

Passo 2: Atualize o configmanager.h

No arquivo configmanager.h, defina a variável SURPRISE_BAGS:

SURPRISE_BAGS,

 

Passo 3: Modifique o items.cpp

No arquivo items.cpp, na função bool Items::reload(), adicione a chamada para a nova função loadSurpriseBags() para carregar as configurações das Surprise Bags.

Coloque essa linha de código logo acima da função void Items::parseRandomizationBlock(...):

if(!loadSurpriseBags())
return false;

 

Passo 4: Crie a Função loadSurpriseBags

Ainda em items.cpp, adicione a implementação da função bool Items::loadSurpriseBags() para carregar as informações das bags a partir do XML:

bool Items::loadSurpriseBags() {
    xmlDocPtr doc = xmlParseFile(getFilePath(FILE_TYPE_OTHER, "items/bags.xml").c_str());
    if(!doc) {
        std::clog << "[Warning - Items::loadBags] Cannot load bags file." << std::endl << getLastXMLError() << std::endl;
        return false;
    }

    xmlNodePtr root = xmlDocGetRootElement(doc);
    if(xmlStrcmp(root->name, (const xmlChar*)"bags")) {
        xmlFreeDoc(doc);
        std::clog << "[Warning - Items::loadBags] Malformed bags file." << std::endl;
        return false;
    }

    std::string strValue;
    int32_t intValue;
    for(xmlNodePtr node = root->children; node; node = node->next) {
        if(xmlStrcmp(node->name, (const xmlChar*)"bag"))
            continue;

        uint16_t itemId = 0;
        std::string itemName;
        uint32_t chance = 0, minAmount = 1, maxAmount = 1;
        uint64_t minRange = 0, maxRange = 0;

        if(readXMLString(node, "name", strValue))
            itemName = strValue;

        if(readXMLInteger(node, "itemid", intValue))
            itemId = intValue;

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

        if(readXMLInteger(node, "minAmount", intValue))
            minAmount = intValue;

        if(readXMLInteger(node, "maxAmount", intValue))
            maxAmount = intValue;

        if(readXMLInteger(node, "minRange", intValue))
            minRange = intValue;

        if(readXMLInteger(node, "maxRange", intValue))
            maxRange = intValue;

        setItemBag(itemId, itemName, chance, minAmount, maxAmount, minRange, maxRange);
    }

    xmlFreeDoc(doc);
    return true;
}

 

Passo 5: Atualize o items.h

Em items.h, defina a estrutura BagItemInfo para armazenar as informações dos itens de bag:

struct BagItemInfo {
    std::string name;
    uint16_t id;
    uint32_t chance;
    uint32_t minAmount;
    uint32_t maxAmount;
    uint64_t minRange;
    uint64_t maxRange;
};

 

Adicione a função loadSurpriseBags() e métodos adicionais para gerenciar as Surprise Bags:

bool loadSurpriseBags();
std::vector<const BagItemInfo*> getAllBagItems() const {
    std::vector<const BagItemInfo*> allBagItems;
    for(auto it = bagItems.begin(); it != bagItems.end(); ++it)
        allBagItems.push_back(&(it->second));
    return allBagItems;
}

void setItemBag(uint16_t itemId, const std::string &itemName, uint32_t chance, uint32_t minAmount, uint32_t maxAmount, uint64_t minRange, uint64_t maxRange) {
    BagItemInfo itemInfo;
    itemInfo.name = itemName;
    itemInfo.id = itemId;
    itemInfo.chance = chance;
    itemInfo.minAmount = minAmount;
    itemInfo.maxAmount = maxAmount;
    itemInfo.minRange = minRange;
    itemInfo.maxRange = maxRange;
    bagItems[itemId] = itemInfo;
}

 

Adicione o mapa bagItems na classe Items abaixo de RandomizationMap randomizationMap;:

std::map<int32_t, BagItemInfo> bagItems;

 

Passo 6: Modifique o otserv.cpp

Em otserv.cpp, adicione o carregamento das bags no início da execução, logo acima de std::clog << "Loading groups" << std::endl;:

if(g_config.getBool(ConfigManager::SURPRISE_BAGS)) {
    std::clog << "Loading surprise bags" << std::endl;
    if(!Item::items.loadSurpriseBags()) {
        std::clog << "Unable to load surprise bags! Continue? (y/N)" << std::endl;
        char buffer = OTSYS_getch();
        if(buffer != 121 && buffer != 89)
            startupErrorMessage("Unable to load surprise bags!");
    }
}

 

Passo 7: Atualize monsters.cpp

No arquivo monsters.cpp, na função void MonsterType::dropLoot(Container* corpse), adicione o código para verificar e adicionar as Surprise Bags ao loot. Coloque-o logo após o código abaixo
 

					Item* tmpItem = *iit;
					if(Container* container = tmpItem->getContainer())
					{
						if(createChildLoot(container, *it))
							corpse->__internalAddThing(tmpItem);
						else
							delete container;
					}
					else
						corpse->__internalAddThing(tmpItem);

 


Adicione

if(g_config.getBool(ConfigManager::SURPRISE_BAGS)) {
    const std::vector<const Items::BagItemInfo*> allBagItems = Item::items.getAllBagItems();
    std::vector<const Items::BagItemInfo*> validBagItems;
    for(const auto& bagItem : allBagItems) {
        if(bagItem->chance > 0)
            validBagItems.push_back(bagItem);
    }

    if(!validBagItems.empty()) {
        for(const auto& bagItem : validBagItems) {
            uint64_t minChance = bagItem->minRange;
            uint64_t maxChance = bagItem->maxRange;

            if(random_range(minChance, maxChance) <= bagItem->chance) {
                uint16_t chosenBagId = bagItem->id;
                uint32_t minAmount = bagItem->minAmount;
                uint32_t maxAmount = bagItem->maxAmount;
                uint16_t dropAmount = static_cast<uint16_t>(random_range(minAmount, maxAmount, DISTRO_UNIFORM));

                if(chosenBagId != 0) {
                    Item* newItem = Item::CreateItem(chosenBagId, dropAmount);
                    if(newItem) {
                        if(g_game.internalAddItem(NULL, corpse, newItem, false) != RET_NOERROR)
                            corpse->__internalAddThing(newItem);
                    }
                }
            }
        }
    }
}

Passo 8: Atualize o config.lua

Por fim, no arquivo config.lua, adicione a configuração que permite ativar ou desativar o drop das Surprise Bags:
 

-- Surprise Bags
-- NOTE: Set dropSurpriseBagsFromMonsters to false to disable surprise bag drops from monsters.
dropSurpriseBagsFromMonsters = false


Para finalizar
va na pasta data/items e crie um arquivo bags.xml e cole isso dentro

 

<?xml version="1.0" encoding="UTF-8"?>
<bags>
    <!-- If chance and maxRange have the same value, the item will always drop. -->
    <bag name="Blue Surprise Bag" itemid="6570" chance="100" maxRange="10000"/>
    <bag name="Red Surprise Bag"  itemid="6571" chance="100" maxRange="1000"/>
</bags>
 

Créditos:
Zorzin pela ideia do código na versão 7.9
Tryller: Criação do código dotópico

 

Tryller

Tryller

Passo 1: Atualize o configmanager.cpp

No arquivo configmanager.cpp, adicione o seguinte código para permitir que a configuração de SURPRISE_BAGS seja ativada/desativada no config.lua:


 
cpp
Copiar código
m_confBool[SURPRISE_BAGS] = getGlobalBool("dropSurpriseBagsFromMonsters", false);

Passo 2: Atualize o configmanager.h

No arquivo configmanager.h, defina a variável SURPRISE_BAGS:


 
cpp
Copiar código
SURPRISE_BAGS,

Passo 3: Modifique o items.cpp

No arquivo items.cpp, na função bool Items::reload(), adicione a chamada para a nova função loadSurpriseBags() para carregar as configurações das Surprise Bags.

Coloque essa linha de código logo acima da função void Items::parseRandomizationBlock(...):


 
cpp
Copiar código
if(!loadSurpriseBags()) return false;

Passo 4: Crie a Função loadSurpriseBags

Ainda em items.cpp, adicione a implementação da função bool Items::loadSurpriseBags() para carregar as informações das bags a partir do XML:


 
cpp
Copiar código
bool Items::loadSurpriseBags() { xmlDocPtr doc = xmlParseFile(getFilePath(FILE_TYPE_OTHER, "items/bags.xml").c_str()); if(!doc) { std::clog << "[Warning - Items::loadBags] Cannot load bags file." << std::endl << getLastXMLError() << std::endl; return false; } xmlNodePtr root = xmlDocGetRootElement(doc); if(xmlStrcmp(root->name, (const xmlChar*)"bags")) { xmlFreeDoc(doc); std::clog << "[Warning - Items::loadBags] Malformed bags file." << std::endl; return false; } std::string strValue; int32_t intValue; for(xmlNodePtr node = root->children; node; node = node->next) { if(xmlStrcmp(node->name, (const xmlChar*)"bag")) continue; uint16_t itemId = 0; std::string itemName; uint32_t chance = 0, minAmount = 1, maxAmount = 1; uint64_t minRange = 0, maxRange = 0; if(readXMLString(node, "name", strValue)) itemName = strValue; if(readXMLInteger(node, "itemid", intValue)) itemId = intValue; if(readXMLInteger(node, "chance", intValue)) chance = intValue; if(readXMLInteger(node, "minAmount", intValue)) minAmount = intValue; if(readXMLInteger(node, "maxAmount", intValue)) maxAmount = intValue; if(readXMLInteger(node, "minRange", intValue)) minRange = intValue; if(readXMLInteger(node, "maxRange", intValue)) maxRange = intValue; setItemBag(itemId, itemName, chance, minAmount, maxAmount, minRange, maxRange); } xmlFreeDoc(doc); return true; }

Passo 5: Atualize o items.h

Em items.h, defina a estrutura BagItemInfo para armazenar as informações dos itens de bag:


 
cpp
Copiar código
struct BagItemInfo { std::string name; uint16_t id; uint32_t chance; uint32_t minAmount; uint32_t maxAmount; uint64_t minRange; uint64_t maxRange; };

Adicione a função loadSurpriseBags() e métodos adicionais para gerenciar as Surprise Bags:


 
cpp
Copiar código
bool loadSurpriseBags(); std::vector<const BagItemInfo*> getAllBagItems() const { std::vector<const BagItemInfo*> allBagItems; for(auto it = bagItems.begin(); it != bagItems.end(); ++it) allBagItems.push_back(&(it->second)); return allBagItems; } void setItemBag(uint16_t itemId, const std::string &itemName, uint32_t chance, uint32_t minAmount, uint32_t maxAmount, uint64_t minRange, uint64_t maxRange) { BagItemInfo itemInfo; itemInfo.name = itemName; itemInfo.id = itemId; itemInfo.chance = chance; itemInfo.minAmount = minAmount; itemInfo.maxAmount = maxAmount; itemInfo.minRange = minRange; itemInfo.maxRange = maxRange; bagItems[itemId] = itemInfo; }

Adicione o mapa bagItems na classe Items:


 
cpp
Copiar código
std::map<int32_t, BagItemInfo> bagItems;

Passo 6: Modifique o otserv.cpp

Em otserv.cpp, adicione o carregamento das bags no início da execução, logo acima de std::clog << "Loading groups" << std::endl;:


 
cpp
Copiar código
if(g_config.getBool(ConfigManager::SURPRISE_BAGS)) { std::clog << "Loading surprise bags" << std::endl; if(!Item::items.loadSurpriseBags()) { std::clog << "Unable to load surprise bags! Continue? (y/N)" << std::endl; char buffer = OTSYS_getch(); if(buffer != 121 && buffer != 89) startupErrorMessage("Unable to load surprise bags!"); } }

Passo 7: Atualize monsters.cpp

No arquivo monsters.cpp, na função void MonsterType::dropLoot(Container* corpse), adicione o código para verificar e adicionar as Surprise Bags ao loot. Coloque-o logo após o código para Container* tmpItem:


 
cpp
Copiar código
if(g_config.getBool(ConfigManager::SURPRISE_BAGS)) { const std::vector<const Items::BagItemInfo*> allBagItems = Item::items.getAllBagItems(); std::vector<const Items::BagItemInfo*> validBagItems; for(const auto& bagItem : allBagItems) { if(bagItem->chance > 0) validBagItems.push_back(bagItem); } if(!validBagItems.empty()) { for(const auto& bagItem : validBagItems) { uint64_t minChance = bagItem->minRange; uint64_t maxChance = bagItem->maxRange; if(random_range(minChance, maxChance) <= bagItem->chance) { uint16_t chosenBagId = bagItem->id; uint32_t minAmount = bagItem->minAmount; uint32_t maxAmount = bagItem->maxAmount; uint16_t dropAmount = static_cast<uint16_t>(random_range(minAmount, maxAmount, DISTRO_UNIFORM)); if(chosenBagId != 0) { Item* newItem = Item::CreateItem(chosenBagId, dropAmount); if(newItem) { if(g_game.internalAddItem(NULL, corpse, newItem, false) != RET_NOERROR) corpse->__internalAddThing(newItem); } } } } } }

Passo 8: Atualize o config.lua

Por fim, no arquivo config.lua, adicione a configuração que permite ativar ou desativar o drop das Surprise Bags:


 
lua
Copiar código
-- Surprise Bags -- NOTE: Set dropSurpriseBagsFromMonsters to false to disable surprise bag drops from monsters. dropSurpriseBagsFromMonsters = false
  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.

×
×
  • Criar Novo...

Informação Importante

Confirmação de Termo