feat(combat): Phase L.1c wire live attack input
This commit is contained in:
parent
d1fb68f419
commit
4874d8595a
6 changed files with 367 additions and 11 deletions
|
|
@ -25,13 +25,13 @@ namespace AcDream.Core.Net.Messages;
|
|||
/// </list>
|
||||
///
|
||||
/// <para>
|
||||
/// All other fields (weenie header, object description, motion tables,
|
||||
/// Most other fields (extended weenie header, object description, motion tables,
|
||||
/// palettes, texture overrides, animation frames, velocity, ...) are
|
||||
/// consumed-but-ignored so the parse position ends up wherever the
|
||||
/// client-side caller wanted — a <c>Parse</c> call doesn't need to reach
|
||||
/// the end of the body to return useful output. We stop after PhysicsData
|
||||
/// since that's the last segment containing fields acdream cares about
|
||||
/// in this phase.
|
||||
/// the end of the body to return useful output. We read through the fixed
|
||||
/// WeenieHeader prefix for Name/ItemType, then stop before optional header
|
||||
/// tails.
|
||||
/// </para>
|
||||
///
|
||||
/// <para>
|
||||
|
|
@ -51,6 +51,8 @@ public static class CreateObject
|
|||
public const uint PaletteTypePrefix = 0x04000000u;
|
||||
/// <summary>SurfaceTexture dat id type prefix.</summary>
|
||||
public const uint SurfaceTextureTypePrefix = 0x05000000u;
|
||||
/// <summary>Icon dat id type prefix.</summary>
|
||||
public const uint IconTypePrefix = 0x06000000u;
|
||||
|
||||
[Flags]
|
||||
public enum PhysicsDescriptionFlag : uint
|
||||
|
|
@ -78,9 +80,9 @@ public static class CreateObject
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// The three fields acdream cares about. Position and SetupTableId are
|
||||
/// nullable because their corresponding physics-description-flag bits
|
||||
/// may not be set on every CreateObject.
|
||||
/// The spawn fields acdream currently cares about. Position and
|
||||
/// SetupTableId are nullable because their corresponding
|
||||
/// physics-description-flag bits may not be set on every CreateObject.
|
||||
/// </summary>
|
||||
public readonly record struct Parsed(
|
||||
uint Guid,
|
||||
|
|
@ -92,6 +94,7 @@ public static class CreateObject
|
|||
uint? BasePaletteId,
|
||||
float? ObjScale,
|
||||
string? Name,
|
||||
uint? ItemType,
|
||||
ServerMotionState? MotionState,
|
||||
uint? MotionTableId,
|
||||
ushort InstanceSequence = 0,
|
||||
|
|
@ -390,27 +393,39 @@ public static class CreateObject
|
|||
pos += 9 * 2;
|
||||
AlignTo4(ref pos);
|
||||
|
||||
// --- WeenieHeader: read just the Name field (second after flags). ---
|
||||
// --- WeenieHeader: read the fixed prefix fields we need. ---
|
||||
// ACE WorldObject_Networking.SerializeCreateObject writes:
|
||||
// weenieFlags, Name, WeenieClassId(PackedDword),
|
||||
// IconId(PackedDwordOfKnownType 0x06000000), ItemType,
|
||||
// ObjectDescriptionFlags, align.
|
||||
string? name = null;
|
||||
uint? itemType = null;
|
||||
if (body.Length - pos >= 4)
|
||||
{
|
||||
pos += 4; // skip weenieFlags u32
|
||||
try
|
||||
{
|
||||
name = ReadString16L(body, ref pos);
|
||||
_ = ReadPackedDword(body, ref pos); // WeenieClassId
|
||||
_ = ReadPackedDwordOfKnownType(body, ref pos, IconTypePrefix);
|
||||
if (body.Length - pos >= 4)
|
||||
itemType = ReadU32(body, ref pos);
|
||||
if (body.Length - pos >= 4)
|
||||
_ = ReadU32(body, ref pos); // ObjectDescriptionFlags
|
||||
AlignTo4(ref pos);
|
||||
}
|
||||
catch { /* truncated name — partial result is still useful */ }
|
||||
}
|
||||
|
||||
return new Parsed(guid, position, setupTableId, animParts,
|
||||
textureChanges, subPalettes, basePaletteId, objScale, name, motionState, motionTableId,
|
||||
textureChanges, subPalettes, basePaletteId, objScale, name, itemType, motionState, motionTableId,
|
||||
instanceSeq, teleportSeq, serverControlSeq, forcePositionSeq);
|
||||
|
||||
// Local helper: if we ran out of fields past PhysicsData, still
|
||||
// return the useful prefix (guid/position/setup/animParts/textures/palettes/scale/motion).
|
||||
Parsed PartialResult() => new(
|
||||
guid, position, setupTableId, animParts,
|
||||
textureChanges, subPalettes, basePaletteId, objScale, null, motionState, motionTableId);
|
||||
textureChanges, subPalettes, basePaletteId, objScale, null, null, motionState, motionTableId);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ public sealed class WorldSession : IDisposable
|
|||
uint? BasePaletteId,
|
||||
float? ObjScale,
|
||||
string? Name,
|
||||
uint? ItemType,
|
||||
CreateObject.ServerMotionState? MotionState,
|
||||
uint? MotionTableId);
|
||||
|
||||
|
|
@ -635,6 +636,7 @@ public sealed class WorldSession : IDisposable
|
|||
parsed.Value.BasePaletteId,
|
||||
parsed.Value.ObjScale,
|
||||
parsed.Value.Name,
|
||||
parsed.Value.ItemType,
|
||||
parsed.Value.MotionState,
|
||||
parsed.Value.MotionTableId));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue