mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 02:43:44 +00:00
Game message 1726 (optional object ID, default 0), as the 1.10.64 client reads it. Live sent it to every player when an object left the world; nothing sends it yet. Tested against a live capture packet. Needs the FromLiveCapture test helper. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
292 lines
11 KiB
C++
292 lines
11 KiB
C++
#ifndef COMBATMESSAGES_H
|
|
#define COMBATMESSAGES_H
|
|
|
|
#include "GameMessages.h"
|
|
#include "NiPoint3.h"
|
|
|
|
#include <string>
|
|
|
|
enum class eKillType : uint32_t;
|
|
enum class eStateChangeType : uint32_t;
|
|
|
|
// Game messages for combat: death and resurrection, stuns and immunities, buffs, knockback and the bubble buff.
|
|
// Field names follow the client (legouniverse.exe 1.10.64); fields are listed in wire order.
|
|
// Unless noted, server -> client messages are sent with Send (UNASSIGNED_SYSTEM_ADDRESS broadcasts), as before.
|
|
namespace GameMessages {
|
|
// Server -> client, broadcast.
|
|
struct Die : public NetGameMsg {
|
|
Die() : NetGameMsg(MessageType::Game::DIE) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
bool bClientDeath{ false };
|
|
bool bSpawnLoot{ true };
|
|
std::u16string deathType{}; // u32 length prefixed
|
|
float directionRelative_AngleXZ{};
|
|
float directionRelative_AngleY{};
|
|
float directionRelative_Force{};
|
|
eKillType killType{ 0 }; // optional, eKillType::VIOLENT when unset
|
|
LWOOBJID killerID{};
|
|
LWOOBJID lootOwnerID{ LWOOBJID_EMPTY }; // optional
|
|
};
|
|
|
|
// Client -> server. Read with the same layout as Die, as DLU always has.
|
|
struct RequestDie : public NetGameMsg {
|
|
RequestDie() : NetGameMsg(MessageType::Game::REQUEST_DIE) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
void Handle(Entity& entity, const SystemAddress& sysAddr) override;
|
|
|
|
bool bClientDeath{ false };
|
|
bool bSpawnLoot{ false };
|
|
std::u16string deathType{}; // u32 length prefixed
|
|
float directionRelative_AngleXZ{};
|
|
float directionRelative_AngleY{};
|
|
float directionRelative_Force{};
|
|
eKillType killType{ 0 }; // optional, eKillType::VIOLENT when unset
|
|
LWOOBJID killerID{};
|
|
LWOOBJID lootOwnerID{ LWOOBJID_EMPTY }; // optional
|
|
};
|
|
|
|
// Client -> server. No payload.
|
|
struct RequestSmashPlayer : public NetGameMsg {
|
|
RequestSmashPlayer() : NetGameMsg(MessageType::Game::REQUEST_SMASH_PLAYER) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
void Handle(Entity& entity, const SystemAddress& sysAddr) override;
|
|
};
|
|
|
|
// Client -> server. The player pressed respawn. No payload.
|
|
struct RequestResurrect : public NetGameMsg {
|
|
RequestResurrect() : NetGameMsg(MessageType::Game::REQUEST_RESURRECT) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
void Handle(Entity& entity, const SystemAddress& sysAddr) override;
|
|
};
|
|
|
|
// Server -> client (broadcast) when an entity comes back to life, and client -> server when the player has
|
|
// resurrected.
|
|
struct Resurrect : public NetGameMsg {
|
|
Resurrect() : NetGameMsg(MessageType::Game::RESURRECT) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
void Handle(Entity& entity, const SystemAddress& sysAddr) override;
|
|
|
|
bool bRezImmediately{ false };
|
|
};
|
|
|
|
// Server -> client. Smashes the target into bricks without destroying it.
|
|
struct Smash : public NetGameMsg {
|
|
Smash() : NetGameMsg(MessageType::Game::SMASH) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
bool bIgnoreObjectVisibility{ false };
|
|
float force{};
|
|
float ghostOpacity{};
|
|
LWOOBJID killerID{};
|
|
};
|
|
|
|
// Server -> client. Rebuilds a smashed target over duration seconds.
|
|
struct UnSmash : public NetGameMsg {
|
|
UnSmash() : NetGameMsg(MessageType::Game::UN_SMASH) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
LWOOBJID builderID{ LWOOBJID_EMPTY }; // optional
|
|
float duration{ 3.0f }; // optional
|
|
};
|
|
|
|
// Server -> client, broadcast.
|
|
struct SetResurrectRestoreValues : public NetGameMsg {
|
|
SetResurrectRestoreValues() : NetGameMsg(MessageType::Game::SET_RESURRECT_RESTORE_VALUES) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
int32_t iArmorRestore{ -1 }; // optional
|
|
int32_t iHealthRestore{ -1 }; // optional
|
|
int32_t iImaginationRestore{ -1 }; // optional
|
|
};
|
|
|
|
// Server -> client. Sent with SendToClient: the old function never broadcast.
|
|
struct SetPlayerAllowedRespawn : public NetGameMsg {
|
|
SetPlayerAllowedRespawn() : NetGameMsg(MessageType::Game::SET_PLAYER_ALLOWED_RESPAWN) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
bool dontPromptForRespawn{};
|
|
};
|
|
|
|
// Server -> client, broadcast.
|
|
struct Knockback : public NetGameMsg {
|
|
Knockback() : NetGameMsg(MessageType::Game::KNOCKBACK) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
LWOOBJID Caster{ LWOOBJID_EMPTY }; // optional
|
|
LWOOBJID Originator{ LWOOBJID_EMPTY }; // optional
|
|
int32_t iKnockBackTimeMS{ 0 }; // optional
|
|
NiPoint3 vector{};
|
|
};
|
|
|
|
// Server -> client.
|
|
struct SetStunned : public NetGameMsg {
|
|
SetStunned() : NetGameMsg(MessageType::Game::SET_STUNNED) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
LWOOBJID Originator{ LWOOBJID_EMPTY }; // optional
|
|
eStateChangeType StateChangeType{};
|
|
bool bCantAttack{ false };
|
|
bool bCantAttackOutChangeWasApplied{ false };
|
|
bool bCantEquip{ false };
|
|
bool bCantEquipOutChangeWasApplied{ false };
|
|
bool bCantInteract{ false };
|
|
bool bCantInteractOutChangeWasApplied{ false };
|
|
bool bCantJump{ false };
|
|
bool bCantJumpOutChangeWasApplied{ false };
|
|
bool bCantMove{ false };
|
|
bool bCantMoveOutChangeWasApplied{ false };
|
|
bool bCantTurn{ false };
|
|
bool bCantTurnOutChangeWasApplied{ false };
|
|
bool bCantUseItem{ false };
|
|
bool bCantUseItemOutChangeWasApplied{ false };
|
|
bool bDontTerminateInteract{ false };
|
|
bool bIgnoreImmunity{ true };
|
|
};
|
|
|
|
// Server -> client.
|
|
struct SetStunImmunity : public NetGameMsg {
|
|
SetStunImmunity() : NetGameMsg(MessageType::Game::SET_STUN_IMMUNITY) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
LWOOBJID Caster{ LWOOBJID_EMPTY }; // optional
|
|
eStateChangeType StateChangeType{};
|
|
bool bImmuneToStunAttack{ false };
|
|
bool bImmuneToStunEquip{ false };
|
|
bool bImmuneToStunInteract{ false };
|
|
bool bImmuneToStunJump{ false };
|
|
bool bImmuneToStunMove{ false };
|
|
bool bImmuneToStunTurn{ false };
|
|
bool bImmuneToStunUseItem{ false };
|
|
};
|
|
|
|
// Server -> client.
|
|
// WIRE FIX: the flags go on the wire in alphabetical order, as the client's Serialize writes them
|
|
// (GameMessage::SetStatusImmunity::Serialize @ 00d8f140 in 1.10.64; field offsets named by its Flash export
|
|
// @ 00d8f410). DLU used to write them in the declaration order below.
|
|
struct SetStatusImmunity : public NetGameMsg {
|
|
SetStatusImmunity() : NetGameMsg(MessageType::Game::SET_STATUS_IMMUNITY) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
eStateChangeType StateChangeType{};
|
|
bool bImmuneToBasicAttack{ false };
|
|
bool bImmuneToDOT{ false };
|
|
bool bImmuneToKnockback{ false };
|
|
bool bImmuneToInterrupt{ false };
|
|
bool bImmuneToSpeed{ false };
|
|
bool bImmuneToImaginationGain{ false };
|
|
bool bImmuneToImaginationLoss{ false };
|
|
bool bImmuneToQuickbuildInterrupt{ false };
|
|
bool bImmuneToPullToPoint{ false };
|
|
};
|
|
|
|
// Server -> client.
|
|
struct AddBuff : public NetGameMsg {
|
|
AddBuff() : NetGameMsg(MessageType::Game::ADD_BUFF) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
bool bAddedByTeammate{ false };
|
|
bool bApplyOnTeammates{ false };
|
|
bool bCancelOnDamaged{ false };
|
|
bool bCancelOnDeath{ false };
|
|
bool bCancelOnLogOut{ false };
|
|
bool bCancelOnMove{ false };
|
|
bool bCancelOnRemoveBuff{ false };
|
|
bool bCancelOnUI{ false };
|
|
bool bCancelOnUnEquip{ false };
|
|
bool bCancelOnZone{ false };
|
|
bool bIgnoreImmunities{ false };
|
|
bool bIsImmunity{ false };
|
|
bool bUseRefCount{ false };
|
|
LWOOBJID i64AddedBy{ LWOOBJID_EMPTY }; // optional
|
|
uint32_t uiBuffID{};
|
|
uint32_t uiDurationMS{ 0 }; // optional
|
|
};
|
|
|
|
// Server -> client, broadcast.
|
|
struct RemoveBuff : public NetGameMsg {
|
|
RemoveBuff() : NetGameMsg(MessageType::Game::REMOVE_BUFF) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
// With either flag set the client only removes a buff that was added with the matching cancelOnRemoveBuff /
|
|
// cancelOnUnEquip (LWOBuffComponent::RemoveBuffIcon @ 00cf99b0 in 1.10.64).
|
|
bool bFromRemoveBehavior{ false };
|
|
bool bFromUnEquip{ false };
|
|
bool bRemoveImmunity{ false };
|
|
uint32_t uiBuffID{};
|
|
};
|
|
|
|
// Server -> client. The client's BuffComponent removes every buff (and immunity) whose source is objectID
|
|
// (msgRemoveBuffsAppliedByObject @ 00d38f20 in 1.10.64). Live sent it to each player when an object left the
|
|
// world (see docs/CaptureUnknowns.md).
|
|
struct RemoveBuffsAppliedByObject : public NetGameMsg {
|
|
RemoveBuffsAppliedByObject() : NetGameMsg(MessageType::Game::REMOVE_BUFFS_APPLIED_BY_OBJECT) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
LWOOBJID objectID{ LWOOBJID_EMPTY }; // optional
|
|
};
|
|
|
|
// Server -> client.
|
|
struct AddRunSpeedModifier : public NetGameMsg {
|
|
AddRunSpeedModifier() : NetGameMsg(MessageType::Game::ADD_RUN_SPEED_MODIFIER) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
LWOOBJID i64Caster{ LWOOBJID_EMPTY }; // optional
|
|
uint32_t uiModifier{ 500 }; // optional
|
|
};
|
|
|
|
// Server -> client.
|
|
struct RemoveRunSpeedModifier : public NetGameMsg {
|
|
RemoveRunSpeedModifier() : NetGameMsg(MessageType::Game::REMOVE_RUN_SPEED_MODIFIER) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
|
|
uint32_t uiModifier{ 500 }; // optional
|
|
};
|
|
|
|
// Client -> server. The player went under water (or into skunk stink) and wants the bubble helmet.
|
|
struct ActivateBubbleBuff : public NetGameMsg {
|
|
ActivateBubbleBuff() : NetGameMsg(MessageType::Game::ACTIVATE_BUBBLE_BUFF) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
void Handle(Entity& entity, const SystemAddress& sysAddr) override;
|
|
|
|
bool bSpecialAnims{};
|
|
std::u16string wszType{}; // u32 length prefixed
|
|
};
|
|
|
|
// Client -> server. No payload.
|
|
struct DeactivateBubbleBuff : public NetGameMsg {
|
|
DeactivateBubbleBuff() : NetGameMsg(MessageType::Game::DECTIVATE_BUBBLE_BUFF) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
void Handle(Entity& entity, const SystemAddress& sysAddr) override;
|
|
};
|
|
|
|
// Server -> client. No payload.
|
|
struct DeactivateBubbleBuffFromServer : public NetGameMsg {
|
|
DeactivateBubbleBuffFromServer() : NetGameMsg(MessageType::Game::DEACTIVATE_BUBBLE_BUFF_FROM_SERVER) {}
|
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
|
};
|
|
};
|
|
|
|
#endif // COMBATMESSAGES_H
|