WIP Spawn struct, need to go confirm struct for cphysics

This commit is contained in:
KimLS 2024-11-15 22:52:52 -08:00
parent 200b7fa604
commit 2f46da5d99
2 changed files with 333 additions and 58 deletions

View File

@ -1063,10 +1063,12 @@ namespace Larion
//PcClient begin //PcClient begin
/* /*
u32 character_id; u32 character_id;
u32 character_id2; u16 world_id;
u16 reserved;
*/ */
out.WriteUInt32(emu->char_id); out.WriteUInt32(emu->char_id);
out.WriteUInt32(100); out.WriteUInt16(RuleI(World, Id));
out.WriteUInt16(0);
/*u32 name_length;*/ /*u32 name_length;*/
/*char name[name_length];*/ /*char name[name_length];*/
@ -1567,44 +1569,312 @@ namespace Larion
{ {
SpawnSize = 3; SpawnSize = 3;
} }
/*
char Name[];
u32 SpawnId;
u8 Level;
float MeleeRadius;
*/
buffer.WriteString(emu->name); buffer.WriteString(emu->name);
buffer.WriteUInt32(emu->spawnId); buffer.WriteUInt32(emu->spawnId);
buffer.WriteUInt8(emu->level); buffer.WriteUInt8(emu->level);
if (emu->DestructibleObject) //bounding radius: we should consider supporting this officially in the future if (emu->DestructibleObject) //bounding radius: we should consider supporting this officially in the future
{ {
buffer.WriteFloat(10.0f); buffer.WriteFloat(10.0f);
} }
else else
{ {
buffer.WriteFloat(SpawnSize - 0.7f); buffer.WriteFloat(SpawnSize - 0.7f);
} }
//buffer.WriteUInt32(0); //should be character id
//buffer.WriteUInt16(RuleI(World, Id)); //world id
//buffer.WriteUInt16(0); //reserved
//buffer.WriteUInt8(emu->NPC); //npc/player flag /*
EqGuid HashKey;
*/
buffer.WriteUInt32(emu->CharacterGuid.Id);
buffer.WriteUInt16(emu->CharacterGuid.WorldId);
buffer.WriteUInt16(0);
/*
u8 Type;
ActorFlags Flags;
*/
buffer.WriteUInt8(emu->NPC);
structs::Spawn_Struct_Bitfields flags;
flags.gender = emu->gender;
flags.ispet = emu->is_pet;
flags.afk = emu->afk;
flags.anon = emu->anon;
flags.gm = emu->gm;
flags.sneak = 0;
flags.lfg = emu->lfg;
flags.invis = emu->invis; //we need to implement this
flags.linkdead = 0; //on live I often see this as 1 for npcs, maybe consider adding this in the future
flags.showhelm = emu->showhelm;
flags.trader = emu->trader ? 1 : 0;
flags.targetable = 1;
flags.targetable_with_hotkey = emu->targetable_with_hotkey ? 1 : 0;
flags.showname = emu->show_name;
flags.buyer = emu->buyer ? 1 : 0;
flags.title = strlen(emu->title) > 0 ? 1 : 0;
flags.suffix = strlen(emu->suffix) > 0 ? 1 : 0;
if (emu->DestructibleObject || emu->class_ == Class::LDoNTreasure) {
flags.interactiveobject = 1;
}
//write flags
buffer.WriteUInt8(flags.data[0]);
buffer.WriteUInt8(flags.data[1]);
buffer.WriteUInt8(flags.data[2]);
buffer.WriteUInt8(flags.data[3]);
buffer.WriteUInt8(flags.data[4]);
/*
float EmitterScalingRadius;
s32 DefaultEmitterID;
*/
//we don't support this atm; wouldn't be hard to add I don't think
//RoF also supports this so might be worth implementing.
buffer.WriteFloat(1.0f);
buffer.WriteInt32(-1);
if (emu->DestructibleObject || emu->class_ == Class::LDoNTreasure)
{
/*
char InteractiveObjectModelName[];
char InteractiveObjectName[];
char InteractiveObjectOtherName[];
*/
buffer.WriteString(emu->DestructibleModel);
buffer.WriteString(emu->DestructibleName2);
buffer.WriteString(emu->DestructibleString);
/*
s32 CurrIOState;
s32 ObjectAnimationID;
*/
buffer.WriteUInt32(emu->DestructibleAppearance);
buffer.WriteUInt32(emu->DestructibleUnk1);
/*
s32 SoundId[10];
*/
buffer.WriteUInt32(emu->DestructibleID1);
buffer.WriteUInt32(emu->DestructibleID2);
buffer.WriteUInt32(emu->DestructibleID3);
buffer.WriteUInt32(emu->DestructibleID4);
buffer.WriteUInt32(emu->DestructibleUnk2);
buffer.WriteUInt32(emu->DestructibleUnk3);
buffer.WriteUInt32(emu->DestructibleUnk4);
buffer.WriteUInt32(emu->DestructibleUnk5);
buffer.WriteUInt32(emu->DestructibleUnk6);
buffer.WriteUInt32(emu->DestructibleUnk7);
/*
s8 Collidable;
s8 ObjectType;
*/
buffer.WriteUInt8(emu->DestructibleUnk8);
buffer.WriteUInt8(emu->DestructibleUnk9);
}
/*
u8 PropertyCount;
u32 Properties[PropertyCount];
*/
//We don't actually support multiple body types yet, but we should consider it in the future
if (!emu->DestructibleObject)
{
buffer.WriteUInt8(1);
buffer.WriteUInt32(emu->bodytype);
}
else
{
buffer.WriteUInt8(0);
}
/*
u8 HPCurrentPct;
*/
buffer.WriteUInt8(emu->curHp);
/*
s8 HairColor;
s8 FacialHairColor;
s8 EyeColor1;
s8 EyeColor2;
s8 HairStyle;
s8 FacialHair;
s32 Heritage;
s32 Tattoo;
s32 Details;
*/
buffer.WriteUInt8(emu->haircolor);
buffer.WriteUInt8(emu->beardcolor);
buffer.WriteUInt8(emu->eyecolor1);
buffer.WriteUInt8(emu->eyecolor2);
buffer.WriteUInt8(emu->hairstyle);
buffer.WriteUInt8(emu->beard);
buffer.WriteUInt32(emu->drakkin_heritage);
buffer.WriteUInt32(emu->drakkin_tattoo);
buffer.WriteUInt32(emu->drakkin_details);
/*
s8 TextureType;
s8 Material;
s8 Variation;
s8 HeadType;
*/
buffer.WriteUInt8(emu->equip_chest2);
buffer.WriteUInt8(0);
buffer.WriteUInt8(0);
buffer.WriteUInt8(emu->helm);
/*
float Height;
s8 FaceStyle;
float MyWalkSpeed;
float RunSpeed;
s32 Race;
*/
buffer.WriteFloat(emu->size);
buffer.WriteInt8(emu->face);
buffer.WriteFloat(emu->walkspeed);
buffer.WriteFloat(emu->runspeed);
buffer.WriteInt32(emu->race);
/*
u8 HoldingAnimation;
u32 Deity;
EqGuid GuildID;
u32 Class;
*/
buffer.WriteUInt8(0);
buffer.WriteUInt32(emu->deity);
if (emu->NPC) {
buffer.WriteInt32(-1);
buffer.WriteUInt32(0);
}
else { //guilds will probably need a ton of work
buffer.WriteUInt32(emu->guildID);
buffer.WriteUInt32(0);
}
buffer.WriteUInt32(emu->class_);
/*
u8 PvP;
u8 StandState;
u8 Light;
u8 GravityBehavior;
*/
buffer.WriteUInt8(0);
buffer.WriteUInt8(emu->StandState);
buffer.WriteUInt8(emu->light);
buffer.WriteUInt8(emu->flymode);
/*
char LastName[];
*/
buffer.WriteString(emu->lastName);
/*
u8 bGuildShowAnim;
u8 bTempPet;
u32 MasterID;
u8 FindBits;
*/
buffer.WriteUInt8(emu->guild_show);
buffer.WriteUInt8(0);
buffer.WriteUInt32(emu->petOwnerId);
buffer.WriteUInt8(0);
/*
u32 PlayerState;
u32 NpcTintIndex;
u32 PrimaryTintIndex;
u32 SecondaryTintIndex;
*/
buffer.WriteUInt32(emu->PlayerState);
buffer.WriteUInt32(0);
buffer.WriteUInt32(0);
buffer.WriteUInt32(0);
/*
u32 EncounterLockState;
u64 LockID;
*/
buffer.WriteUInt32(0);
buffer.WriteUInt64(0);
//u32 SeeInvis[3];
if (emu->NPC) {
buffer.WriteUInt32(0);
buffer.WriteUInt32(0);
buffer.WriteUInt32(0);
}
if ((emu->NPC == 0) || (emu->race <= Race::Gnome) || (emu->race == Race::Iksar) ||
(emu->race == Race::VahShir) || (emu->race == Race::Froglok2) || (emu->race == Race::Drakkin)
)
{
/*
u32 ArmorColor[9];
*/
for (int k = EQ::textures::textureBegin; k < EQ::textures::materialCount; ++k)
{
buffer.WriteUInt32(emu->equipment_tint.Slot[k].Color);
}
/*
Armor Armor[9];
*/
for (int k = EQ::textures::textureBegin; k < EQ::textures::materialCount; k++) {
buffer.WriteUInt32(emu->equipment.Slot[k].Material);
buffer.WriteUInt32(emu->equipment.Slot[k].Unknown1);
buffer.WriteUInt32(emu->equipment.Slot[k].EliteModel);
buffer.WriteUInt32(emu->equipment.Slot[k].HerosForgeModel);
buffer.WriteUInt32(emu->equipment.Slot[k].Unknown2);
}
}
else
{
//Armor Armor[3];
buffer.WriteUInt32(0);
buffer.WriteUInt32(0);
buffer.WriteUInt32(0);
buffer.WriteUInt32(0);
buffer.WriteUInt32(0);
buffer.WriteUInt32(emu->equipment.Primary.Material);
buffer.WriteUInt32(0);
buffer.WriteUInt32(0);
buffer.WriteUInt32(0);
buffer.WriteUInt32(0);
buffer.WriteUInt32(emu->equipment.Secondary.Material);
buffer.WriteUInt32(0);
buffer.WriteUInt32(0);
buffer.WriteUInt32(0);
buffer.WriteUInt32(0);
}
//u8 CPhysicsData[20];
//structs::Spawn_Struct_Bitfields flags;
//flags.gender = emu->gender;
//flags.gender = emu->gender;
//flags.ispet = emu->is_pet;
//flags.afk = emu->afk;
//flags.anon = emu->anon;
//flags.gm = emu->gm;
//flags.sneak = 0;
//flags.lfg = emu->lfg;
//flags.invis = emu->invis;
//flags.linkdead = 0;
//flags.showhelm = emu->showhelm;
//flags.trader = emu->trader ? 1 : 0;
//flags.targetable = 1;
//flags.targetable_with_hotkey = emu->targetable_with_hotkey ? 1 : 0;
//flags.showname = emu->show_name;
} }
} }
// DECODE methods // DECODE methods

