mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 05:21:29 +00:00
Save PlayerState server side
We now send the PlayerState in the spawn struct to allow clients to see other bard animations with instrument to be played if they zone in after the bard equipped the instrument OP_WeaponEquip2 and OP_WeaponUnequip2 renamed to OP_PlayerStateAdd and OP_PlayerStateRemove Still needs work: Get AI controlled mobs sending the correct PlayerStates. (stunned, attacking, etc)
This commit is contained in:
parent
8224a9e776
commit
7bcfaf60ab
@ -364,6 +364,8 @@ N(OP_PetitionUnCheckout),
|
||||
N(OP_PetitionUpdate),
|
||||
N(OP_PickPocket),
|
||||
N(OP_PlayerProfile),
|
||||
N(OP_PlayerStateAdd),
|
||||
N(OP_PlayerStateRemove),
|
||||
N(OP_PlayEverquestRequest),
|
||||
N(OP_PlayEverquestResponse),
|
||||
N(OP_PlayMP3),
|
||||
@ -519,8 +521,6 @@ N(OP_VetRewardsAvaliable),
|
||||
N(OP_VoiceMacroIn),
|
||||
N(OP_VoiceMacroOut),
|
||||
N(OP_WeaponEquip1),
|
||||
N(OP_WeaponEquip2),
|
||||
N(OP_WeaponUnequip2),
|
||||
N(OP_WearChange),
|
||||
N(OP_Weather),
|
||||
N(OP_Weblink),
|
||||
|
||||
@ -273,7 +273,8 @@ struct Spawn_Struct {
|
||||
/*0146*/ uint8 beard; // Beard style (not totally, sure but maybe!)
|
||||
/*0147*/ uint8 unknown0147[4];
|
||||
/*0151*/ uint8 level; // Spawn Level
|
||||
/*0152*/ uint8 unknown0259[4]; // ***Placeholder
|
||||
// None = 0, Open = 1, WeaponSheathed = 2, Aggressive = 4, ForcedAggressive = 8, InstrumentEquipped = 16, Stunned = 32, PrimaryWeaponEquipped = 64, SecondaryWeaponEquipped = 128
|
||||
/*0152*/ uint32 PlayerState; // Controls animation stuff
|
||||
/*0156*/ uint8 beardcolor; // Beard color
|
||||
/*0157*/ char suffix[32]; // Player's suffix (of Veeshan, etc.)
|
||||
/*0189*/ uint32 petOwnerId; // If this is a pet, the spawn id of owner
|
||||
@ -366,6 +367,11 @@ union
|
||||
|
||||
};
|
||||
|
||||
struct PlayerState_Struct {
|
||||
/*00*/ uint32 spawn_id;
|
||||
/*04*/ uint32 state;
|
||||
};
|
||||
|
||||
/*
|
||||
** New Spawn
|
||||
** Length: 176 Bytes
|
||||
|
||||
@ -3990,7 +3990,7 @@ namespace RoF
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown13
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown14 - Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->PlayerState);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown15
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown16
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown17
|
||||
|
||||
@ -4140,7 +4140,7 @@ namespace RoF2
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown13
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown14 - Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->PlayerState);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown15
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown16
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown17
|
||||
|
||||
@ -416,7 +416,7 @@ struct Spawn_Struct
|
||||
/*0000*/ uint8 unknown12;
|
||||
/*0000*/ uint32 petOwnerId;
|
||||
/*0000*/ uint8 unknown13;
|
||||
/*0000*/ uint32 unknown14; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
||||
/*0000*/ uint32 PlayerState; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
||||
/*0000*/ uint32 unknown15;
|
||||
/*0000*/ uint32 unknown16;
|
||||
/*0000*/ uint32 unknown17;
|
||||
|
||||
@ -410,7 +410,7 @@ struct Spawn_Struct
|
||||
/*0000*/ uint8 unknown12;
|
||||
/*0000*/ uint32 petOwnerId;
|
||||
/*0000*/ uint8 unknown13;
|
||||
/*0000*/ uint32 unknown14; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
||||
/*0000*/ uint32 PlayerState; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
||||
/*0000*/ uint32 unknown15;
|
||||
/*0000*/ uint32 unknown16;
|
||||
/*0000*/ uint32 unknown17;
|
||||
|
||||
@ -2737,7 +2737,7 @@ namespace SoD
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown12
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown13
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown14 - Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->PlayerState);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown15
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown16
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown17
|
||||
|
||||
@ -286,7 +286,7 @@ struct Spawn_Struct
|
||||
/*0000*/ uint8 unknown12;
|
||||
/*0000*/ uint32 petOwnerId;
|
||||
/*0000*/ uint8 unknown13;
|
||||
/*0000*/ uint32 unknown14; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
||||
/*0000*/ uint32 PlayerState; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
||||
/*0000*/ uint32 unknown15;
|
||||
/*0000*/ uint32 unknown16;
|
||||
/*0000*/ uint32 unknown17;
|
||||
|
||||
@ -2088,6 +2088,7 @@ namespace SoF
|
||||
eq->runspeed = emu->runspeed;
|
||||
eq->light = emu->light;
|
||||
eq->level = emu->level;
|
||||
eq->PlayerState = emu->PlayerState;
|
||||
eq->lfg = emu->lfg;
|
||||
eq->hairstyle = emu->hairstyle;
|
||||
eq->haircolor = emu->haircolor;
|
||||
|
||||
@ -241,7 +241,8 @@ struct Spawn_Struct {
|
||||
/*0506*/ uint8 light; // Spawn's lightsource
|
||||
/*0507*/ uint8 unknown0507[4];
|
||||
/*0511*/ uint8 level; // Spawn Level
|
||||
/*0512*/ uint8 unknown0512[16];
|
||||
/*0512*/ uint32 PlayerState;
|
||||
/*0516*/ uint8 unknown0516[12];
|
||||
/*0528*/ uint8 lfg;
|
||||
/*0529*/ uint8 unknown0529[4];
|
||||
/*0533*/ uint8 hairstyle; // Sets the style of hair
|
||||
|
||||
@ -1549,7 +1549,7 @@ namespace Titanium
|
||||
eq->beardcolor = emu->beardcolor;
|
||||
// eq->unknown0147[4] = emu->unknown0147[4];
|
||||
eq->level = emu->level;
|
||||
// eq->unknown0259[4] = emu->unknown0259[4];
|
||||
eq->PlayerState = emu->PlayerState;
|
||||
eq->beard = emu->beard;
|
||||
strcpy(eq->suffix, emu->suffix);
|
||||
eq->petOwnerId = emu->petOwnerId;
|
||||
|
||||
@ -212,7 +212,7 @@ struct Spawn_Struct {
|
||||
/*0146*/ uint8 beardcolor; // Beard color
|
||||
/*0147*/ uint8 unknown0147[4];
|
||||
/*0151*/ uint8 level; // Spawn Level
|
||||
/*0152*/ uint8 unknown0259[4]; // ***Placeholder
|
||||
/*0152*/ uint32 PlayerState; // PlayerState controls some animation stuff
|
||||
/*0156*/ uint8 beard; // Beard style
|
||||
/*0157*/ char suffix[32]; // Player's suffix (of Veeshan, etc.)
|
||||
/*0189*/ uint32 petOwnerId; // If this is a pet, the spawn id of owner
|
||||
|
||||
@ -3005,7 +3005,7 @@ namespace UF
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown12
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown13
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown14 - Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->PlayerState);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown15
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown16
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown17
|
||||
|
||||
@ -286,7 +286,7 @@ struct Spawn_Struct
|
||||
/*0000*/ uint8 unknown12;
|
||||
/*0000*/ uint32 petOwnerId;
|
||||
/*0000*/ uint8 unknown13;
|
||||
/*0000*/ uint32 unknown14; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
||||
/*0000*/ uint32 PlayerState; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
|
||||
/*0000*/ uint32 unknown15;
|
||||
/*0000*/ uint32 unknown16;
|
||||
/*0000*/ uint32 unknown17;
|
||||
|
||||
@ -269,8 +269,8 @@ OP_RequestDuel=0x1ea9
|
||||
OP_MobRename=0x5040
|
||||
OP_AugmentItem=0x1627 # Was 0x37cb
|
||||
OP_WeaponEquip1=0x35c3
|
||||
OP_WeaponEquip2=0x012f # Was 0x6022
|
||||
OP_WeaponUnequip2=0x1076 # Was 0x0110
|
||||
OP_PlayerStateAdd=0x012f # Was 0x6022
|
||||
OP_PlayerStateRemove=0x1076 # Was 0x0110
|
||||
OP_ApplyPoison=0x1499
|
||||
OP_Save=0x2e6f
|
||||
OP_TestBuff=0x046e # Was 0x3772
|
||||
|
||||
@ -268,8 +268,8 @@ OP_RequestDuel=0x3af1
|
||||
OP_MobRename=0x2c57
|
||||
OP_AugmentItem=0x661b
|
||||
OP_WeaponEquip1=0x34a7
|
||||
OP_WeaponEquip2=0x559a
|
||||
OP_WeaponUnequip2=0x2d25
|
||||
OP_PlayerStateAdd=0x559a
|
||||
OP_PlayerStateRemove=0x2d25
|
||||
OP_ApplyPoison=0x31e6
|
||||
OP_Save=0x4a39
|
||||
OP_TestBuff=0x7cb8
|
||||
|
||||
@ -266,8 +266,8 @@ OP_RequestDuel=0x79e0 # C
|
||||
OP_MobRename=0x0a1d # C
|
||||
OP_AugmentItem=0x0370 # C
|
||||
OP_WeaponEquip1=0x719e # C
|
||||
OP_WeaponEquip2=0x7b6e # C
|
||||
OP_WeaponUnequip2=0x19a8 # C
|
||||
OP_PlayerStateAdd=0x7b6e # C
|
||||
OP_PlayerStateRemove=0x19a8 # C
|
||||
OP_ApplyPoison=0x405b # C
|
||||
OP_Save=0x5c85 # C
|
||||
OP_TestBuff=0x5fc7 # C
|
||||
|
||||
@ -262,8 +262,8 @@ OP_RequestDuel=0x3A2B #Xinu 02/22/09
|
||||
OP_MobRename=0x6be5 #Trevius 01/16/09
|
||||
OP_AugmentItem=0x172A #Trevius 03/14/09
|
||||
OP_WeaponEquip1=0x7260 #Trevius 02/27/09
|
||||
OP_WeaponEquip2=0x5C2F #Trevius 02/27/09
|
||||
OP_WeaponUnequip2=0x6213 #Trevius 02/27/09
|
||||
OP_PlayerStateAdd=0x5C2F #Trevius 02/27/09
|
||||
OP_PlayerStateRemove=0x6213 #Trevius 02/27/09
|
||||
OP_ApplyPoison=0x4543 #WildcardX 03/6/09
|
||||
OP_Save=0x72F2 #Trevius 03/15/09
|
||||
OP_TestBuff=0x07BF #/testbuff
|
||||
|
||||
@ -534,8 +534,8 @@ OP_PVPLeaderBoardDetailsRequest=0x06a2
|
||||
OP_PVPLeaderBoardDetailsReply=0x246a
|
||||
OP_PickLockSuccess=0x40E7
|
||||
OP_WeaponEquip1=0x6c5e
|
||||
OP_WeaponEquip2=0x63da
|
||||
OP_WeaponUnequip2=0x381d
|
||||
OP_PlayerStateAdd=0x63da
|
||||
OP_PlayerStateRemove=0x381d
|
||||
OP_VoiceMacroIn=0x2866 # Client to Server
|
||||
OP_VoiceMacroOut=0x2ec6 # Server to Client
|
||||
OP_CameraEffect=0x0937 # Correct
|
||||
|
||||
@ -272,8 +272,8 @@ OP_RequestDuel=0x6cfe # C
|
||||
OP_MobRename=0x0507 # C
|
||||
OP_AugmentItem=0x7c87 # C
|
||||
OP_WeaponEquip1=0x4572 # C
|
||||
OP_WeaponEquip2=0x399b # C
|
||||
OP_WeaponUnequip2=0x416b # C
|
||||
OP_PlayerStateAdd=0x399b # C
|
||||
OP_PlayerStateRemove=0x416b # C
|
||||
OP_ApplyPoison=0x5cd3 # C
|
||||
OP_Save=0x6618 # C
|
||||
OP_TestBuff=0x3415 # C
|
||||
|
||||
@ -305,6 +305,8 @@ void MapOpcodes()
|
||||
ConnectedOpcodes[OP_PetitionRefresh] = &Client::Handle_OP_PetitionRefresh;
|
||||
ConnectedOpcodes[OP_PetitionResolve] = &Client::Handle_OP_PetitionResolve;
|
||||
ConnectedOpcodes[OP_PetitionUnCheckout] = &Client::Handle_OP_PetitionUnCheckout;
|
||||
ConnectedOpcodes[OP_PlayerStateAdd] = &Client::Handle_OP_PlayerStateAdd;
|
||||
ConnectedOpcodes[OP_PlayerStateRemove] = &Client::Handle_OP_PlayerStateRemove;
|
||||
ConnectedOpcodes[OP_PickPocket] = &Client::Handle_OP_PickPocket;
|
||||
ConnectedOpcodes[OP_PopupResponse] = &Client::Handle_OP_PopupResponse;
|
||||
ConnectedOpcodes[OP_PotionBelt] = &Client::Handle_OP_PotionBelt;
|
||||
@ -381,8 +383,6 @@ void MapOpcodes()
|
||||
ConnectedOpcodes[OP_VetClaimRequest] = &Client::Handle_OP_VetClaimRequest;
|
||||
ConnectedOpcodes[OP_VoiceMacroIn] = &Client::Handle_OP_VoiceMacroIn;
|
||||
ConnectedOpcodes[OP_WearChange] = &Client::Handle_OP_WearChange;
|
||||
ConnectedOpcodes[OP_WeaponEquip2] = &Client::Handle_OP_WeaponEquip2;
|
||||
ConnectedOpcodes[OP_WeaponUnequip2] = &Client::Handle_OP_WeaponUnequip2;
|
||||
ConnectedOpcodes[OP_WhoAllRequest] = &Client::Handle_OP_WhoAllRequest;
|
||||
ConnectedOpcodes[OP_WorldUnknown001] = &Client::Handle_OP_Ignore;
|
||||
ConnectedOpcodes[OP_XTargetAutoAddHaters] = &Client::Handle_OP_XTargetAutoAddHaters;
|
||||
@ -10325,6 +10325,32 @@ void Client::Handle_OP_PetitionUnCheckout(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
|
||||
void Client::Handle_OP_PlayerStateAdd(const EQApplicationPacket *app)
|
||||
{
|
||||
if (app->size != sizeof(PlayerState_Struct)) {
|
||||
std::cout << "Wrong size: OP_PlayerStateAdd, size=" << app->size << ", expected " << sizeof(PlayerState_Struct) << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerState_Struct *ps = (PlayerState_Struct *)app->pBuffer;
|
||||
AddPlayerState(ps->state);
|
||||
|
||||
entity_list.QueueClients(this, app, false);
|
||||
}
|
||||
|
||||
void Client::Handle_OP_PlayerStateRemove(const EQApplicationPacket *app)
|
||||
{
|
||||
if (app->size != sizeof(PlayerState_Struct)) {
|
||||
std::cout << "Wrong size: OP_PlayerStateRemove, size=" << app->size << ", expected " << sizeof(PlayerState_Struct) << std::endl;
|
||||
return;
|
||||
}
|
||||
PlayerState_Struct *ps = (PlayerState_Struct *)app->pBuffer;
|
||||
RemovePlayerState(ps->state);
|
||||
|
||||
// We should probably save it server side, but for now this works
|
||||
entity_list.QueueClients(this, app, false);
|
||||
}
|
||||
|
||||
void Client::Handle_OP_PickPocket(const EQApplicationPacket *app)
|
||||
{
|
||||
if (app->size != sizeof(PickPocket_Struct))
|
||||
@ -13891,28 +13917,6 @@ void Client::Handle_OP_WearChange(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
|
||||
void Client::Handle_OP_WeaponEquip2(const EQApplicationPacket *app)
|
||||
{
|
||||
if (app->size != 8) {
|
||||
std::cout << "Wrong size: OP_WeaponEquip2, size=" << app->size << ", expected " << 8 << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// We should probably save it server side, but for now this works
|
||||
entity_list.QueueClients(this, app, false);
|
||||
}
|
||||
|
||||
void Client::Handle_OP_WeaponUnequip2(const EQApplicationPacket *app)
|
||||
{
|
||||
if (app->size != 8) {
|
||||
std::cout << "Wrong size: OP_WeaponUnequip2, size=" << app->size << ", expected " << 8 << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// We should probably save it server side, but for now this works
|
||||
entity_list.QueueClients(this, app, false);
|
||||
}
|
||||
|
||||
void Client::Handle_OP_WhoAllRequest(const EQApplicationPacket *app)
|
||||
{
|
||||
if (app->size != sizeof(Who_All_Struct)) {
|
||||
|
||||
@ -218,6 +218,8 @@
|
||||
void Handle_OP_PetitionRefresh(const EQApplicationPacket *app);
|
||||
void Handle_OP_PetitionResolve(const EQApplicationPacket *app);
|
||||
void Handle_OP_PetitionUnCheckout(const EQApplicationPacket *app);
|
||||
void Handle_OP_PlayerStateAdd(const EQApplicationPacket *app);
|
||||
void Handle_OP_PlayerStateRemove(const EQApplicationPacket *app);
|
||||
void Handle_OP_PickPocket(const EQApplicationPacket *app);
|
||||
void Handle_OP_PopupResponse(const EQApplicationPacket *app);
|
||||
void Handle_OP_PotionBelt(const EQApplicationPacket *app);
|
||||
@ -288,8 +290,6 @@
|
||||
void Handle_OP_VetClaimRequest(const EQApplicationPacket *app);
|
||||
void Handle_OP_VoiceMacroIn(const EQApplicationPacket *app);
|
||||
void Handle_OP_WearChange(const EQApplicationPacket *app);
|
||||
void Handle_OP_WeaponEquip2(const EQApplicationPacket *app);
|
||||
void Handle_OP_WeaponUnequip2(const EQApplicationPacket *app);
|
||||
void Handle_OP_WhoAllRequest(const EQApplicationPacket *app);
|
||||
void Handle_OP_XTargetAutoAddHaters(const EQApplicationPacket *app);
|
||||
void Handle_OP_XTargetRequest(const EQApplicationPacket *app);
|
||||
|
||||
@ -692,8 +692,8 @@ luabind::scope lua_register_packet_opcodes() {
|
||||
luabind::value("VetClaimRequest", static_cast<int>(OP_VetClaimRequest)),
|
||||
luabind::value("VetClaimReply", static_cast<int>(OP_VetClaimReply)),
|
||||
luabind::value("WeaponEquip1", static_cast<int>(OP_WeaponEquip1)),
|
||||
luabind::value("WeaponEquip2", static_cast<int>(OP_WeaponEquip2)),
|
||||
luabind::value("WeaponUnequip2", static_cast<int>(OP_WeaponUnequip2)),
|
||||
luabind::value("PlayerStateAdd", static_cast<int>(OP_PlayerStateAdd)),
|
||||
luabind::value("PlayerStateRemove", static_cast<int>(OP_PlayerStateRemove)),
|
||||
luabind::value("WorldLogout", static_cast<int>(OP_WorldLogout)),
|
||||
luabind::value("SessionReady", static_cast<int>(OP_SessionReady)),
|
||||
luabind::value("Login", static_cast<int>(OP_Login)),
|
||||
|
||||
@ -148,6 +148,7 @@ Mob::Mob(const char* in_name,
|
||||
size = in_size;
|
||||
base_size = size;
|
||||
runspeed = in_runspeed;
|
||||
PlayerState = 0;
|
||||
|
||||
|
||||
// sanity check
|
||||
@ -915,6 +916,7 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
|
||||
ns->spawn.class_ = class_;
|
||||
ns->spawn.gender = gender;
|
||||
ns->spawn.level = level;
|
||||
ns->spawn.PlayerState = PlayerState;
|
||||
ns->spawn.deity = deity;
|
||||
ns->spawn.animation = 0;
|
||||
ns->spawn.findable = findable?1:0;
|
||||
|
||||
@ -1026,6 +1026,11 @@ protected:
|
||||
uint32 follow_dist;
|
||||
bool no_target_hotkey;
|
||||
|
||||
uint32 PlayerState;
|
||||
uint32 GetPlayerState() { return PlayerState; }
|
||||
void AddPlayerState(uint32 new_state) { PlayerState |= new_state; }
|
||||
void RemovePlayerState(uint32 old_state) { PlayerState &= ~old_state; }
|
||||
|
||||
uint8 gender;
|
||||
uint16 race;
|
||||
uint8 base_gender;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user