fix some endianness differences on GC/XB
This commit is contained in:
+36
-4
@@ -3768,12 +3768,18 @@ struct G_Unknown_6x09 {
|
||||
|
||||
// 6x0A: Enemy hit
|
||||
|
||||
template <bool IsBigEndian>
|
||||
struct G_EnemyHitByPlayer_6x0A {
|
||||
G_EnemyIDHeader header;
|
||||
// Note: enemy_id (in header) is in the range [0x1000, 0x4000)
|
||||
le_uint16_t enemy_id = 0;
|
||||
le_uint16_t remaining_hp = 0;
|
||||
be_uint32_t flags = 0;
|
||||
typename std::conditional<IsBigEndian, be_uint32_t, le_uint32_t>::type flags = 0;
|
||||
} __packed__;
|
||||
|
||||
struct G_EnemyHitByPlayer_GC_6x0A : G_EnemyHitByPlayer_6x0A<true> {
|
||||
} __packed__;
|
||||
struct G_EnemyHitByPlayer_DC_PC_XB_BB_6x0A : G_EnemyHitByPlayer_6x0A<false> {
|
||||
} __packed__;
|
||||
|
||||
// 6x0B: Box destroyed
|
||||
@@ -3814,7 +3820,22 @@ struct G_Unknown_6x10_6x11_6x12_6x14 {
|
||||
// Same format as 6x10
|
||||
|
||||
// 6x12: Dragon boss actions (not valid on Episode 3)
|
||||
// Same format as 6x10
|
||||
|
||||
template <bool IsBigEndian>
|
||||
struct G_DragonBossActions_6x12 {
|
||||
using F32T = typename std::conditional<IsBigEndian, be_float, le_float>::type;
|
||||
G_EnemyIDHeader header;
|
||||
le_uint16_t unknown_a2 = 0;
|
||||
le_uint16_t unknown_a3 = 0;
|
||||
le_uint32_t unknown_a4 = 0;
|
||||
F32T x = 0.0f;
|
||||
F32T z = 0.0f;
|
||||
} __packed__;
|
||||
|
||||
struct G_DragonBossActions_DC_PC_XB_BB_6x12 : G_DragonBossActions_6x12<false> {
|
||||
} __packed__;
|
||||
struct G_DragonBossActions_GC_6x12 : G_DragonBossActions_6x12<true> {
|
||||
} __packed__;
|
||||
|
||||
// 6x13: De Rol Le boss actions (not valid on Episode 3)
|
||||
|
||||
@@ -5068,11 +5089,22 @@ struct G_ModifyTradeProposal_6xA6 {
|
||||
|
||||
// 6xA8: Gol Dragon boss actions (not valid on pre-V3 or Episode 3)
|
||||
|
||||
template <bool IsBigEndian>
|
||||
struct G_GolDragonBossActions_6xA8 {
|
||||
using F32T = typename std::conditional<IsBigEndian, be_float, le_float>::type;
|
||||
G_EnemyIDHeader header;
|
||||
le_uint16_t unknown_a1 = 0;
|
||||
le_uint16_t unknown_a2 = 0;
|
||||
le_uint32_t unknown_a3 = 0;
|
||||
le_uint16_t unknown_a3 = 0;
|
||||
le_uint32_t unknown_a4 = 0;
|
||||
F32T x = 0.0f;
|
||||
F32T z = 0.0f;
|
||||
uint8_t unknown_a5 = 0;
|
||||
parray<uint8_t, 3> unused;
|
||||
} __packed__;
|
||||
|
||||
struct G_GolDragonBossActions_XB_BB_6xA8 : G_GolDragonBossActions_6xA8<false> {
|
||||
} __packed__;
|
||||
struct G_GolDragonBossActions_GC_6xA8 : G_GolDragonBossActions_6xA8<true> {
|
||||
} __packed__;
|
||||
|
||||
// 6xA9: Barba Ray boss actions (not valid on pre-V3 or Episode 3)
|
||||
|
||||
+83
-13
@@ -729,7 +729,7 @@ static void on_player_drop_item(shared_ptr<Client> c, uint8_t command, uint8_t f
|
||||
}
|
||||
|
||||
template <typename CmdT>
|
||||
void forward_subcommand_with_mag_transcode_t(shared_ptr<Client> c, uint8_t command, uint8_t flag, const CmdT& cmd) {
|
||||
void forward_subcommand_with_item_transcode_t(shared_ptr<Client> c, uint8_t command, uint8_t flag, const CmdT& cmd) {
|
||||
// I'm lazy and this should never happen for item commands (since all players
|
||||
// need to stay in sync)
|
||||
if (command_is_private(command)) {
|
||||
@@ -784,7 +784,7 @@ static void on_create_inventory_item_t(shared_ptr<Client> c, uint8_t command, ui
|
||||
p->print_inventory(stderr, c->version(), s->item_name_index);
|
||||
}
|
||||
|
||||
forward_subcommand_with_mag_transcode_t(c, command, flag, cmd);
|
||||
forward_subcommand_with_item_transcode_t(c, command, flag, cmd);
|
||||
}
|
||||
|
||||
static void on_create_inventory_item(shared_ptr<Client> c, uint8_t command, uint8_t flag, const void* data, size_t size) {
|
||||
@@ -830,7 +830,7 @@ static void on_drop_partial_stack_t(shared_ptr<Client> c, uint8_t command, uint8
|
||||
c->game_data.player()->print_inventory(stderr, c->version(), s->item_name_index);
|
||||
}
|
||||
|
||||
forward_subcommand_with_mag_transcode_t(c, command, flag, cmd);
|
||||
forward_subcommand_with_item_transcode_t(c, command, flag, cmd);
|
||||
}
|
||||
|
||||
static void on_drop_partial_stack(shared_ptr<Client> c, uint8_t command, uint8_t flag, const void* data, size_t size) {
|
||||
@@ -924,7 +924,7 @@ static void on_buy_shop_item(shared_ptr<Client> c, uint8_t command, uint8_t flag
|
||||
p->print_inventory(stderr, c->version(), s->item_name_index);
|
||||
}
|
||||
|
||||
forward_subcommand_with_mag_transcode_t(c, command, flag, cmd);
|
||||
forward_subcommand_with_item_transcode_t(c, command, flag, cmd);
|
||||
}
|
||||
|
||||
template <typename CmdT>
|
||||
@@ -1547,14 +1547,74 @@ static void on_set_quest_flag(shared_ptr<Client> c, uint8_t command, uint8_t fla
|
||||
}
|
||||
}
|
||||
|
||||
static void on_enemy_hit(shared_ptr<Client> c, uint8_t command, uint8_t flag, const void* data, size_t size) {
|
||||
auto l = c->require_lobby();
|
||||
if (l->base_version == GameVersion::BB) {
|
||||
const auto& cmd = check_size_t<G_EnemyHitByPlayer_6x0A>(data, size);
|
||||
static void on_dragon_actions(shared_ptr<Client> c, uint8_t command, uint8_t, const void* data, size_t size) {
|
||||
const auto& cmd = check_size_t<G_DragonBossActions_DC_PC_XB_BB_6x12>(data, size);
|
||||
|
||||
if (!l->is_game()) {
|
||||
return;
|
||||
if (command_is_private(command)) {
|
||||
return;
|
||||
}
|
||||
auto l = c->require_lobby();
|
||||
if (!l->is_game()) {
|
||||
return;
|
||||
}
|
||||
|
||||
G_DragonBossActions_GC_6x12 sw_cmd = {{{cmd.header.subcommand, cmd.header.size, cmd.header.enemy_id},
|
||||
cmd.unknown_a2, cmd.unknown_a3, cmd.unknown_a4, cmd.x.load(), cmd.z.load()}};
|
||||
bool sender_is_gc = (c->version() == GameVersion::GC);
|
||||
for (auto lc : l->clients) {
|
||||
if (lc && (lc != c)) {
|
||||
if ((lc->version() == GameVersion::GC) == sender_is_gc) {
|
||||
send_command_t(lc, 0x60, 0x00, cmd);
|
||||
} else {
|
||||
send_command_t(lc, 0x60, 0x00, sw_cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void on_gol_dragon_actions(shared_ptr<Client> c, uint8_t command, uint8_t, const void* data, size_t size) {
|
||||
const auto& cmd = check_size_t<G_GolDragonBossActions_XB_BB_6xA8>(data, size);
|
||||
|
||||
if (command_is_private(command)) {
|
||||
return;
|
||||
}
|
||||
auto l = c->require_lobby();
|
||||
if (!l->is_game()) {
|
||||
return;
|
||||
}
|
||||
|
||||
G_GolDragonBossActions_GC_6xA8 sw_cmd = {{{cmd.header.subcommand, cmd.header.size, cmd.header.enemy_id},
|
||||
cmd.unknown_a2,
|
||||
cmd.unknown_a3,
|
||||
cmd.unknown_a4,
|
||||
cmd.x.load(),
|
||||
cmd.z.load(),
|
||||
cmd.unknown_a5,
|
||||
0}};
|
||||
bool sender_is_gc = (c->version() == GameVersion::GC);
|
||||
for (auto lc : l->clients) {
|
||||
if (lc && (lc != c)) {
|
||||
if ((lc->version() == GameVersion::GC) == sender_is_gc) {
|
||||
send_command_t(lc, 0x60, 0x00, cmd);
|
||||
} else {
|
||||
send_command_t(lc, 0x60, 0x00, sw_cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void on_enemy_hit(shared_ptr<Client> c, uint8_t command, uint8_t, const void* data, size_t size) {
|
||||
const auto& cmd = check_size_t<G_EnemyHitByPlayer_DC_PC_XB_BB_6x0A>(data, size);
|
||||
|
||||
if (command_is_private(command)) {
|
||||
return;
|
||||
}
|
||||
auto l = c->require_lobby();
|
||||
if (!l->is_game()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (l->base_version == GameVersion::BB) {
|
||||
if (c->lobby_client_id > 3) {
|
||||
throw logic_error("client ID is above 3");
|
||||
}
|
||||
@@ -1573,7 +1633,17 @@ static void on_enemy_hit(shared_ptr<Client> c, uint8_t command, uint8_t flag, co
|
||||
enemy.last_hit_by_client_id = c->lobby_client_id;
|
||||
}
|
||||
|
||||
forward_subcommand(c, command, flag, data, size);
|
||||
G_EnemyHitByPlayer_GC_6x0A sw_cmd = {{{cmd.header.subcommand, cmd.header.size, cmd.header.enemy_id}, cmd.enemy_id, cmd.remaining_hp, cmd.flags.load()}};
|
||||
bool sender_is_gc = (c->version() == GameVersion::GC);
|
||||
for (auto lc : l->clients) {
|
||||
if (lc && (lc != c)) {
|
||||
if ((lc->version() == GameVersion::GC) == sender_is_gc) {
|
||||
send_command_t(lc, 0x60, 0x00, cmd);
|
||||
} else {
|
||||
send_command_t(lc, 0x60, 0x00, sw_cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void on_charge_attack_bb(shared_ptr<Client> c, uint8_t command, uint8_t flag, const void* data, size_t size) {
|
||||
@@ -2225,7 +2295,7 @@ subcommand_handler_t subcommand_handlers[0x100] = {
|
||||
/* 6x0F */ nullptr,
|
||||
/* 6x10 */ nullptr,
|
||||
/* 6x11 */ nullptr,
|
||||
/* 6x12 */ on_forward_check_size_game,
|
||||
/* 6x12 */ on_dragon_actions,
|
||||
/* 6x13 */ on_forward_check_size_game,
|
||||
/* 6x14 */ on_forward_check_size_game,
|
||||
/* 6x15 */ on_forward_check_size_game,
|
||||
@@ -2375,7 +2445,7 @@ subcommand_handler_t subcommand_handlers[0x100] = {
|
||||
/* 6xA5 */ on_forward_check_size_game,
|
||||
/* 6xA6 */ on_forward_check_size,
|
||||
/* 6xA7 */ nullptr,
|
||||
/* 6xA8 */ on_forward_check_size_game,
|
||||
/* 6xA8 */ on_gol_dragon_actions,
|
||||
/* 6xA9 */ on_forward_check_size_game,
|
||||
/* 6xAA */ on_forward_check_size_game,
|
||||
/* 6xAB */ on_forward_check_size_client,
|
||||
|
||||
Reference in New Issue
Block a user