Ir para conteúdo
  • Cadastre-se

Adicionando Surprise Bags no Drop de Monstros


Posts Recomendados

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

 

Editado por Tryller
Formatação (veja o histórico de edições)
Link para o post
Compartilhar em outros sites
  • Sub-Admin

Adorei!!! Fiz um em creaturescripts por on kill, tabalha da mesma forma, mais esse é sensacional tbm obg :) 

 

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
1 hora atrás, L3K0T disse:

Adorei!!! Fiz um em creaturescripts por on kill, tabalha da mesma forma, mais esse é sensacional tbm obg :) 

Valeu! Andei trabalhando em um servidor 8.60 com algumas coisas e me lembrei que no OT do Zorzin 7.9 tinha algo parecido. Resolvi criar um onde o jogador consiga editar os itens através de um XML

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.

×
×
  • Criar Novo...

Informação Importante

Confirmação de Termo