View File

@ -193,37 +193,42 @@ namespace Larion {
struct Spawn_Struct_Bitfields struct Spawn_Struct_Bitfields
{ {
// byte 1 union {
/*00*/ unsigned gender : 2; // Gender (0=male, 1=female, 2=monster) struct {
/*02*/ unsigned ispet : 1; // Guessed based on observing live spawns // byte 1
/*03*/ unsigned afk : 1; // 0=no, 1=afk /*00*/ unsigned gender : 2; // Gender (0=male, 1=female, 2=monster)
/*04*/ unsigned anon : 2; // 0=normal, 1=anon, 2=roleplay /*02*/ unsigned ispet : 1; // Guessed based on observing live spawns
/*06*/ unsigned gm : 1; /*03*/ unsigned afk : 1; // 0=no, 1=afk
/*07*/ unsigned sneak : 1; /*04*/ unsigned anon : 2; // 0=normal, 1=anon, 2=roleplay
// byte 2 /*06*/ unsigned gm : 1;
/*08*/ unsigned lfg : 1; /*07*/ unsigned sneak : 1;
/*09*/ unsigned unk9 : 1; // byte 2
/*10*/ unsigned invis : 12; // there are 3000 different (non-GM) invis levels /*08*/ unsigned lfg : 1;
/*22*/ unsigned linkdead : 1; // 1 Toggles LD on or off after name. Correct for RoF2 /*09*/ unsigned unk9 : 1;
/*23*/ unsigned showhelm : 1; /*10*/ unsigned invis : 12; // there are 3000 different (non-GM) invis levels
// byte 4 /*22*/ unsigned linkdead : 1; // 1 Toggles LD on or off after name. Correct for RoF2
/*24*/ unsigned betabuffed : 1; // Prefixes name with ! /*23*/ unsigned showhelm : 1;
/*25*/ unsigned trader : 1; // byte 4
/*26*/ unsigned animationonpop : 1; /*24*/ unsigned betabuffed : 1; // Prefixes name with !
/*27*/ unsigned targetable : 1; /*25*/ unsigned trader : 1;
/*28*/ unsigned targetable_with_hotkey : 1; /*26*/ unsigned animationonpop : 1;
/*29*/ unsigned showname : 1; /*27*/ unsigned targetable : 1;
/*30*/ unsigned idleanimationsoff : 1; // what we called statue? /*28*/ unsigned targetable_with_hotkey : 1;
/*31*/ unsigned untargetable : 1; // bClickThrough /*29*/ unsigned showname : 1;
// byte 5 /*30*/ unsigned idleanimationsoff : 1; // what we called statue?
/*32*/ unsigned buyer : 1; /*31*/ unsigned untargetable : 1; // bClickThrough
/*33*/ unsigned offline : 1; // byte 5
/*34*/ unsigned interactiveobject : 1; /*32*/ unsigned buyer : 1;
/*35*/ unsigned missile : 1; /*33*/ unsigned offline : 1;
/*36*/ unsigned title : 1; /*34*/ unsigned interactiveobject : 1;
/*37*/ unsigned suffix : 1; /*35*/ unsigned missile : 1;
/*38*/ unsigned unk38 : 1; /*36*/ unsigned title : 1;
/*39*/ unsigned unk39 : 1; /*37*/ unsigned suffix : 1;
/*38*/ unsigned unk38 : 1;
/*39*/ unsigned unk39 : 1;
};
uint8_t data[5];
};
}; };
#pragma pack() #pragma pack()