use game implementation for stack item limits
This commit is contained in:
+11
-13
@@ -540,7 +540,7 @@ PlayerBankItem::PlayerBankItem()
|
|||||||
|
|
||||||
PlayerBankItem::PlayerBankItem(const PlayerInventoryItem& src)
|
PlayerBankItem::PlayerBankItem(const PlayerInventoryItem& src)
|
||||||
: data(src.data),
|
: data(src.data),
|
||||||
amount(combine_item_to_max.count(this->data.primary_identifier()) ? this->data.data1[5] : 1),
|
amount(stack_size_for_item(this->data)),
|
||||||
show_flags(1) { }
|
show_flags(1) { }
|
||||||
|
|
||||||
|
|
||||||
@@ -569,9 +569,8 @@ void SavedPlayerDataBB::add_item(const PlayerInventoryItem& item) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle combinable items
|
// Handle combinable items
|
||||||
try {
|
size_t combine_max = stack_size_for_item(item.data);
|
||||||
uint32_t combine_max = combine_item_to_max.at(pid);
|
if (combine_max > 1) {
|
||||||
|
|
||||||
// Get the item index if there's already a stack of the same item in the
|
// Get the item index if there's already a stack of the same item in the
|
||||||
// player's inventory
|
// player's inventory
|
||||||
size_t y;
|
size_t y;
|
||||||
@@ -589,7 +588,7 @@ void SavedPlayerDataBB::add_item(const PlayerInventoryItem& item) {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (const out_of_range&) { }
|
}
|
||||||
|
|
||||||
// If we get here, then it's not meseta and not a combine item, so it needs to
|
// If we get here, then it's not meseta and not a combine item, so it needs to
|
||||||
// go into an empty inventory slot
|
// go into an empty inventory slot
|
||||||
@@ -611,9 +610,8 @@ void PlayerBank::add_item(const PlayerBankItem& item) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
size_t combine_max = stack_size_for_item(item.data);
|
||||||
uint32_t combine_max = combine_item_to_max.at(pid);
|
if (combine_max > 1) {
|
||||||
|
|
||||||
size_t y;
|
size_t y;
|
||||||
for (y = 0; y < this->num_items; y++) {
|
for (y = 0; y < this->num_items; y++) {
|
||||||
if (this->items[y].data.primary_identifier() == item.data.primary_identifier()) {
|
if (this->items[y].data.primary_identifier() == item.data.primary_identifier()) {
|
||||||
@@ -629,7 +627,7 @@ void PlayerBank::add_item(const PlayerBankItem& item) {
|
|||||||
this->items[y].amount = this->items[y].data.data1[5];
|
this->items[y].amount = this->items[y].data.data1[5];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (const out_of_range&) { }
|
}
|
||||||
|
|
||||||
if (this->num_items >= 200) {
|
if (this->num_items >= 200) {
|
||||||
throw runtime_error("bank is full");
|
throw runtime_error("bank is full");
|
||||||
@@ -663,8 +661,8 @@ PlayerInventoryItem SavedPlayerDataBB::remove_item(
|
|||||||
// then create a new item and reduce the amount of the existing stack. Note
|
// then create a new item and reduce the amount of the existing stack. Note
|
||||||
// that passing amount == 0 means to remove the entire stack, so this only
|
// that passing amount == 0 means to remove the entire stack, so this only
|
||||||
// applies if amount is nonzero.
|
// applies if amount is nonzero.
|
||||||
if (amount && (amount < inventory_item.data.data1[5]) &&
|
if (amount && (stack_size_for_item(inventory_item.data) > 1) &&
|
||||||
combine_item_to_max.count(inventory_item.data.primary_identifier())) {
|
(amount < inventory_item.data.data1[5])) {
|
||||||
ret = inventory_item;
|
ret = inventory_item;
|
||||||
ret.data.data1[5] = amount;
|
ret.data.data1[5] = amount;
|
||||||
ret.data.id = 0xFFFFFFFF;
|
ret.data.id = 0xFFFFFFFF;
|
||||||
@@ -700,8 +698,8 @@ PlayerBankItem PlayerBank::remove_item(uint32_t item_id, uint32_t amount) {
|
|||||||
size_t index = this->find_item(item_id);
|
size_t index = this->find_item(item_id);
|
||||||
auto& bank_item = this->items[index];
|
auto& bank_item = this->items[index];
|
||||||
|
|
||||||
if (amount && (amount < bank_item.data.data1[5]) &&
|
if (amount && (stack_size_for_item(bank_item.data) > 1) &&
|
||||||
combine_item_to_max.count(bank_item.data.primary_identifier())) {
|
(amount < bank_item.data.data1[5])) {
|
||||||
ret = bank_item;
|
ret = bank_item;
|
||||||
ret.data.data1[5] = amount;
|
ret.data.data1[5] = amount;
|
||||||
ret.amount = amount;
|
ret.amount = amount;
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ struct RareItemDrop {
|
|||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct RareItemSet {
|
struct RareItemSet {
|
||||||
|
// TODO: It looks like this structure can actually vary. We see the offsets
|
||||||
|
// 0194 and 01B2 in the unused section, along with the value 1E (number of box
|
||||||
|
// rares). In PSOGC, these all appear to be the same size/format, but that's
|
||||||
|
// probably not strictly required to be the case.
|
||||||
// 0x280 in size; describes one difficulty, section ID, and episode
|
// 0x280 in size; describes one difficulty, section ID, and episode
|
||||||
RareItemDrop rares[0x65]; // 0000 - 0194 in file
|
RareItemDrop rares[0x65]; // 0000 - 0194 in file
|
||||||
uint8_t box_areas[0x1E]; // 0194 - 01B2 in file
|
uint8_t box_areas[0x1E]; // 0194 - 01B2 in file
|
||||||
|
|||||||
+20
-19
@@ -253,24 +253,25 @@ uint8_t npc_for_name(const u16string& name) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const unordered_map<uint32_t, uint32_t> combine_item_to_max({
|
size_t stack_size_for_item(uint8_t data0, uint8_t data1) {
|
||||||
{0x030000, 10},
|
if (data0 == 4) {
|
||||||
{0x030001, 10},
|
return 999999;
|
||||||
{0x030002, 10},
|
}
|
||||||
{0x030100, 10},
|
if (data0 == 3) {
|
||||||
{0x030101, 10},
|
if ((data1 < 9) && (data1 != 2)) {
|
||||||
{0x030102, 10},
|
return 10;
|
||||||
{0x030300, 10},
|
} else if (data1 == 0x10) {
|
||||||
{0x030400, 10},
|
return 99;
|
||||||
{0x030500, 10},
|
}
|
||||||
{0x030600, 10},
|
}
|
||||||
{0x030601, 10},
|
return 1;
|
||||||
{0x030700, 10},
|
}
|
||||||
{0x030800, 10},
|
|
||||||
{0x031000, 99},
|
size_t stack_size_for_item(const ItemData& item) {
|
||||||
{0x031001, 99},
|
return stack_size_for_item(item.data1[0], item.data1[1]);
|
||||||
{0x031002, 99},
|
}
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
const unordered_map<uint8_t, const char*> name_for_weapon_special({
|
const unordered_map<uint8_t, const char*> name_for_weapon_special({
|
||||||
{0x00, nullptr},
|
{0x00, nullptr},
|
||||||
@@ -1592,7 +1593,7 @@ string name_for_item(const ItemData& item, bool include_color_codes) {
|
|||||||
|
|
||||||
// For tools, add the amount (if applicable)
|
// For tools, add the amount (if applicable)
|
||||||
} else if (item.data1[0] == 0x03) {
|
} else if (item.data1[0] == 0x03) {
|
||||||
if (combine_item_to_max.count(primary_identifier)) {
|
if (stack_size_for_item(item) > 1) {
|
||||||
ret_tokens.emplace_back(string_printf("x%hhu", item.data1[5]));
|
ret_tokens.emplace_back(string_printf("x%hhu", item.data1[5]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,9 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern const std::unordered_map<uint32_t, uint32_t> combine_item_to_max;
|
size_t stack_size_for_item(uint8_t data0, uint8_t data1);
|
||||||
|
size_t stack_size_for_item(const ItemData& item);
|
||||||
|
|
||||||
extern const std::unordered_map<uint8_t, const char*> name_for_weapon_special;
|
extern const std::unordered_map<uint8_t, const char*> name_for_weapon_special;
|
||||||
extern const std::unordered_map<uint8_t, const char*> name_for_s_rank_special;
|
extern const std::unordered_map<uint8_t, const char*> name_for_s_rank_special;
|
||||||
extern const std::unordered_map<uint32_t, const char*> name_for_primary_identifier;
|
extern const std::unordered_map<uint32_t, const char*> name_for_primary_identifier;
|
||||||
|
|||||||
Reference in New Issue
Block a user