fix meseta overdraft disconnect bug
This commit is contained in:
@@ -1495,9 +1495,6 @@ DataIndex::DataIndex(const string& directory, uint32_t behavior_flags)
|
|||||||
add_maps_from_dir(directory + "/maps-free", false);
|
add_maps_from_dir(directory + "/maps-free", false);
|
||||||
add_maps_from_dir(directory + "/maps-quest", true);
|
add_maps_from_dir(directory + "/maps-quest", true);
|
||||||
|
|
||||||
// Generate (and cache) the map list to ensure it's not too large
|
|
||||||
this->get_compressed_map_list();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto json = JSONObject::parse(load_file(directory + "/com-decks.json"));
|
auto json = JSONObject::parse(load_file(directory + "/com-decks.json"));
|
||||||
for (const auto& def_json : json->as_list()) {
|
for (const auto& def_json : json->as_list()) {
|
||||||
|
|||||||
+3
-1
@@ -231,7 +231,9 @@ void player_use_item(shared_ptr<Client> c, size_t item_index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (should_delete_item) {
|
if (should_delete_item) {
|
||||||
c->game_data.player()->remove_item(item.data.id, 1);
|
// Allow overdrafting meseta if the client is not BB, since the server isn't
|
||||||
|
// informed when meseta is added or removed from the bank.
|
||||||
|
c->game_data.player()->remove_item(item.data.id, 1, c->version() != GameVersion::BB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-3
@@ -793,18 +793,21 @@ void PlayerBank::add_item(const PlayerBankItem& item) {
|
|||||||
// TODO: Eliminate code duplication between this function and the parallel
|
// TODO: Eliminate code duplication between this function and the parallel
|
||||||
// function in PlayerBank
|
// function in PlayerBank
|
||||||
PlayerInventoryItem SavedPlayerDataBB::remove_item(
|
PlayerInventoryItem SavedPlayerDataBB::remove_item(
|
||||||
uint32_t item_id, uint32_t amount) {
|
uint32_t item_id, uint32_t amount, bool allow_meseta_overdraft) {
|
||||||
PlayerInventoryItem ret;
|
PlayerInventoryItem ret;
|
||||||
|
|
||||||
// If we're removing meseta (signaled by an invalid item ID), then create a
|
// If we're removing meseta (signaled by an invalid item ID), then create a
|
||||||
// meseta item.
|
// meseta item.
|
||||||
if (item_id == 0xFFFFFFFF) {
|
if (item_id == 0xFFFFFFFF) {
|
||||||
if (amount > this->disp.meseta) {
|
if (amount <= this->disp.meseta) {
|
||||||
|
this->disp.meseta -= amount;
|
||||||
|
} else if (allow_meseta_overdraft) {
|
||||||
|
this->disp.meseta = 0;
|
||||||
|
} else {
|
||||||
throw out_of_range("player does not have enough meseta");
|
throw out_of_range("player does not have enough meseta");
|
||||||
}
|
}
|
||||||
ret.data.data1[0] = 0x04;
|
ret.data.data1[0] = 0x04;
|
||||||
ret.data.data2d = amount;
|
ret.data.data2d = amount;
|
||||||
this->disp.meseta -= amount;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -483,7 +483,8 @@ struct SavedPlayerDataBB { // .nsc file format
|
|||||||
parray<uint8_t, 0x0028> tech_menu_config;
|
parray<uint8_t, 0x0028> tech_menu_config;
|
||||||
|
|
||||||
void add_item(const PlayerInventoryItem& item);
|
void add_item(const PlayerInventoryItem& item);
|
||||||
PlayerInventoryItem remove_item(uint32_t item_id, uint32_t amount);
|
PlayerInventoryItem remove_item(
|
||||||
|
uint32_t item_id, uint32_t amount, bool allow_meseta_overdraft);
|
||||||
|
|
||||||
void print_inventory(FILE* stream) const;
|
void print_inventory(FILE* stream) const;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|||||||
@@ -476,8 +476,8 @@ static void on_player_drop_item(shared_ptr<ServerState>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (l->flags & Lobby::Flag::ITEM_TRACKING_ENABLED) {
|
if (l->flags & Lobby::Flag::ITEM_TRACKING_ENABLED) {
|
||||||
l->add_item(c->game_data.player()->remove_item(cmd.item_id, 0), cmd.area,
|
auto item = c->game_data.player()->remove_item(cmd.item_id, 0, c->version() != GameVersion::BB);
|
||||||
cmd.x, cmd.z);
|
l->add_item(item, cmd.area, cmd.x, cmd.z);
|
||||||
|
|
||||||
l->log.info("Player %hu dropped item %08" PRIX32 " at %hu:(%g, %g)",
|
l->log.info("Player %hu dropped item %08" PRIX32 " at %hu:(%g, %g)",
|
||||||
cmd.header.client_id.load(), cmd.item_id.load(), cmd.area.load(),
|
cmd.header.client_id.load(), cmd.item_id.load(), cmd.area.load(),
|
||||||
@@ -563,7 +563,8 @@ static void on_drop_partial_stack_bb(shared_ptr<ServerState>,
|
|||||||
throw logic_error("item tracking not enabled in BB game");
|
throw logic_error("item tracking not enabled in BB game");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto item = c->game_data.player()->remove_item(cmd.item_id, cmd.amount);
|
auto item = c->game_data.player()->remove_item(
|
||||||
|
cmd.item_id, cmd.amount, c->version() != GameVersion::BB);
|
||||||
|
|
||||||
// if a stack was split, the original item still exists, so the dropped item
|
// if a stack was split, the original item still exists, so the dropped item
|
||||||
// needs a new ID. remove_item signals this by returning an item with id=-1
|
// needs a new ID. remove_item signals this by returning an item with id=-1
|
||||||
@@ -814,7 +815,8 @@ static void on_bank_action_bb(shared_ptr<ServerState>,
|
|||||||
c->game_data.player()->bank.meseta += cmd.meseta_amount;
|
c->game_data.player()->bank.meseta += cmd.meseta_amount;
|
||||||
c->game_data.player()->disp.meseta -= cmd.meseta_amount;
|
c->game_data.player()->disp.meseta -= cmd.meseta_amount;
|
||||||
} else { // item
|
} else { // item
|
||||||
auto item = c->game_data.player()->remove_item(cmd.item_id, cmd.item_amount);
|
auto item = c->game_data.player()->remove_item(
|
||||||
|
cmd.item_id, cmd.item_amount, c->version() != GameVersion::BB);
|
||||||
c->game_data.player()->bank.add_item(item);
|
c->game_data.player()->bank.add_item(item);
|
||||||
send_destroy_item(l, c, cmd.item_id, cmd.item_amount);
|
send_destroy_item(l, c, cmd.item_id, cmd.item_amount);
|
||||||
}
|
}
|
||||||
@@ -1130,7 +1132,8 @@ static void on_destroy_inventory_item(shared_ptr<ServerState>,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (l->flags & Lobby::Flag::ITEM_TRACKING_ENABLED) {
|
if (l->flags & Lobby::Flag::ITEM_TRACKING_ENABLED) {
|
||||||
c->game_data.player()->remove_item(cmd.item_id, cmd.amount);
|
c->game_data.player()->remove_item(
|
||||||
|
cmd.item_id, cmd.amount, c->version() != GameVersion::BB);
|
||||||
l->log.info("Inventory item %hu:%08" PRIX32 " destroyed (%" PRIX32 " of them)",
|
l->log.info("Inventory item %hu:%08" PRIX32 " destroyed (%" PRIX32 " of them)",
|
||||||
cmd.header.client_id.load(), cmd.item_id.load(), cmd.amount.load());
|
cmd.header.client_id.load(), cmd.item_id.load(), cmd.amount.load());
|
||||||
c->game_data.player()->print_inventory(stderr);
|
c->game_data.player()->print_inventory(stderr);
|
||||||
|
|||||||
Reference in New Issue
Block a user