#pragma once
#include <cstdint>

// ============================================================================
// Offsets.h — DayZ Enfusion engine memory offsets
//
// Verification log (update whenever you confirm offsets against a live client):
//
//   DayZ 1.29 | 2026-06-13
//     Base::*              — SigScanner-scanned; patterns in SigScanner.cpp
//     World::*             — live-debugged via Spectre stable
//     Common::*, Network::* — live-debugged; cross-checked with C# port
//     Player::*, Inventory::* — live-debugged; SigScanner covers IsDead/Inventory
//     Skeleton::*          — animClass/matrixClass probed at runtime (see cands)
//
// When the game patches, update the SigScanner patterns first (they cover the
// most volatile offsets).  Hard-coded offsets that the scanner does NOT cover
// are marked [manual] and must be verified by hand after each patch.
// ============================================================================

namespace Offsets {

    // [manual] Module-relative RVAs — also covered by SigScanner (World, NetworkManager)
    namespace Base {
        constexpr uint64_t World              = 0x4264028;  // v1.29
        constexpr uint64_t NetworkManager     = 0x100FC10;  // v1.29
        constexpr uint64_t Tick               = 0xFF4998;   // v1.29 [manual]
        constexpr uint64_t Fov                = 0x100A7D8;  // v1.29 [manual]
    }

    // World struct member offsets — also covered by SigScanner
    namespace World {
        constexpr uint64_t NearEntityList     = 0xF48;   // v1.29
        constexpr uint64_t NearTableSize      = 0xF50;   // v1.29
        constexpr uint64_t FarEntityList      = 0x1090;  // v1.29
        constexpr uint64_t FarTableSize       = 0x1098;  // v1.29
        constexpr uint64_t SlowEntityList     = 0x2010;  // v1.29 [manual]
        constexpr uint64_t SlowTableAllocCount= 0x2018;  // v1.29 [manual]
        constexpr uint64_t SlowTableValidCount= 0x1FA0;  // v1.29 [manual]
        constexpr uint64_t LocalPlayer        = 0x2960;  // v1.29 [manual]
        constexpr uint64_t ItemList           = 0x2060;  // v1.29
        constexpr uint64_t ItemTableAllocCount= 0x2068;  // v1.29
        constexpr uint64_t ItemTableValidCount= 0x2070;  // v1.29
        constexpr uint64_t BulletTable        = 0xE00;   // v1.29
        constexpr uint64_t BulletCount        = 0xE08;   // v1.29
        constexpr uint64_t Camera             = 0x1B8;   // v1.29 [manual]
    }

    // [manual] Common entity struct offsets — VisualState also covered by SigScanner
    namespace Common {
        constexpr uint64_t Item               = 0x18;   // v1.29
        constexpr uint64_t Path               = 0xB0;   // v1.29
        constexpr uint64_t Size               = 0x8;    // v1.29
        constexpr uint64_t Type               = 0x180;  // v1.29
        constexpr uint64_t VisualState        = 0x1C8;  // v1.29
        constexpr uint64_t FutureVisualState  = 0x120;  // v1.29 [manual]
        constexpr uint64_t DirectionX         = 0x20;   // v1.29 [manual]
        constexpr uint64_t DirectionY         = 0x28;   // v1.29 [manual]
        constexpr uint64_t Position           = 0x2C;   // v1.29 [manual]
    }

    // [manual] Network manager struct offsets
    namespace Network {
        constexpr uint64_t ManagerNetworkClient      = 0x50;   // v1.29
        constexpr uint64_t EntityNetworkId           = 0x6DC;  // v1.29
        constexpr uint64_t ClientScoreboard          = 0x18;   // v1.29
        constexpr uint64_t ClientPlayerCount         = 0x24;   // v1.29
        constexpr uint64_t ClientPlayerIdentitySize  = 0x170;  // v1.29
        constexpr uint64_t PlayerIdentityNetworkId   = 0x30;   // v1.29
        constexpr uint64_t PlayerIdentitySteamId     = 0xA0;   // v1.29
        constexpr uint64_t PlayerIdentityPlayerName  = 0xF8;   // v1.29
        constexpr uint64_t PlayerCount               = 0x24;   // v1.29
        constexpr uint64_t ServerName                = 0x308;  // v1.29 [manual]
        constexpr uint64_t GameVersion               = 0x350;  // v1.29 [manual]
        constexpr uint64_t MapName                   = 0x38;   // v1.29 [manual]
        constexpr uint64_t ThirdPerson               = 0x9C;   // v1.29 [manual]
        constexpr uint64_t Crosshair                 = 0xA0;   // v1.29 [manual]
    }

