Fix for OP_ZoneEntry spawn struct sometimes containing garbage data in flags causing random crashes.

This commit is contained in:
KimLS 2024-11-16 22:04:44 -08:00
parent 018308bfca
commit b85344f779
3 changed files with 65 additions and 61 deletions

View File

@ -1603,6 +1603,8 @@ namespace Larion
buffer.WriteUInt8(emu->NPC); buffer.WriteUInt8(emu->NPC);
structs::Spawn_Struct_Bitfields flags; structs::Spawn_Struct_Bitfields flags;
memset(&flags, 0, sizeof(structs::Spawn_Struct_Bitfields));
flags.gender = emu->gender; flags.gender = emu->gender;
flags.ispet = emu->is_pet; flags.ispet = emu->is_pet;
flags.afk = emu->afk; flags.afk = emu->afk;
@ -1626,7 +1628,10 @@ namespace Larion
} }
//write flags //write flags
buffer.WriteStructure(flags); //buffer.WriteStructure(flags);
for (int j = 0; j < 5; ++j) {
buffer.WriteUInt8(flags.raw[j]);
}
/* /*
float EmitterScalingRadius; float EmitterScalingRadius;
@ -1868,6 +1873,7 @@ namespace Larion
//u8 CPhysicsData[20]; //u8 CPhysicsData[20];
structs::Spawn_Struct_Position position; structs::Spawn_Struct_Position position;
memset(&position, 0, sizeof(structs::Spawn_Struct_Position));
position.y = emu->y; position.y = emu->y;
position.deltaZ = emu->deltaZ; position.deltaZ = emu->deltaZ;
@ -1879,7 +1885,10 @@ namespace Larion
position.animation = emu->animation; position.animation = emu->animation;
position.deltaY = emu->deltaY; position.deltaY = emu->deltaY;
buffer.WriteStructure(position); //buffer.WriteStructure(position);
for (int j = 0; j < 5; ++j) {
buffer.WriteUInt32(position.raw[j]);
}
/* /*
if(Flags.title) { if(Flags.title) {

View File

@ -193,58 +193,68 @@ 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 raw[5];
};
}; };
struct Spawn_Struct_Position struct Spawn_Struct_Position
{ {
signed y : 19; union {
signed deltaX : 13; struct {
signed y : 19;
signed deltaX : 13;
unsigned heading : 12; unsigned heading : 12;
signed z : 19; signed z : 19;
unsigned pad1 : 1; unsigned pad1 : 1;
unsigned pitch : 12; unsigned pitch : 12;
signed animation : 10; //these might be swapped signed animation : 10; //these might be swapped
signed deltaHeading : 10; //these might be swapped signed deltaHeading : 10; //these might be swapped
signed deltaY : 13; signed deltaY : 13;
signed deltaZ : 13; signed deltaZ : 13;
unsigned pad3 : 6; unsigned pad3 : 6;
signed x : 19; signed x : 19;
unsigned pad4 : 13; unsigned pad4 : 13;
};
uint32_t raw[5];
};
}; };

View File

@ -181,21 +181,6 @@ public:
m_pos += len; m_pos += len;
} }
template<typename T>
void WriteStructurePtr(T *value) {
auto type_size = sizeof(T);
if (m_pos + type_size > m_capacity)
Grow(m_capacity + type_size);
memcpy(m_buffer + m_pos, value, type_size);
m_pos += sizeof(type_size);
}
template<typename T>
void WriteStructure(T& value) {
WriteStructurePtr(&value);
}
size_t size() const { return m_pos; } size_t size() const { return m_pos; }
size_t length() const { return size(); } size_t length() const { return size(); }
size_t capacity() const { return m_capacity; } size_t capacity() const { return m_capacity; }