Postado Novembro 7, 2024 Nov 7 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 Novembro 7, 2024 Nov 7 por Tryller Formatação (veja o histórico de edições)
Postado Novembro 7, 2024 Nov 7 Diretor Adorei!!! Fiz um em creaturescripts por on kill, tabalha da mesma forma, mais esse é sensacional tbm obg
Postado Novembro 7, 2024 Nov 7 Autor 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
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.