add patch to show EXP gains from the server
This commit is contained in:
+11
-7
@@ -6172,12 +6172,23 @@ struct G_ChangeLobbyMusic_Ep3_6xBF {
|
||||
} __packed_ws__(G_ChangeLobbyMusic_Ep3_6xBF, 8);
|
||||
|
||||
// 6xBF: Give EXP (BB) (server->client only)
|
||||
// newserv implements an extension that causes this command to show the purple
|
||||
// EXP numbers which are normally generated by the client instead. This
|
||||
// requires the server to also send the enemy ID that generated the EXP, hence
|
||||
// the extension struct here. See ServerEXPDisplay.59NL.patch.s for details.
|
||||
|
||||
struct G_GiveExperience_BB_6xBF {
|
||||
G_ClientIDHeader header;
|
||||
le_uint32_t amount = 0;
|
||||
} __packed_ws__(G_GiveExperience_BB_6xBF, 8);
|
||||
|
||||
struct G_GiveExperience_Extension_BB_6xBF {
|
||||
G_ClientIDHeader header;
|
||||
le_uint32_t amount = 0;
|
||||
le_uint16_t from_enemy_id = 0;
|
||||
le_uint16_t unused = 0;
|
||||
} __packed_ws__(G_GiveExperience_Extension_BB_6xBF, 0x0C);
|
||||
|
||||
// 6xC0: Sell item at shop (BB) (protected on V3/V4)
|
||||
|
||||
struct G_SellItemAtShop_BB_6xC0 {
|
||||
@@ -6433,18 +6444,11 @@ struct G_Episode4BossActions_BB_6xDC {
|
||||
// means all EXP is doubled, for example. This only affects what the client
|
||||
// shows when an enemy is killed; actual EXP gains are controlled by the server
|
||||
// in response to the 6xC8 command.
|
||||
// newserv supports an extension to this command that supports fractional
|
||||
// multipliers. This is implemented in FractionalEXPMultiplier.59NL.patch.s.
|
||||
|
||||
struct G_SetEXPMultiplier_BB_6xDD {
|
||||
G_ParameterHeader header;
|
||||
} __packed_ws__(G_SetEXPMultiplier_BB_6xDD, 4);
|
||||
|
||||
struct G_SetFractionalEXPMultiplier_Extension_BB_6xDD {
|
||||
G_ParameterHeader header;
|
||||
le_float multiplier;
|
||||
} __packed_ws__(G_SetFractionalEXPMultiplier_Extension_BB_6xDD, 8);
|
||||
|
||||
// 6xDE: Exchange Secret Lottery Ticket (BB; handled by server)
|
||||
// The client sends this when it executes an F95C quest opcode.
|
||||
// There appears to be a bug in the client here: it sets the subcommand size to
|
||||
|
||||
@@ -3863,13 +3863,13 @@ static asio::awaitable<void> on_level_up(shared_ptr<Client> c, SubcommandMessage
|
||||
forward_subcommand(c, msg);
|
||||
}
|
||||
|
||||
static void add_player_exp(shared_ptr<Client> c, uint32_t exp) {
|
||||
static void add_player_exp(shared_ptr<Client> c, uint32_t exp, uint16_t from_enemy_id) {
|
||||
auto s = c->require_server_state();
|
||||
auto p = c->character_file();
|
||||
|
||||
p->disp.stats.experience += exp;
|
||||
if (c->version() == Version::BB_V4) {
|
||||
send_give_experience(c, exp);
|
||||
send_give_experience(c, exp, from_enemy_id);
|
||||
}
|
||||
|
||||
bool leveled_up = false;
|
||||
@@ -3994,7 +3994,7 @@ static asio::awaitable<void> on_steal_exp_bb(shared_ptr<Client> c, SubcommandMes
|
||||
ene_st->e_id, enemy_exp, percent, stolen_exp);
|
||||
send_text_message_fmt(c, "$C5+{} E-{:03X} {}", stolen_exp, ene_st->e_id, phosg::name_for_enum(type));
|
||||
}
|
||||
add_player_exp(c, stolen_exp);
|
||||
add_player_exp(c, stolen_exp, cmd.enemy_index | 0x1000);
|
||||
}
|
||||
|
||||
static asio::awaitable<void> on_enemy_exp_request_bb(shared_ptr<Client> c, SubcommandMessage& msg) {
|
||||
@@ -4081,7 +4081,7 @@ static asio::awaitable<void> on_enemy_exp_request_bb(shared_ptr<Client> c, Subco
|
||||
if (lc->check_flag(Client::Flag::DEBUG_ENABLED)) {
|
||||
send_text_message_fmt(lc, "$C5+{} E-{:03X} {}", player_exp, ene_st->e_id, phosg::name_for_enum(type));
|
||||
}
|
||||
add_player_exp(lc, player_exp);
|
||||
add_player_exp(lc, player_exp, cmd.enemy_index | 0x1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4582,7 +4582,7 @@ static asio::awaitable<void> on_battle_level_up_bb(shared_ptr<Client> c, Subcomm
|
||||
if (exp_delta > 0) {
|
||||
s->level_table(lc->version())->advance_to_level(lp->disp.stats, target_level, lp->disp.visual.char_class);
|
||||
if (lc->version() == Version::BB_V4) {
|
||||
send_give_experience(lc, exp_delta);
|
||||
send_give_experience(lc, exp_delta, 0xFFFF);
|
||||
send_level_up(lc);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-6
@@ -3311,14 +3311,14 @@ void send_level_up(shared_ptr<Client> c) {
|
||||
send_command_t(l, 0x60, 0x00, cmd);
|
||||
}
|
||||
|
||||
void send_give_experience(shared_ptr<Client> c, uint32_t amount) {
|
||||
void send_give_experience(shared_ptr<Client> c, uint32_t amount, uint16_t from_enemy_id) {
|
||||
auto l = c->require_lobby();
|
||||
if (c->version() != Version::BB_V4) {
|
||||
throw logic_error("6xBF can only be sent to BB clients");
|
||||
}
|
||||
uint16_t client_id = c->lobby_client_id;
|
||||
G_GiveExperience_BB_6xBF cmd = {
|
||||
{0xBF, sizeof(G_GiveExperience_BB_6xBF) / 4, client_id}, amount};
|
||||
G_GiveExperience_Extension_BB_6xBF cmd = {
|
||||
{0xBF, sizeof(G_GiveExperience_Extension_BB_6xBF) / 4, client_id}, amount, from_enemy_id, 0};
|
||||
send_command_t(l, 0x60, 0x00, cmd);
|
||||
}
|
||||
|
||||
@@ -3326,11 +3326,9 @@ void send_set_exp_multiplier(shared_ptr<Lobby> l) {
|
||||
if (!l->is_game()) {
|
||||
throw logic_error("6xDD can only be sent in games (not in lobbies)");
|
||||
}
|
||||
G_SetFractionalEXPMultiplier_Extension_BB_6xDD cmd = {
|
||||
{0xDD, sizeof(G_SetFractionalEXPMultiplier_Extension_BB_6xDD) / 4, 1}, 1.0f};
|
||||
G_SetEXPMultiplier_BB_6xDD cmd = {0xDD, sizeof(G_SetEXPMultiplier_BB_6xDD) / 4, 1};
|
||||
if (l->mode != GameMode::CHALLENGE) {
|
||||
cmd.header.param = l->base_exp_multiplier;
|
||||
cmd.multiplier = l->base_exp_multiplier;
|
||||
}
|
||||
for (auto lc : l->clients) {
|
||||
if (lc && (lc->version() == Version::BB_V4)) {
|
||||
|
||||
+1
-1
@@ -399,7 +399,7 @@ void send_item_identify_result(std::shared_ptr<Client> c);
|
||||
void send_bank(std::shared_ptr<Client> c);
|
||||
void send_shop(std::shared_ptr<Client> c, uint8_t shop_type);
|
||||
void send_level_up(std::shared_ptr<Client> c);
|
||||
void send_give_experience(std::shared_ptr<Client> c, uint32_t amount);
|
||||
void send_give_experience(std::shared_ptr<Client> c, uint32_t amount, uint16_t entity_id);
|
||||
void send_set_exp_multiplier(std::shared_ptr<Lobby> l);
|
||||
void send_rare_enemy_index_list(std::shared_ptr<Client> c, const std::vector<size_t>& indexes);
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ write_call_to_code:
|
||||
# [esp + 0x04] = code ptr
|
||||
# [esp + 0x08] = code size
|
||||
# [esp + 0x0C] = jump callsite
|
||||
# [esp + 0x10] = callsite size
|
||||
# [esp + 0x10] = callsite size (if zero, write the address instead of a call)
|
||||
|
||||
# Allocate memory for the copied code
|
||||
mov ecx, [0x00AAB404]
|
||||
@@ -41,8 +41,16 @@ memcpy_again:
|
||||
jne memcpy_again
|
||||
pop ebx
|
||||
|
||||
# Write the call or jmp opcode
|
||||
mov edx, [esp + 0x0C] # edx = jump callsite
|
||||
|
||||
# If the callsite size is zero, just write the address directly
|
||||
cmp dword [esp + 0x10], 0
|
||||
jne write_call_or_jmp
|
||||
mov [edx], eax
|
||||
jmp done
|
||||
|
||||
# Write the call or jmp opcode
|
||||
write_call_or_jmp:
|
||||
lea ecx, [eax - 5]
|
||||
sub ecx, edx # ecx = (dest code addr) - (jump callsite) - 5
|
||||
cmp dword [esp + 0x10], 0
|
||||
|
||||
@@ -811,8 +811,9 @@
|
||||
"Friday": ["Monomate x1", "Dimate x1", "Trimate x1", "Monofluid x1", "Difluid x1", "Trifluid x1", "Sol Atomizer x1", "Moon Atomizer x1", "Antidote x1", "Antiparalysis x1", "Telepipe x1", "Trap Vision x1"],
|
||||
"Saturday": ["Monomate x1", "Dimate x1", "Trimate x1", "Monofluid x1", "Difluid x1", "Trifluid x1", "Sol Atomizer x1", "Moon Atomizer x1", "Antidote x1", "Antiparalysis x1", "Telepipe x1", "Trap Vision x1"],
|
||||
},
|
||||
// EXP multiplier for BB games. This must be an integer due to a client
|
||||
// limitation, and must be at least 1.
|
||||
// EXP multiplier for BB games. If this is not an integer, the client will
|
||||
// display incorrect EXP values, unless you also add "ServerEXPDisplay" to
|
||||
// BBRequiredPatches.
|
||||
"BBGlobalEXPMultiplier": 1,
|
||||
// EXP share multiplier for BB games. The logic for EXP computation is:
|
||||
// - If the player lands the killing blow on an enemy they get full EXP (or
|
||||
|
||||
Reference in New Issue
Block a user