mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-11-14 15:57:13 +00:00
fix: a player with PVP on is not its own enemy
LWOCharacterComponent::SendMessage (0x00d34330), IsValidPVPTarget: the target is never the player itself. LWODestroyableComponent's IsEnemy asks it for every character. DLU called a player with PVP on an enemy of itself. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -532,6 +532,8 @@ void DestroyableComponent::AddFaction(const int32_t factionID, const bool ignore
|
||||
bool DestroyableComponent::IsEnemy(const Entity* other) const {
|
||||
if (IsEnemyImplentation.ExecuteWithDefault(other, false)) return true;
|
||||
if (m_Parent->IsPlayer() && other->IsPlayer()) {
|
||||
// A player is never its own PVP target
|
||||
if (other == m_Parent) return false;
|
||||
auto* thisCharacterComponent = m_Parent->GetComponent<CharacterComponent>();
|
||||
if (!thisCharacterComponent) return false;
|
||||
auto* otherCharacterComponent = other->GetComponent<CharacterComponent>();
|
||||
|
||||
@@ -622,6 +622,41 @@ TEST_F(DestroyableTest, PlayerDieDoesNotClaimAClientDeath) {
|
||||
player.SetCharacter(nullptr);
|
||||
}
|
||||
|
||||
// LWOCharacterComponent::SendMessage, IsValidPVPTarget: two players with PVP on are enemies, a player is never its own
|
||||
TEST_F(DestroyableTest, APlayerWithPvpIsNotItsOwnEnemy) {
|
||||
auto playerInfo = info;
|
||||
playerInfo.lot = 1;
|
||||
SystemAddress address;
|
||||
address.binaryAddress = 0x0100007f;
|
||||
address.port = 2003;
|
||||
|
||||
Entity player(0x1000000000000001LL, playerInfo);
|
||||
Character character(1, nullptr);
|
||||
player.SetCharacter(&character);
|
||||
character.SetEntity(&player);
|
||||
auto* playerCharacter = player.AddComponent<CharacterComponent>(-1, &character, address);
|
||||
auto* destroyable = player.AddComponent<DestroyableComponent>(-1);
|
||||
|
||||
Entity other(0x1000000000000002LL, playerInfo);
|
||||
Character otherCharacter(2, nullptr);
|
||||
other.SetCharacter(&otherCharacter);
|
||||
otherCharacter.SetEntity(&other);
|
||||
auto* otherCharacterComponent = other.AddComponent<CharacterComponent>(-1, &otherCharacter, address);
|
||||
other.AddComponent<DestroyableComponent>(-1);
|
||||
ASSERT_TRUE(player.IsPlayer());
|
||||
ASSERT_TRUE(other.IsPlayer());
|
||||
|
||||
EXPECT_FALSE(destroyable->IsEnemy(&other));
|
||||
playerCharacter->SetPvpEnabled(true);
|
||||
EXPECT_FALSE(destroyable->IsEnemy(&other));
|
||||
otherCharacterComponent->SetPvpEnabled(true);
|
||||
EXPECT_TRUE(destroyable->IsEnemy(&other));
|
||||
EXPECT_FALSE(destroyable->IsEnemy(&player));
|
||||
|
||||
player.SetCharacter(nullptr);
|
||||
other.SetCharacter(nullptr);
|
||||
}
|
||||
|
||||
// BasicAttack's dir_angle_* are degrees; live's Die carries them as these exact floats.
|
||||
TEST_F(DestroyableTest, DeathDirectionDegreesMatchLiveBits) {
|
||||
const auto bits = [](float value) { uint32_t out; std::memcpy(&out, &value, sizeof(out)); return out; };
|
||||
|
||||
Reference in New Issue
Block a user