fix NPC last-hit EXP
This commit is contained in:
@@ -4342,13 +4342,14 @@ struct G_Attack_6x43_6x44_6x45 {
|
|||||||
|
|
||||||
// 6x46: Attack finished (sent after each of 43, 44, and 45) (protected on V3/V4)
|
// 6x46: Attack finished (sent after each of 43, 44, and 45) (protected on V3/V4)
|
||||||
|
|
||||||
|
struct TargetEntry {
|
||||||
|
le_uint16_t entity_id = 0;
|
||||||
|
le_uint16_t unknown_a2 = 0;
|
||||||
|
} __packed__;
|
||||||
|
|
||||||
struct G_AttackFinished_6x46 {
|
struct G_AttackFinished_6x46 {
|
||||||
G_ClientIDHeader header;
|
G_ClientIDHeader header;
|
||||||
le_uint32_t count = 0;
|
le_uint32_t count = 0;
|
||||||
struct TargetEntry {
|
|
||||||
le_uint16_t unknown_a1 = 0;
|
|
||||||
le_uint16_t unknown_a2 = 0;
|
|
||||||
} __packed__;
|
|
||||||
// The client may send a shorter command if not all of these are used.
|
// The client may send a shorter command if not all of these are used.
|
||||||
parray<TargetEntry, 10> targets;
|
parray<TargetEntry, 10> targets;
|
||||||
} __packed__;
|
} __packed__;
|
||||||
@@ -4366,11 +4367,7 @@ struct G_CastTechnique_6x47 {
|
|||||||
// compatibility, and never cleaned it up.
|
// compatibility, and never cleaned it up.
|
||||||
uint8_t level = 0;
|
uint8_t level = 0;
|
||||||
uint8_t target_count = 0; // Must be in [0, 10]
|
uint8_t target_count = 0; // Must be in [0, 10]
|
||||||
struct TargetEntry {
|
// The client may send a shorter command if not all of these are used.
|
||||||
le_uint16_t client_id = 0;
|
|
||||||
le_uint16_t unknown_a2 = 0;
|
|
||||||
} __packed__;
|
|
||||||
// The client mauy send a shorter command if not all of these are used.
|
|
||||||
parray<TargetEntry, 10> targets;
|
parray<TargetEntry, 10> targets;
|
||||||
} __packed__;
|
} __packed__;
|
||||||
|
|
||||||
|
|||||||
+3
-6
@@ -663,19 +663,16 @@ Map::Enemy::Enemy(uint16_t enemy_id, size_t source_index, size_t set_index, uint
|
|||||||
game_flags(0),
|
game_flags(0),
|
||||||
type(type),
|
type(type),
|
||||||
floor(floor),
|
floor(floor),
|
||||||
state_flags(0),
|
state_flags(0) {}
|
||||||
last_hit_by_client_id(0) {
|
|
||||||
}
|
|
||||||
|
|
||||||
string Map::Enemy::str() const {
|
string Map::Enemy::str() const {
|
||||||
return string_printf("[Map::Enemy E-%hX source %zX %s%s floor=%02hhX flags=%02hhX last_hit_by_client_id=%hu]",
|
return string_printf("[Map::Enemy E-%hX source %zX %s%s floor=%02hhX flags=%02hhX]",
|
||||||
this->enemy_id,
|
this->enemy_id,
|
||||||
this->source_index,
|
this->source_index,
|
||||||
name_for_enum(this->type),
|
name_for_enum(this->type),
|
||||||
enemy_type_is_rare(this->type) ? " RARE" : "",
|
enemy_type_is_rare(this->type) ? " RARE" : "",
|
||||||
this->floor,
|
this->floor,
|
||||||
this->state_flags,
|
this->state_flags);
|
||||||
this->last_hit_by_client_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string Map::Object::str() const {
|
string Map::Object::str() const {
|
||||||
|
|||||||
@@ -242,7 +242,6 @@ struct Map {
|
|||||||
EnemyType type;
|
EnemyType type;
|
||||||
uint8_t floor;
|
uint8_t floor;
|
||||||
uint8_t state_flags;
|
uint8_t state_flags;
|
||||||
uint8_t last_hit_by_client_id;
|
|
||||||
|
|
||||||
Enemy(uint16_t enemy_id, size_t source_index, size_t set_index, uint8_t floor, EnemyType type);
|
Enemy(uint16_t enemy_id, size_t source_index, size_t set_index, uint8_t floor, EnemyType type);
|
||||||
|
|
||||||
|
|||||||
@@ -2597,7 +2597,6 @@ static void on_update_enemy_state(shared_ptr<Client> c, uint8_t command, uint8_t
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto& enemy = l->map->enemies[cmd.enemy_index];
|
auto& enemy = l->map->enemies[cmd.enemy_index];
|
||||||
enemy.last_hit_by_client_id = c->lobby_client_id;
|
|
||||||
enemy.game_flags = is_big_endian(c->version()) ? bswap32(cmd.flags) : cmd.flags.load();
|
enemy.game_flags = is_big_endian(c->version()) ? bswap32(cmd.flags) : cmd.flags.load();
|
||||||
enemy.total_damage = cmd.total_damage;
|
enemy.total_damage = cmd.total_damage;
|
||||||
l->log.info("E-%hX updated to damage=%hu game_flags=%08" PRIX32, cmd.enemy_index.load(), enemy.total_damage, enemy.game_flags);
|
l->log.info("E-%hX updated to damage=%hu game_flags=%08" PRIX32, cmd.enemy_index.load(), enemy.total_damage, enemy.game_flags);
|
||||||
@@ -2831,19 +2830,17 @@ static void on_enemy_exp_request_bb(shared_ptr<Client> c, uint8_t, uint8_t, void
|
|||||||
// the monsters would all give more EXP, but they did something far lazier
|
// the monsters would all give more EXP, but they did something far lazier
|
||||||
// instead: they just stuck an if statement in the client's EXP request
|
// instead: they just stuck an if statement in the client's EXP request
|
||||||
// function. We, unfortunately, have to do the same here.
|
// function. We, unfortunately, have to do the same here.
|
||||||
bool is_killer = (e.last_hit_by_client_id == c->lobby_client_id);
|
|
||||||
bool is_ep2 = (l->episode == Episode::EP2);
|
bool is_ep2 = (l->episode == Episode::EP2);
|
||||||
uint32_t player_exp = experience *
|
uint32_t player_exp = experience *
|
||||||
(is_killer ? 1.0 : 0.8) *
|
(cmd.is_killer ? 1.0 : 0.8) *
|
||||||
l->base_exp_multiplier *
|
l->base_exp_multiplier *
|
||||||
l->challenge_exp_multiplier *
|
l->challenge_exp_multiplier *
|
||||||
(is_ep2 ? 1.3 : 1.0);
|
(is_ep2 ? 1.3 : 1.0);
|
||||||
if (c->config.check_flag(Client::Flag::DEBUG_ENABLED)) {
|
if (c->config.check_flag(Client::Flag::DEBUG_ENABLED)) {
|
||||||
send_text_message_printf(
|
send_text_message_printf(
|
||||||
c, "$C5+%" PRIu32 " E-%hX %s%s",
|
c, "$C5+%" PRIu32 " E-%hX %s",
|
||||||
player_exp,
|
player_exp,
|
||||||
cmd.enemy_index.load(),
|
cmd.enemy_index.load(),
|
||||||
(!cmd.is_killer == !is_killer) ? "" : "$C6!K$C5 ",
|
|
||||||
name_for_enum(e.type));
|
name_for_enum(e.type));
|
||||||
}
|
}
|
||||||
if (c->character()->disp.stats.level < 199) {
|
if (c->character()->disp.stats.level < 199) {
|
||||||
|
|||||||
Reference in New Issue
Block a user