drop format revision

This commit is contained in:
FinnHornhoover 2021-03-28 23:22:23 -07:00 committed by Gent Semaj
parent 30de9f668c
commit 1779d69078
3 changed files with 74 additions and 59 deletions

View File

@ -18,7 +18,7 @@ std::map<std::pair<int32_t, int32_t>, Items::Item> Items::ItemData;
std::map<int32_t, CrocPotEntry> Items::CrocPotTable;
std::map<int32_t, std::vector<int32_t>> Items::RarityWeights;
std::map<int32_t, Crate> Items::Crates;
std::map<int32_t, DroppableItem> Items::DroppableItems;
std::map<int32_t, ItemReference> Items::ItemReferences;
std::map<std::string, std::vector<std::pair<int32_t, int32_t>>> Items::CodeItems;
std::map<int32_t, CrateDropChance> Items::CrateDropChances;
@ -118,11 +118,11 @@ static int getRarity(int crateId, int itemSetTypeId) {
// remember that rarities start from 1!
std::set<int> rarityIndices;
for (int droppableItemId : Items::ItemSetTypes[itemSetTypeId].droppableItemIds) {
if (Items::DroppableItems.find(droppableItemId) == Items::DroppableItems.end())
for (int itemReferenceId : Items::ItemSetTypes[itemSetTypeId].itemReferenceIds) {
if (Items::ItemReferences.find(itemReferenceId) == Items::ItemReferences.end())
continue;
rarityIndices.insert(Items::DroppableItems[droppableItemId].rarity - 1);
rarityIndices.insert(Items::ItemReferences[itemReferenceId].rarity - 1);
// shortcut
if (rarityIndices.size() == rarityWeights.size())
@ -144,37 +144,29 @@ static int getRarity(int crateId, int itemSetTypeId) {
static int getCrateItem(sItemBase* result, int itemSetTypeId, int itemSetChanceId, int rarity, int playerGender) {
// (int, vector<int>)
auto& [ignoreGender, droppableItemIds] = Items::ItemSetTypes[itemSetTypeId];
auto& [ignoreGender, itemReferenceIds] = Items::ItemSetTypes[itemSetTypeId];
// collect valid items that match the rarity and (if not ignored) gender
std::vector<std::pair<int, DroppableItem*>> validItems;
for (int i = 0; i < droppableItemIds.size(); i++) {
int droppableItemId = droppableItemIds[i];
std::vector<std::pair<int, ItemReference*>> validItems;
for (int i = 0; i < itemReferenceIds.size(); i++) {
int itemReferenceId = itemReferenceIds[i];
if (Items::DroppableItems.find(droppableItemId) == Items::DroppableItems.end()) {
std::cout << "[WARN] Droppable item " << droppableItemId << " was not found, skipping..." << std::endl;
if (Items::ItemReferences.find(itemReferenceId) == Items::ItemReferences.end()) {
std::cout << "[WARN] Item reference " << itemReferenceId << " in item set type "
<< itemSetTypeId << " was not found, skipping..." << std::endl;
continue;
}
DroppableItem* droppableItem = &Items::DroppableItems[droppableItemId];
ItemReference* item = &Items::ItemReferences[itemReferenceId];
if (droppableItem->rarity != rarity)
if (item->rarity != rarity)
continue;
auto key = std::make_pair(droppableItem->itemId, droppableItem->type);
if (Items::ItemData.find(key) == Items::ItemData.end()) {
std::cout << "[WARN] Item-Type pair (" << key.first << ", " << key.second << ") specified by droppable item "
<< droppableItemId << " was not found, skipping..." << std::endl;
continue;
}
// if gender is incorrect, exclude item
int itemGender = Items::ItemData[key].gender;
if (!ignoreGender && itemGender != 0 && itemGender != playerGender)
if (!ignoreGender && item->gender != 0 && item->gender != playerGender)
continue;
validItems.push_back(std::make_pair(i, droppableItem));
validItems.push_back(std::make_pair(i, item));
}
if (validItems.empty()) {
@ -184,20 +176,19 @@ static int getCrateItem(sItemBase* result, int itemSetTypeId, int itemSetChanceI
}
// (int, map<int, int>)
auto& [defaultWeight, specialWeights] = Items::ItemSetChances[itemSetChanceId];
auto& [defaultWeight, indexWeightMap] = Items::ItemSetChances[itemSetChanceId];
// initialize all weights as the default weight for all item slots
std::vector<int> itemWeights(validItems.size(), defaultWeight);
if (!specialWeights.empty()) {
if (!indexWeightMap.empty()) {
for (int i = 0; i < validItems.size(); i++) {
// (int, DroppableItem*)
auto& [dropIndex, droppableItem] = validItems[i];
int dropIndex = validItems[i].first;
if (specialWeights.find(dropIndex) == specialWeights.end())
if (indexWeightMap.find(dropIndex) == indexWeightMap.end())
continue;
int weight = specialWeights[dropIndex];
int weight = indexWeightMap[dropIndex];
// allow 0 weights for convenience
if (weight > -1)
itemWeights[i] = weight;
@ -205,7 +196,7 @@ static int getCrateItem(sItemBase* result, int itemSetTypeId, int itemSetChanceI
}
int chosenIndex = Rand::randWeighted(itemWeights);
DroppableItem* item = validItems[chosenIndex].second;
ItemReference* item = validItems[chosenIndex].second;
result->iID = item->itemId;
result->iType = item->type;
@ -866,7 +857,7 @@ void Items::giveMobDrop(CNSocket *sock, Mob* mob, int rolledBoosts, int rolledPo
sock->sendPacket((void*)respbuf, P_FE2CL_REP_REWARD_ITEM, sizeof(sP_FE2CL_REP_REWARD_ITEM));
} else {
// item reward
getMobDrop(&item->sItem, crateDropChance.crateWeights, crateDropType, rolledCrateType);
getMobDrop(&item->sItem, crateDropChance.crateTypeDropWeights, crateDropType, rolledCrateType);
item->iSlotNum = slot;
item->eIL = 1; // Inventory Location. 1 means player inventory.

View File

@ -17,7 +17,7 @@ struct Crate {
struct CrateDropChance {
int dropChance, dropChanceTotal;
std::vector<int> crateWeights;
std::vector<int> crateTypeDropWeights;
};
struct MiscDropChance {
@ -43,18 +43,19 @@ struct MobDrop {
struct ItemSetType {
bool ignoreGender;
std::vector<int> droppableItemIds;
std::vector<int> itemReferenceIds;
};
struct ItemSetChance {
int defaultItemWeight;
std::map<int, int> specialItemWeights;
std::map<int, int> indexWeightMap;
};
struct DroppableItem {
struct ItemReference {
int itemId;
int rarity;
int type;
int rarity;
int gender;
};
namespace Items {
@ -76,7 +77,7 @@ namespace Items {
extern std::map<int32_t, CrocPotEntry> CrocPotTable; // level gap -> entry
extern std::map<int32_t, std::vector<int32_t>> RarityWeights;
extern std::map<int32_t, Crate> Crates;
extern std::map<int32_t, DroppableItem> DroppableItems;
extern std::map<int32_t, ItemReference> ItemReferences;
extern std::map<std::string, std::vector<std::pair<int32_t, int32_t>>> CodeItems; // code -> vector of <id, type>
// mob drops

View File

@ -213,7 +213,7 @@ static void loadDrops() {
nlohmann::json crateWeights = crateDropChance["CrateTypeDropWeights"];
for (nlohmann::json::iterator _crateWeight = crateWeights.begin(); _crateWeight != crateWeights.end(); _crateWeight++)
toAdd.crateWeights.push_back((int)_crateWeight.value());
toAdd.crateTypeDropWeights.push_back((int)_crateWeight.value());
Items::CrateDropChances[(int)crateDropChance["CrateDropChanceID"]] = toAdd;
}
@ -295,9 +295,9 @@ static void loadDrops() {
toAdd.ignoreGender = (bool)itemSetType["IgnoreGender"];
nlohmann::json droppableItemIds = itemSetType["DroppableItemIDs"];
for (nlohmann::json::iterator _droppableItemId = droppableItemIds.begin(); _droppableItemId != droppableItemIds.end(); _droppableItemId++)
toAdd.droppableItemIds.push_back((int)_droppableItemId.value());
nlohmann::json itemReferenceIds = itemSetType["ItemReferenceIDs"];
for (nlohmann::json::iterator itemReferenceId = itemReferenceIds.begin(); itemReferenceId != itemReferenceIds.end(); itemReferenceId++)
toAdd.itemReferenceIds.push_back((int)itemReferenceId.value());
Items::ItemSetTypes[(int)itemSetType["ItemSetTypeID"]] = toAdd;
}
@ -310,12 +310,9 @@ static void loadDrops() {
toAdd.defaultItemWeight = (int)itemSetChanceObject["DefaultItemWeight"];
nlohmann::json specialItemWeightIndices = itemSetChanceObject["SpecialItemWeightIndices"];
nlohmann::json specialItemWeightVector = itemSetChanceObject["SpecialItemWeights"];
for (nlohmann::json::iterator _specialItemWeightIndex = specialItemWeightIndices.begin(), _specialItemWeight = specialItemWeightVector.begin();
_specialItemWeightIndex != specialItemWeightIndices.end() && _specialItemWeight != specialItemWeightVector.end();
_specialItemWeightIndex++, _specialItemWeight++)
toAdd.specialItemWeights[(int)_specialItemWeightIndex.value()] = (int)_specialItemWeight.value();
nlohmann::json indexWeightMap = itemSetChanceObject["IndexWeightMap"];
for (nlohmann::json::iterator _indexWeightMapEntry = indexWeightMap.begin(); _indexWeightMapEntry != indexWeightMap.end(); _indexWeightMapEntry++)
toAdd.indexWeightMap[std::atoi(_indexWeightMapEntry.key().c_str())] = (int)_indexWeightMapEntry.value();
Items::ItemSetChances[(int)itemSetChanceObject["ItemSetChanceID"]] = toAdd;
}
@ -332,15 +329,29 @@ static void loadDrops() {
};
}
// DroppableItems
nlohmann::json droppableItems = dropData["DroppableItems"];
for (nlohmann::json::iterator _droppableItem = droppableItems.begin(); _droppableItem != droppableItems.end(); _droppableItem++) {
auto droppableItem = _droppableItem.value();
// ItemReferences
nlohmann::json itemReferences = dropData["ItemReferences"];
for (nlohmann::json::iterator _itemReference = itemReferences.begin(); _itemReference != itemReferences.end(); _itemReference++) {
auto itemReference = _itemReference.value();
Items::DroppableItems[(int)droppableItem["DroppableItemID"]] = {
(int)droppableItem["ItemID"],
(int)droppableItem["Rarity"],
(int)droppableItem["Type"]
int itemReferenceId = (int)itemReference["ItemReferenceID"];
int itemId = (int)itemReference["ItemID"];
int type = (int)itemReference["Type"];
// validate and fetch relevant fields as they're loaded
auto key = std::make_pair(itemId, type);
if (Items::ItemData.find(key) == Items::ItemData.end()) {
std::cout << "[WARN] Item-Type pair (" << key.first << ", " << key.second << ") specified by item reference "
<< itemReferenceId << " was not found, skipping..." << std::endl;
continue;
}
Items::Item& item = Items::ItemData[key];
Items::ItemReferences[itemReferenceId] = {
itemId,
type,
item.rarity,
item.gender
};
}
@ -405,15 +416,27 @@ static void loadDrops() {
std::string codeStr = code["Code"];
std::vector<std::pair<int32_t, int32_t>> itemVector;
nlohmann::json items = code["Items"];
for (nlohmann::json::iterator _item = items.begin(); _item != items.end(); _item++)
itemVector.push_back(std::make_pair((int)code["ItemID"], (int)code["Type"]));
nlohmann::json itemReferenceIds = code["ItemReferenceIDs"];
for (nlohmann::json::iterator _itemReferenceId = itemReferenceIds.begin(); _itemReferenceId != itemReferenceIds.end(); _itemReferenceId++) {
int itemReferenceId = (int)_itemReferenceId.value();
// validate and convert here
if (Items::ItemReferences.find(itemReferenceId) == Items::ItemReferences.end()) {
std::cout << "[WARN] Item reference " << itemReferenceId << " for code "
<< codeStr << " was not found, skipping..." << std::endl;
continue;
}
// no need to further check whether this is a real item or not, we already did this!
ItemReference& itemReference = Items::ItemReferences[itemReferenceId];
itemVector.push_back(std::make_pair(itemReference.itemId, itemReference.type));
}
Items::CodeItems[codeStr] = itemVector;
}
std::cout << "[INFO] Loaded " << Items::Crates.size() << " Crates containing "
<< Items::DroppableItems.size() << " unique items" << std::endl;
<< Items::ItemReferences.size() << " unique items" << std::endl;
}
catch (const std::exception& err) {