factor ClientGameData into Client to reduce data duplication
This commit is contained in:
+68
-69
@@ -13,7 +13,6 @@
|
||||
#include "Loggers.hh"
|
||||
#include "Map.hh"
|
||||
#include "PSOProtocol.hh"
|
||||
#include "Player.hh"
|
||||
#include "SendCommands.hh"
|
||||
#include "StaticGameData.hh"
|
||||
#include "Text.hh"
|
||||
@@ -324,7 +323,7 @@ static void on_sync_joining_player_item_state(shared_ptr<Client> c, uint8_t comm
|
||||
}
|
||||
auto* floor_items = reinterpret_cast<FloorItem*>(decompressed.data() + sizeof(G_SyncItemState_6x6D_Decompressed));
|
||||
|
||||
size_t target_num_items = target->game_data.character()->inventory.num_items;
|
||||
size_t target_num_items = target->character()->inventory.num_items;
|
||||
for (size_t z = 0; z < 12; z++) {
|
||||
uint32_t client_next_id = decompressed_cmd->next_item_id_per_player[z];
|
||||
uint32_t server_next_id = l->next_item_id[z];
|
||||
@@ -549,12 +548,12 @@ static void on_send_guild_card(shared_ptr<Client> c, uint8_t command, uint8_t fl
|
||||
case Version::DC_V1:
|
||||
case Version::DC_V2: {
|
||||
const auto& cmd = check_size_t<G_SendGuildCard_DC_6x06>(data, size);
|
||||
c->game_data.character(true, false)->guild_card.description.encode(cmd.guild_card.description.decode(c->language()), c->language());
|
||||
c->character(true, false)->guild_card.description.encode(cmd.guild_card.description.decode(c->language()), c->language());
|
||||
break;
|
||||
}
|
||||
case Version::PC_V2: {
|
||||
const auto& cmd = check_size_t<G_SendGuildCard_PC_6x06>(data, size);
|
||||
c->game_data.character(true, false)->guild_card.description = cmd.guild_card.description;
|
||||
c->character(true, false)->guild_card.description = cmd.guild_card.description;
|
||||
break;
|
||||
}
|
||||
case Version::GC_NTE:
|
||||
@@ -562,12 +561,12 @@ static void on_send_guild_card(shared_ptr<Client> c, uint8_t command, uint8_t fl
|
||||
case Version::GC_EP3_TRIAL_EDITION:
|
||||
case Version::GC_EP3: {
|
||||
const auto& cmd = check_size_t<G_SendGuildCard_GC_6x06>(data, size);
|
||||
c->game_data.character(true, false)->guild_card.description.encode(cmd.guild_card.description.decode(c->language()), c->language());
|
||||
c->character(true, false)->guild_card.description.encode(cmd.guild_card.description.decode(c->language()), c->language());
|
||||
break;
|
||||
}
|
||||
case Version::XB_V3: {
|
||||
const auto& cmd = check_size_t<G_SendGuildCard_XB_6x06>(data, size);
|
||||
c->game_data.character(true, false)->guild_card.description.encode(cmd.guild_card.description.decode(c->language()), c->language());
|
||||
c->character(true, false)->guild_card.description.encode(cmd.guild_card.description.decode(c->language()), c->language());
|
||||
break;
|
||||
}
|
||||
case Version::BB_V4:
|
||||
@@ -651,7 +650,7 @@ static void on_word_select_t(shared_ptr<Client> c, uint8_t command, uint8_t, con
|
||||
}
|
||||
|
||||
} catch (const exception& e) {
|
||||
string name = c->game_data.character()->disp.name.decode(c->language());
|
||||
string name = c->character()->disp.name.decode(c->language());
|
||||
lc->log.warning("Untranslatable Word Select message: %s", e.what());
|
||||
send_text_message_printf(lc, "$C4Untranslatable Word\nSelect message from\n%s", name.c_str());
|
||||
}
|
||||
@@ -720,7 +719,7 @@ static void on_player_died(shared_ptr<Client> c, uint8_t command, uint8_t flag,
|
||||
|
||||
if (l->check_flag(Lobby::Flag::ITEM_TRACKING_ENABLED)) {
|
||||
try {
|
||||
auto& inventory = c->game_data.character()->inventory;
|
||||
auto& inventory = c->character()->inventory;
|
||||
size_t mag_index = inventory.find_equipped_item(EquipSlot::MAG);
|
||||
auto& data = inventory.items[mag_index].data;
|
||||
data.data2[0] = max<int8_t>(static_cast<int8_t>(data.data2[0] - 5), 0);
|
||||
@@ -874,7 +873,7 @@ static void on_player_drop_item(shared_ptr<Client> c, uint8_t command, uint8_t f
|
||||
|
||||
auto l = c->require_lobby();
|
||||
if (l->check_flag(Lobby::Flag::ITEM_TRACKING_ENABLED)) {
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
auto item = p->remove_item(cmd.item_id, 0, c->version() != Version::BB_V4);
|
||||
l->add_item(item, cmd.floor, cmd.x, cmd.z);
|
||||
|
||||
@@ -933,7 +932,7 @@ static void on_create_inventory_item_t(shared_ptr<Client> c, uint8_t command, ui
|
||||
|
||||
auto l = c->require_lobby();
|
||||
if (l->check_flag(Lobby::Flag::ITEM_TRACKING_ENABLED)) {
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
ItemData item = cmd.item_data;
|
||||
item.decode_for_version(c->version());
|
||||
l->on_item_id_generated_externally(item.id);
|
||||
@@ -992,7 +991,7 @@ static void on_drop_partial_stack_t(shared_ptr<Client> c, uint8_t command, uint8
|
||||
string name = s->describe_item(c->version(), item, true);
|
||||
send_text_message_printf(c, "$C5SPLIT %08" PRIX32 "\n%s", item.id.load(), name.c_str());
|
||||
}
|
||||
c->game_data.character()->print_inventory(stderr, c->version(), s->item_name_index);
|
||||
c->character()->print_inventory(stderr, c->version(), s->item_name_index);
|
||||
}
|
||||
|
||||
forward_subcommand_with_item_transcode_t(c, command, flag, cmd);
|
||||
@@ -1021,7 +1020,7 @@ static void on_drop_partial_stack_bb(shared_ptr<Client> c, uint8_t command, uint
|
||||
throw logic_error("item tracking not enabled in BB game");
|
||||
}
|
||||
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
auto item = p->remove_item(cmd.item_id, cmd.amount, c->version() != Version::BB_V4);
|
||||
|
||||
// If a stack was split, the original item still exists, so the dropped item
|
||||
@@ -1070,7 +1069,7 @@ static void on_buy_shop_item(shared_ptr<Client> c, uint8_t command, uint8_t flag
|
||||
}
|
||||
|
||||
if (l->check_flag(Lobby::Flag::ITEM_TRACKING_ENABLED)) {
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
ItemData item = cmd.item_data;
|
||||
item.data2d = 0; // Clear the price field
|
||||
item.decode_for_version(c->version());
|
||||
@@ -1169,7 +1168,7 @@ static void on_pick_up_item(shared_ptr<Client> c, uint8_t command, uint8_t flag,
|
||||
|
||||
if (l->check_flag(Lobby::Flag::ITEM_TRACKING_ENABLED)) {
|
||||
auto s = c->require_server_state();
|
||||
auto effective_p = effective_c->game_data.character();
|
||||
auto effective_p = effective_c->character();
|
||||
|
||||
// It seems the client just plays it fast and loose with these commands.
|
||||
// There can be multiple 6x5A (request to pick up item) commands in flight,
|
||||
@@ -1238,7 +1237,7 @@ static void on_pick_up_item_request(shared_ptr<Client> c, uint8_t command, uint8
|
||||
throw logic_error("item tracking not enabled in BB game");
|
||||
}
|
||||
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
auto item = l->remove_item(cmd.item_id);
|
||||
p->add_item(item);
|
||||
|
||||
@@ -1268,7 +1267,7 @@ static void on_equip_item(shared_ptr<Client> c, uint8_t command, uint8_t flag, c
|
||||
auto l = c->require_lobby();
|
||||
if (l->check_flag(Lobby::Flag::ITEM_TRACKING_ENABLED)) {
|
||||
EquipSlot slot = static_cast<EquipSlot>(cmd.equip_slot.load());
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
p->inventory.equip_item_id(cmd.item_id, slot);
|
||||
c->log.info("Equipped item %08" PRIX32, cmd.item_id.load());
|
||||
} else if (l->base_version == Version::BB_V4) {
|
||||
@@ -1287,7 +1286,7 @@ static void on_unequip_item(shared_ptr<Client> c, uint8_t command, uint8_t flag,
|
||||
|
||||
auto l = c->require_lobby();
|
||||
if (l->check_flag(Lobby::Flag::ITEM_TRACKING_ENABLED)) {
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
p->inventory.unequip_item_id(cmd.item_id);
|
||||
c->log.info("Unequipped item %08" PRIX32, cmd.item_id.load());
|
||||
} else if (l->base_version == Version::BB_V4) {
|
||||
@@ -1311,7 +1310,7 @@ static void on_use_item(
|
||||
auto l = c->require_lobby();
|
||||
if (l->check_flag(Lobby::Flag::ITEM_TRACKING_ENABLED)) {
|
||||
auto s = c->require_server_state();
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
size_t index = p->inventory.find_item(cmd.item_id);
|
||||
string name, colored_name;
|
||||
{
|
||||
@@ -1349,7 +1348,7 @@ static void on_feed_mag(
|
||||
auto l = c->require_lobby();
|
||||
if (l->check_flag(Lobby::Flag::ITEM_TRACKING_ENABLED)) {
|
||||
auto s = c->require_server_state();
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
|
||||
size_t mag_index = p->inventory.find_item(cmd.mag_item_id);
|
||||
size_t fed_index = p->inventory.find_item(cmd.fed_item_id);
|
||||
@@ -1404,21 +1403,21 @@ static void on_open_shop_bb_or_ep3_battle_subs(shared_ptr<Client> c, uint8_t com
|
||||
}
|
||||
|
||||
auto s = c->require_server_state();
|
||||
size_t level = c->game_data.character()->disp.stats.level + 1;
|
||||
size_t level = c->character()->disp.stats.level + 1;
|
||||
switch (cmd.shop_type) {
|
||||
case 0:
|
||||
c->game_data.shop_contents[0] = l->item_creator->generate_tool_shop_contents(level);
|
||||
c->bb_shop_contents[0] = l->item_creator->generate_tool_shop_contents(level);
|
||||
break;
|
||||
case 1:
|
||||
c->game_data.shop_contents[1] = l->item_creator->generate_weapon_shop_contents(level);
|
||||
c->bb_shop_contents[1] = l->item_creator->generate_weapon_shop_contents(level);
|
||||
break;
|
||||
case 2:
|
||||
c->game_data.shop_contents[2] = l->item_creator->generate_armor_shop_contents(level);
|
||||
c->bb_shop_contents[2] = l->item_creator->generate_armor_shop_contents(level);
|
||||
break;
|
||||
default:
|
||||
throw runtime_error("invalid shop type");
|
||||
}
|
||||
for (auto& item : c->game_data.shop_contents[cmd.shop_type]) {
|
||||
for (auto& item : c->bb_shop_contents[cmd.shop_type]) {
|
||||
item.id = 0xFFFFFFFF;
|
||||
item.data2d = s->item_parameter_table_for_version(c->version())->price_for_item(item);
|
||||
}
|
||||
@@ -1452,8 +1451,8 @@ static void on_ep3_private_word_select_bb_bank_action(shared_ptr<Client> c, uint
|
||||
throw logic_error("item tracking not enabled in BB game");
|
||||
}
|
||||
|
||||
auto p = c->game_data.character();
|
||||
auto& bank = c->game_data.current_bank();
|
||||
auto p = c->character();
|
||||
auto& bank = c->current_bank();
|
||||
if (cmd.action == 0) { // Deposit
|
||||
if (cmd.item_id == 0xFFFFFFFF) { // Deposit Meseta
|
||||
if (cmd.meseta_amount > p->disp.stats.meseta) {
|
||||
@@ -1484,7 +1483,7 @@ static void on_ep3_private_word_select_bb_bank_action(shared_ptr<Client> c, uint
|
||||
string name = s->item_name_index->describe_item(Version::BB_V4, item);
|
||||
l->log.info("Player %hu deposited item %08" PRIX32 " (x%hhu) (%s) in the bank",
|
||||
c->lobby_client_id, cmd.item_id.load(), cmd.item_amount, name.c_str());
|
||||
c->game_data.character()->print_inventory(stderr, c->version(), s->item_name_index);
|
||||
c->character()->print_inventory(stderr, c->version(), s->item_name_index);
|
||||
}
|
||||
|
||||
} else if (cmd.action == 1) { // Take
|
||||
@@ -1511,7 +1510,7 @@ static void on_ep3_private_word_select_bb_bank_action(shared_ptr<Client> c, uint
|
||||
string name = s->item_name_index->describe_item(Version::BB_V4, item);
|
||||
l->log.info("Player %hu withdrew item %08" PRIX32 " (x%hhu) (%s) from the bank",
|
||||
c->lobby_client_id, item.id.load(), cmd.item_amount, name.c_str());
|
||||
c->game_data.character()->print_inventory(stderr, c->version(), s->item_name_index);
|
||||
c->character()->print_inventory(stderr, c->version(), s->item_name_index);
|
||||
}
|
||||
|
||||
} else if (cmd.action == 3) { // Leave bank counter
|
||||
@@ -1532,7 +1531,7 @@ static void on_sort_inventory_bb(shared_ptr<Client> c, uint8_t, uint8_t, const v
|
||||
throw logic_error("item tracking not enabled in BB game");
|
||||
}
|
||||
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
|
||||
// Make sure the set of item IDs passed in by the client exactly matches the
|
||||
// set of item IDs present in the inventory
|
||||
@@ -1745,7 +1744,7 @@ static void on_set_quest_flag(shared_ptr<Client> c, uint8_t command, uint8_t fla
|
||||
}
|
||||
|
||||
// TODO: Should we allow overlays here?
|
||||
auto p = c->game_data.character(true, false);
|
||||
auto p = c->character(true, false);
|
||||
|
||||
// The client explicitly checks for both 0 and 1 - any other value means no
|
||||
// operation is performed.
|
||||
@@ -1898,7 +1897,7 @@ static void on_charge_attack_bb(shared_ptr<Client> c, uint8_t command, uint8_t f
|
||||
forward_subcommand(c, command, flag, data, size);
|
||||
|
||||
const auto& cmd = check_size_t<G_ChargeAttack_BB_6xC7>(data, size);
|
||||
auto& disp = c->game_data.character()->disp;
|
||||
auto& disp = c->character()->disp;
|
||||
if (cmd.meseta_amount > disp.stats.meseta) {
|
||||
disp.stats.meseta = 0;
|
||||
} else {
|
||||
@@ -1914,7 +1913,7 @@ static void on_level_up(shared_ptr<Client> c, uint8_t command, uint8_t flag, con
|
||||
return;
|
||||
}
|
||||
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
p->disp.stats.char_stats.atp = cmd.atp;
|
||||
p->disp.stats.char_stats.mst = cmd.mst;
|
||||
p->disp.stats.char_stats.evp = cmd.evp;
|
||||
@@ -1928,7 +1927,7 @@ static void on_level_up(shared_ptr<Client> c, uint8_t command, uint8_t flag, con
|
||||
|
||||
static void add_player_exp(shared_ptr<Client> c, uint32_t exp) {
|
||||
auto s = c->require_server_state();
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
|
||||
p->disp.stats.experience += exp;
|
||||
send_give_experience(c, exp);
|
||||
@@ -1963,7 +1962,7 @@ static void on_steal_exp_bb(shared_ptr<Client> c, uint8_t, uint8_t, const void*
|
||||
|
||||
const auto& cmd = check_size_t<G_StealEXP_BB_6xC6>(data, size);
|
||||
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
const auto& enemy = l->map->enemies.at(cmd.enemy_index);
|
||||
const auto& inventory = p->inventory;
|
||||
const auto& weapon = inventory.items[inventory.find_equipped_item(EquipSlot::WEAPON)];
|
||||
@@ -2073,14 +2072,14 @@ static void on_enemy_exp_request_bb(shared_ptr<Client> c, uint8_t, uint8_t, cons
|
||||
(!cmd.is_killer == !is_killer) ? "" : "$C6!K$C5 ",
|
||||
name_for_enum(e.type));
|
||||
}
|
||||
if (c->game_data.character()->disp.stats.level < 199) {
|
||||
if (c->character()->disp.stats.level < 199) {
|
||||
add_player_exp(c, player_exp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update kill counts on unsealable items
|
||||
auto& inventory = c->game_data.character()->inventory;
|
||||
auto& inventory = c->character()->inventory;
|
||||
for (size_t z = 0; z < inventory.num_items; z++) {
|
||||
auto& item = inventory.items[z];
|
||||
if ((item.flags & 0x08) &&
|
||||
@@ -2093,7 +2092,7 @@ static void on_enemy_exp_request_bb(shared_ptr<Client> c, uint8_t, uint8_t, cons
|
||||
void on_meseta_reward_request_bb(shared_ptr<Client> c, uint8_t, uint8_t, const void* data, size_t size) {
|
||||
const auto& cmd = check_size_t<G_MesetaRewardRequest_BB_6xC9>(data, size);
|
||||
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
if (cmd.amount < 0) {
|
||||
if (-cmd.amount > static_cast<int32_t>(p->disp.stats.meseta.load())) {
|
||||
p->disp.stats.meseta = 0;
|
||||
@@ -2119,7 +2118,7 @@ void on_item_reward_request_bb(shared_ptr<Client> c, uint8_t, uint8_t, const voi
|
||||
ItemData item;
|
||||
item = cmd.item_data;
|
||||
item.id = l->generate_item_id(c->lobby_client_id);
|
||||
c->game_data.character()->add_item(item);
|
||||
c->character()->add_item(item);
|
||||
send_create_inventory_item(c, item);
|
||||
}
|
||||
|
||||
@@ -2148,7 +2147,7 @@ void on_transfer_item_via_mail_message_bb(shared_ptr<Client> c, uint8_t command,
|
||||
forward_subcommand(c, command, flag, data, size);
|
||||
|
||||
auto s = c->require_server_state();
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
auto item = p->remove_item(cmd.item_id, cmd.amount, c->version() != Version::BB_V4);
|
||||
|
||||
auto name = s->describe_item(c->version(), item, false);
|
||||
@@ -2167,10 +2166,10 @@ void on_transfer_item_via_mail_message_bb(shared_ptr<Client> c, uint8_t command,
|
||||
auto target_c = s->find_client(nullptr, cmd.target_guild_card_number);
|
||||
if (target_c &&
|
||||
(target_c->version() == Version::BB_V4) &&
|
||||
(target_c->game_data.character(false) != nullptr) &&
|
||||
(target_c->character(false) != nullptr) &&
|
||||
!target_c->config.check_flag(Client::Flag::AT_BANK_COUNTER)) {
|
||||
try {
|
||||
target_c->game_data.current_bank().add_item(item);
|
||||
target_c->current_bank().add_item(item);
|
||||
item_sent = true;
|
||||
} catch (const runtime_error&) {
|
||||
}
|
||||
@@ -2210,7 +2209,7 @@ void on_exchange_item_for_team_points_bb(shared_ptr<Client> c, uint8_t command,
|
||||
}
|
||||
|
||||
auto s = c->require_server_state();
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
auto item = p->remove_item(cmd.item_id, cmd.amount, c->version() != Version::BB_V4);
|
||||
|
||||
size_t points = s->item_parameter_table_v4->get_item_team_points(item);
|
||||
@@ -2241,7 +2240,7 @@ static void on_destroy_inventory_item(shared_ptr<Client> c, uint8_t command, uin
|
||||
|
||||
if (l->check_flag(Lobby::Flag::ITEM_TRACKING_ENABLED)) {
|
||||
auto s = c->require_server_state();
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
auto item = p->remove_item(cmd.item_id, cmd.amount, c->version() != Version::BB_V4);
|
||||
auto name = s->describe_item(c->version(), item, false);
|
||||
l->log.info("Player %hhu destroyed inventory item %hu:%08" PRIX32 " (%s)",
|
||||
@@ -2293,7 +2292,7 @@ static void on_identify_item_bb(shared_ptr<Client> c, uint8_t command, uint8_t f
|
||||
throw logic_error("received item identify subcommand without item creator present");
|
||||
}
|
||||
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
size_t x = p->inventory.find_item(cmd.item_id);
|
||||
if (p->inventory.items[x].data.data1[0] != 0) {
|
||||
throw runtime_error("non-weapon items cannot be unidentified");
|
||||
@@ -2305,9 +2304,9 @@ static void on_identify_item_bb(shared_ptr<Client> c, uint8_t command, uint8_t f
|
||||
// ID instead.
|
||||
l->generate_item_id(c->lobby_client_id);
|
||||
p->disp.stats.meseta -= 100;
|
||||
c->game_data.identify_result = p->inventory.items[x].data;
|
||||
c->game_data.identify_result.data1[4] &= 0x7F;
|
||||
l->item_creator->apply_tekker_deltas(c->game_data.identify_result, p->disp.visual.section_id);
|
||||
c->bb_identify_result = p->inventory.items[x].data;
|
||||
c->bb_identify_result.data1[4] &= 0x7F;
|
||||
l->item_creator->apply_tekker_deltas(c->bb_identify_result, p->disp.visual.section_id);
|
||||
send_item_identify_result(c);
|
||||
|
||||
} else {
|
||||
@@ -2324,15 +2323,15 @@ static void on_accept_identify_item_bb(shared_ptr<Client> c, uint8_t command, ui
|
||||
throw logic_error("item tracking not enabled in BB game");
|
||||
}
|
||||
|
||||
if (!c->game_data.identify_result.id || (c->game_data.identify_result.id == 0xFFFFFFFF)) {
|
||||
if (!c->bb_identify_result.id || (c->bb_identify_result.id == 0xFFFFFFFF)) {
|
||||
throw runtime_error("no identify result present");
|
||||
}
|
||||
if (c->game_data.identify_result.id != cmd.item_id) {
|
||||
if (c->bb_identify_result.id != cmd.item_id) {
|
||||
throw runtime_error("accepted item ID does not match previous identify request");
|
||||
}
|
||||
c->game_data.character()->add_item(c->game_data.identify_result);
|
||||
send_create_inventory_item(c, c->game_data.identify_result);
|
||||
c->game_data.identify_result.clear();
|
||||
c->character()->add_item(c->bb_identify_result);
|
||||
send_create_inventory_item(c, c->bb_identify_result);
|
||||
c->bb_identify_result.clear();
|
||||
|
||||
} else {
|
||||
forward_subcommand(c, command, flag, data, size);
|
||||
@@ -2350,7 +2349,7 @@ static void on_sell_item_at_shop_bb(shared_ptr<Client> c, uint8_t command, uint8
|
||||
}
|
||||
|
||||
auto s = c->require_server_state();
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
auto item = p->remove_item(cmd.item_id, cmd.amount, c->version() != Version::BB_V4);
|
||||
size_t price = (s->item_parameter_table_for_version(c->version())->price_for_item(item) >> 3) * cmd.amount;
|
||||
p->add_meseta(price);
|
||||
@@ -2378,7 +2377,7 @@ static void on_buy_shop_item_bb(shared_ptr<Client> c, uint8_t, uint8_t, const vo
|
||||
}
|
||||
|
||||
ItemData item;
|
||||
item = c->game_data.shop_contents.at(cmd.shop_type).at(cmd.item_index);
|
||||
item = c->bb_shop_contents.at(cmd.shop_type).at(cmd.item_index);
|
||||
if (item.is_stackable()) {
|
||||
item.data1[5] = cmd.amount;
|
||||
} else if (cmd.amount != 1) {
|
||||
@@ -2387,7 +2386,7 @@ static void on_buy_shop_item_bb(shared_ptr<Client> c, uint8_t, uint8_t, const vo
|
||||
|
||||
size_t price = item.data2d * cmd.amount;
|
||||
item.data2d = 0;
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
p->remove_meseta(price, false);
|
||||
|
||||
item.id = l->generate_item_id(c->lobby_client_id);
|
||||
@@ -2410,7 +2409,7 @@ static void on_buy_shop_item_bb(shared_ptr<Client> c, uint8_t, uint8_t, const vo
|
||||
static void on_medical_center_bb(shared_ptr<Client> c, uint8_t, uint8_t, const void*, size_t) {
|
||||
auto l = c->require_lobby();
|
||||
if (l->is_game() && (l->base_version == Version::BB_V4)) {
|
||||
c->game_data.character()->remove_meseta(10, false);
|
||||
c->character()->remove_meseta(10, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2436,8 +2435,8 @@ static void on_battle_restart_bb(shared_ptr<Client> c, uint8_t, uint8_t, const v
|
||||
|
||||
for (auto& lc : l->clients) {
|
||||
if (lc) {
|
||||
lc->game_data.delete_overlay();
|
||||
lc->game_data.create_battle_overlay(new_rules, s->level_table);
|
||||
lc->delete_overlay();
|
||||
lc->create_battle_overlay(new_rules, s->level_table);
|
||||
}
|
||||
}
|
||||
l->map->clear();
|
||||
@@ -2462,7 +2461,7 @@ static void on_battle_level_up_bb(shared_ptr<Client> c, uint8_t, uint8_t, const
|
||||
auto lc = l->clients.at(cmd.header.client_id);
|
||||
if (lc) {
|
||||
auto s = c->require_server_state();
|
||||
auto lp = lc->game_data.character();
|
||||
auto lp = lc->character();
|
||||
uint32_t target_level = lp->disp.stats.level + cmd.num_levels;
|
||||
uint32_t before_exp = lp->disp.stats.experience;
|
||||
lp->disp.stats.advance_to_level(lp->disp.visual.char_class, target_level, s->level_table);
|
||||
@@ -2502,7 +2501,7 @@ static void on_quest_exchange_item_bb(shared_ptr<Client> c, uint8_t, uint8_t, co
|
||||
const auto& cmd = check_size_t<G_ExchangeItemInQuest_BB_6xD5>(data, size);
|
||||
|
||||
try {
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
|
||||
size_t found_index = p->inventory.find_item_by_primary_identifier(cmd.find_item.primary_identifier());
|
||||
auto found_item = p->remove_item(p->inventory.items[found_index].data.id, 1, false);
|
||||
@@ -2529,7 +2528,7 @@ static void on_wrap_item_bb(shared_ptr<Client> c, uint8_t, uint8_t, const void*
|
||||
if (l->is_game() && (l->base_version == Version::BB_V4)) {
|
||||
const auto& cmd = check_size_t<G_WrapItem_BB_6xD6>(data, size);
|
||||
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
auto item = p->remove_item(cmd.item.id, 1, false);
|
||||
send_destroy_item(c, item.id, 1);
|
||||
item.wrap();
|
||||
@@ -2544,7 +2543,7 @@ static void on_photon_drop_exchange_for_item_bb(shared_ptr<Client> c, uint8_t, u
|
||||
const auto& cmd = check_size_t<G_PaganiniPhotonDropExchange_BB_6xD7>(data, size);
|
||||
|
||||
try {
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
|
||||
size_t found_index = p->inventory.find_item_by_primary_identifier(0x031000);
|
||||
auto found_item = p->remove_item(p->inventory.items[found_index].data.id, 0, false);
|
||||
@@ -2572,7 +2571,7 @@ static void on_photon_drop_exchange_for_s_rank_special_bb(shared_ptr<Client> c,
|
||||
const auto& cmd = check_size_t<G_AddSRankWeaponSpecial_BB_6xD8>(data, size);
|
||||
|
||||
try {
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
|
||||
static const array<uint8_t, 0x10> costs({60, 60, 20, 20, 30, 30, 30, 50, 40, 50, 40, 40, 50, 40, 40, 40});
|
||||
uint8_t cost = costs.at(cmd.special_type);
|
||||
@@ -2610,7 +2609,7 @@ static void on_secret_lottery_ticket_exchange_bb(shared_ptr<Client> c, uint8_t,
|
||||
throw runtime_error("no secret lottery results are defined");
|
||||
}
|
||||
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
ssize_t slt_index = -1;
|
||||
try {
|
||||
slt_index = p->inventory.find_item_by_primary_identifier(0x031003); // Secret Lottery Ticket
|
||||
@@ -2659,7 +2658,7 @@ static void on_photon_crystal_exchange_bb(shared_ptr<Client> c, uint8_t, uint8_t
|
||||
auto l = c->require_lobby();
|
||||
if (l->is_game() && (l->base_version == Version::BB_V4) && l->check_flag(Lobby::Flag::QUEST_IN_PROGRESS)) {
|
||||
check_size_t<G_ExchangePhotonCrystals_BB_6xDF>(data, size);
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
size_t index = p->inventory.find_item_by_primary_identifier(0x031002);
|
||||
auto item = p->remove_item(p->inventory.items[index].data.id, 1, false);
|
||||
send_destroy_item(c, item.id, 1);
|
||||
@@ -2701,7 +2700,7 @@ static void on_quest_F95F_result_bb(shared_ptr<Client> c, uint8_t, uint8_t, cons
|
||||
if (l->is_game() && (l->base_version == Version::BB_V4) && l->check_flag(Lobby::Flag::QUEST_IN_PROGRESS)) {
|
||||
const auto& cmd = check_size_t<G_ExchangePhotonTickets_BB_6xE1>(data, size);
|
||||
auto s = c->require_server_state();
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
|
||||
const auto& result = s->quest_F95F_results.at(cmd.result_index);
|
||||
if (result.second.empty()) {
|
||||
@@ -2739,7 +2738,7 @@ static void on_momoka_item_exchange_bb(shared_ptr<Client> c, uint8_t, uint8_t, c
|
||||
auto l = c->require_lobby();
|
||||
if (l->is_game() && (l->base_version == Version::BB_V4) && l->check_flag(Lobby::Flag::QUEST_IN_PROGRESS)) {
|
||||
const auto& cmd = check_size_t<G_MomokaItemExchange_BB_6xD9>(data, size);
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
try {
|
||||
size_t found_index = p->inventory.find_item_by_primary_identifier(cmd.find_item.primary_identifier());
|
||||
auto found_item = p->remove_item(p->inventory.items[found_index].data.id, 1, false);
|
||||
@@ -2768,7 +2767,7 @@ static void on_upgrade_weapon_attribute_bb(shared_ptr<Client> c, uint8_t, uint8_
|
||||
auto l = c->require_lobby();
|
||||
if (l->is_game() && (l->base_version == Version::BB_V4) && l->check_flag(Lobby::Flag::QUEST_IN_PROGRESS)) {
|
||||
const auto& cmd = check_size_t<G_UpgradeWeaponAttribute_BB_6xDA>(data, size);
|
||||
auto p = c->game_data.character();
|
||||
auto p = c->character();
|
||||
try {
|
||||
size_t item_index = p->inventory.find_item(cmd.item_id);
|
||||
auto& item = p->inventory.items[item_index].data;
|
||||
@@ -2819,7 +2818,7 @@ static void on_upgrade_weapon_attribute_bb(shared_ptr<Client> c, uint8_t, uint8_
|
||||
|
||||
static void on_write_quest_global_flag_bb(shared_ptr<Client> c, uint8_t, uint8_t, const void* data, size_t size) {
|
||||
const auto& cmd = check_size_t<G_SetQuestGlobalFlag_BB_6xD2>(data, size);
|
||||
c->game_data.character()->quest_global_flags[cmd.index] = cmd.value;
|
||||
c->character()->quest_global_flags[cmd.index] = cmd.value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user