    // [manual] Entity type object offsets
    namespace EntityType {
        constexpr uint64_t ModelName          = 0xB0;   // v1.29
        constexpr uint64_t ConfigName         = 0x98;   // v1.29
        constexpr uint64_t TypeName           = 0xD0;   // v1.29
        constexpr uint64_t CleanName          = 0x518;  // v1.29
    }

    // [manual] Camera struct offsets (relative to World::Camera pointer target)
    namespace Camera {
        constexpr uint64_t InvertedViewRight   = 0x8;   // v1.29
        constexpr uint64_t InvertedViewUp      = 0x14;  // v1.29
        constexpr uint64_t InvertedViewForward = 0x20;  // v1.29
        constexpr uint64_t Translation         = 0x2C;  // v1.29
        constexpr uint64_t ViewPortSize        = 0x58;  // v1.29
        constexpr uint64_t ProjectionD1        = 0xD0;  // v1.29
        constexpr uint64_t ProjectionD2        = 0xDC;  // v1.29
    }

    namespace CameraFov {
        // Camera FOV offsets (derived from Base::Fov)
        // Populated as needed; base offset is Base::Fov
    }

    // Player entity struct offsets — IsDead/Inventory also covered by SigScanner
    namespace Player {
        constexpr uint64_t Skeleton           = 0x7E0;  // v1.29 [manual]; alt: 0x810 (external source)
        constexpr uint64_t InputController    = 0x7E8;  // v1.29 [manual]
        constexpr uint64_t IsDead             = 0xE2;   // v1.29
        constexpr uint64_t EntityDead         = 0x15D;  // v1.29 [manual]
        // TODO: verify health offset for current game version.
        // Set to 0 to disable health reading; set to the correct entity offset
        // for a float in the range 0..100 once confirmed via RE.
        constexpr uint64_t Health             = 0x0;
    }

    namespace Infected {
        // Infected share common entity offsets; extend here as needed
        // Skeleton pointer: see Skeleton::ZombieCand
    }

    // Inventory struct offsets — Base/Hands also covered by SigScanner
    namespace Inventory {
        constexpr uint64_t Base               = 0x650;  // v1.29
        constexpr uint64_t ItemQuality        = 0x194;  // v1.29 [manual]
        constexpr uint64_t Hands              = 0x1B0;  // v1.29
        constexpr uint64_t HandItemValid      = 0x1CC;  // v1.29 [manual]
        constexpr uint64_t WornClothes        = 0x150;  // v1.29 [manual] — ptr to weared-clothes grid object
        constexpr uint64_t PlayerCargoGrid    = 0x150;  // alias kept for compatibility
        constexpr uint64_t CargoGridCount     = 0xC;    // v1.29 [manual] — uint32 count at grid+0xC
        constexpr uint64_t ItemPtr            = 0x8;    // v1.29 [manual] — ptr to items array at grid+0x8
        constexpr uint64_t ItemSize           = 0x10;   // v1.29 [manual] — stride per item slot (16 bytes)
    }

    namespace SlowTable {
        constexpr uint64_t EntrySize          = 0x18;  // v1.29
        constexpr uint64_t EntryPointerOffset = 0x8;   // v1.29
    }

    namespace Skeleton {
        // Entity → skeleton pointer offset candidates (probed at runtime, first match wins).
        // v1.29 confirmed: player=0x7E0, zombie=0x670.
        // External source (unknown version): player=0x810, zombie=0x680.
        constexpr uint64_t PlayerCand[2] = { 0x7E0, 0x810 };
        constexpr uint64_t ZombieCand[2] = { 0x670, 0x680 };

        // Convenience aliases (first candidate = last-known-good).
        constexpr uint64_t PlayerOffset = PlayerCand[0];
        constexpr uint64_t ZombieOffset = ZombieCand[0];

        // Probed candidates: skeleton → animClass pointer (tried in order).
        // 0x118 confirmed v1.29 (Spectre stable); 0xA8 confirmed by external source.
        constexpr uint64_t AnimCand[4]   = { 0x118, 0xA8, 0x98, 0xB0 };

        // Probed candidates: animClass → matrixArray pointer (tried in order).
        // 0xBE8 confirmed v1.29 (Spectre stable); 0xBF0 confirmed by external source.
        constexpr uint64_t MatrixCand[5] = { 0xBE8, 0xBF0, 0xBD8, 0xB40, 0xB30 };

        // Each bone entry is 48 bytes; translation (x,y,z) starts at byte offset 0x54
        // from the matrixArray base (effective: matrixArray + 0x54 + boneIndex*0x30).
        // This gives boneIndex N the same world position as their boneIndex N+1
        // (the +0x54 vs +0x24 difference is exactly one stride).
        constexpr uint32_t BoneStride            = 48;    // v1.29
        constexpr uint32_t BoneTranslationOffset = 0x54;  // v1.29
    }

} // namespace Offsets
