Skip to content

🏥 AFU.Status

AFU.Status เป็นระบบจัดการสถานะของผู้เล่นสำหรับ FiveM เช่น ความหิว, ความกระหาย, ความเครียด, พลังงาน หรือค่าอื่นๆ ที่ต้องการติดตาม โดยมีประสิทธิภาพสูง (High Performance) ปรับแต่งได้ตามต้องการ รองรับระบบ Free Zone, ระบบอาหารและเครื่องดื่ม, ระบบสิทธิพิเศษ (Privilege System / Options) และมี Public Exports ครบถ้วนสำหรับการพัฒนา UI หรือเชื่อมต่อกับระบบอื่น

ข้อมูลสคริปต์

  • Framework: ESX (es_extended)
  • Dependencies (จำเป็น):
    • oxmysqlบังคับ (ต้อง start ก่อน)
    • es_extendedบังคับ
  • Dependencies (ทางเลือก):
    • AFU.Notify — แนะนำ (ใช้แสดงการแจ้งเตือนเมื่อค่าสถานะเปลี่ยนแปลง)
  • เวอร์ชัน: 1.0.1+ · fx_version cerulean · lua54
  • Performance (ประสิทธิภาพ):
    • Server: 0.00 ~ 0.01 ms
    • Client: 0.00 ~ 0.01 ms (หากเปิดใช้ UI จะเป็น 0.00 ~ 0.06 ms)

⚠️ ต้องใช้ License Token

สคริปต์นี้มีระบบตรวจสอบ License ผู้ซื้อต้องมี Token ที่ถูกต้อง และตั้งค่าใน server.cfg ก่อนเสมอ หากไม่มี Token ที่ถูกต้อง Resource จะไม่ทำงาน

ซื้อ Token ได้ที่ awayfromus.store (หรือ awayfromus.dev)


🛠️ Installation

1. Download & Placement

นำ Resource ไปวางในโฟลเดอร์ resources/ ของเซิร์ฟเวอร์:

text
resources/
└── [afu]/
    ├── AFU.Status/
    │   ├── config/
    │   │   ├── core/
    │   │   │   ├── status.lua       (ตั้งค่าสถานะ เช่น hunger, thirst, stress)
    │   │   │   ├── foods.lua        (ตั้งค่ารายการอาหาร เครื่องดื่ม แอนิเมชัน พร็อพ)
    │   │   │   └── options.lua      (ตั้งค่าสิทธิพิเศษ เช่น Admin, VIP, อาชีพ)
    │   │   └── free.zone.lua        (ตั้งค่าพื้นที่ปลอดภัย Free Zone)
    │   ├── nui/                     (UI แสดงค่าสถานะ)
    │   ├── source/                  (ไฟล์หลักระบบ)
    │   └── fxmanifest.lua
    └── AFU.Notify/

ห้ามเปลี่ยนชื่อโฟลเดอร์

ต้องตั้งชื่อโฟลเดอร์ว่า AFU.Status ตามตัวอย่าง ชื่อต้องมีจุด (.) ตรงตามนี้เสมอ เพราะระบบเรียกใช้งานผ่านชื่อ Resource จากสคริปต์อื่น เช่น exports['AFU.Status'] หากเปลี่ยนชื่อ Command และ Export ทั้งหมดจะไม่ทำงาน

2. Dependencies

ตรวจสอบและติดตั้ง Resource ที่จำเป็นก่อน Start:

  • oxmysqlบังคับ (ต้อง start ก่อนเสมอ)
  • es_extendedบังคับ (ต้อง start ก่อนเสมอ)
  • AFU.Notify — แนะนำ สำหรับระบบแจ้งเตือน

3. server.cfg

เพิ่มบรรทัดต่อไปนี้ใน server.cfg:

cfg
# License Token (จำเป็น) — รับจากระบบ Orders ของ awayfromus.store
set afu_license "YOUR_TOKEN_HERE"

# ลำดับการ start ที่ถูกต้อง
ensure oxmysql
ensure es_extended
ensure AFU.Notify
ensure AFU.Status

ลำดับการ Start สำคัญมาก

  • oxmysql และ es_extended ต้อง start ก่อน AFU.Status เสมอ
  • หากไม่ใส่ set afu_license สคริปต์จะไม่ทำงาน

✨ ความสามารถหลัก (Core Features)

🔄 ระบบสถานะแบบไดนามิก (Dynamic Status System)

  • กำหนดสถานะได้ไม่จำกัด — สามารถเพิ่มสถานะใหม่ได้ง่ายๆ เช่น ความหิว, ความกระหาย, ความเครียด, ความสุข, พลังงาน ฯลฯ
  • ลดค่าตามเวลา — สถานะแต่ละประเภทจะลดลงหรือเพิ่มขึ้นอัตโนมัติตามเวลาที่กำหนด (Tick)
  • บันทึกค่าอัตโนมัติ — ซิงค์และบันทึกสถานะทั้งหมดลงฐานข้อมูลเมื่อผู้เล่นออกจากเซิร์ฟเวอร์
  • กำหนดเงื่อนไขผลกระทบ — เช่น เมื่อความหิวน้อยกว่า 20% จะเริ่มลดเลือดของผู้เล่น

🌈 ระบบ Free Zone (Free Zone System)

  • โซนพิเศษไม่มีผลกระทบ — กำหนดพื้นที่พิเศษที่สถานะต่างๆ จะไม่มีผลกระทบต่อผู้เล่น
  • กำหนดสถานะอิสระได้ — เลือกได้ว่าสถานะใดบ้างที่จะไม่ส่งผลกระทบในโซนนี้ เช่น ไม่หิว ไม่กระหาย หรือไม่เครียด
  • รองรับหลายโซน — สามารถกำหนดได้หลายโซนในแผนที่
  • ระบบการตรวจจับอัตโนมัติ — ระบบจะตรวจจับเมื่อผู้เล่นเข้า-ออกพื้นที่ Free Zone โดยอัตโนมัติ
  • โหมดดีบัก — มีโหมดดีบักแสดงขอบเขตของ Free Zone เพื่อช่วยในการตั้งค่าพิกัด

🍔 ระบบอาหารและเครื่องดื่ม (Food and Drink System)

  • กำหนดไอเทมอาหารหลากหลาย — สามารถเพิ่มอาหารและเครื่องดื่มได้ไม่จำกัด
  • ผลกระทบหลายสถานะ — อาหาร 1 ชิ้นสามารถมีผลกระทบกับหลายสถานะพร้อมกัน (เช่น กาแฟ เพิ่มพลังงานแต่ลดความกระหาย)
  • แอนิเมชันแบบกำหนดเอง — กำหนดท่าทางการกิน/ดื่มของอาหารแต่ละประเภทได้
  • พร็อพประกอบการกิน — แสดงโมเดลอาหารหรือแก้วน้ำในมือขณะกิน
  • กำหนดพื้นที่สำหรับกินอาหาร — สามารถตั้งค่าให้อาหารบางชนิดกินได้เฉพาะในพื้นที่ที่กำหนด
  • จำกัดอาชีพการกินอาหาร — รองรับการจำกัดอาหารบางประเภทให้เฉพาะอาชีพที่กำหนด

👑 ระบบสิทธิพิเศษ (Privilege System / Options)

  • สิทธิพิเศษแอดมิน — แอดมินมีสิทธิ์พิเศษสามารถกินอาหารได้ทุกประเภท อมตะ หรือไม่ลดค่าสถานะ
  • สิทธิพิเศษ VIP — ผู้เล่น VIP ได้รับสิทธิประโยชน์ เช่น สถานะลดช้ากว่าผู้เล่นทั่วไป หรือกินอาหารได้ทุกพื้นที่
  • ระบบตรวจสอบสิทธิ์ — ตรวจสอบสิทธิ์ผู้เล่นแต่ละประเภทอัตโนมัติ (ผ่าน job หรือไอเทม VIP)

🛡️ ระบบความปลอดภัย (Security System)

  • ตรวจสอบการโกง — ป้องกันการสแปมด้วยระบบตรวจสอบระยะเวลาในการกินอาหาร
  • บันทึกกิจกรรมผู้เล่น — บันทึกประวัติการใช้อาหารและการเปลี่ยนแปลงสถานะ
  • ตรวจสอบค่าผิดปกติ — ระบบตรวจสอบค่าสถานะที่ผิดปกติ ป้องกันการฉีดโค้ด

🖥️ ระบบ UI (User Interface)

  • UI แบบติดตัว — แสดงค่าสถานะแบบบาร์ด้านข้างหน้าจอ
  • ปรับแต่งได้สมบูรณ์ — สามารถเปิด/ปิด UI เดิม หรือสร้าง UI ของตัวเองโดยใช้ Exports getSharedObject()
  • การแจ้งเตือน — แจ้งเตือนเมื่อค่าสถานะวิกฤตผ่าน AFU.Notify

ตัวอย่างการใช้ getSharedObject สำหรับ UI แบบกำหนดเอง

lua
-- ดึงข้อมูล Object หลักของระบบสถานะ (Client Side)
local afuStatus = exports["AFU.Status"]:getSharedObject()

-- ตัวอย่างการนำไปใช้สร้าง UI แบบกำหนดเอง
Citizen.CreateThread(function()
    while true do
        Citizen.Wait(500) -- อัพเดททุก 500ms

        -- ดึงข้อมูลสถานะปัจจุบัน
        local hungerStatus = afuStatus.GetPlayerStatus("hunger")
        local happinessStatus = afuStatus.GetPlayerStatus("happiness")

        if hungerStatus and happinessStatus then
            -- คำนวณเปอร์เซ็นต์ (0-100)
            local hungerPercent = hungerStatus.getPercent()
            local happinessPercent = happinessStatus.getPercent()

            -- ส่งข้อมูลไปยัง NUI (UI ที่คุณสร้างขึ้น)
            SendNUIMessage({
                type = "updateStatus",
                hunger = hungerPercent,
                happiness = happinessPercent,
                hungerLabel = hungerStatus.label,
                happinessLabel = happinessStatus.label
            })
        end
    end
end)

⚙️ Configuration

1. การเพิ่มสถานะใหม่ (config/core/status.lua)

คุณสามารถเพิ่มสถานะใหม่ได้อย่างอิสระ ตัวอย่างเช่น:

lua
{
    Name = "energy",
    Label = "พลังงาน",
    Icon = 'assets/EnergyIcon.svg',
    Default = 500,
    Max = 1000,
    Tick = {
        Every = 2 * Time.Minute,
        Value = -25,
        onTick = function(status)
            if status.value <= 100 then
                -- ใส่โค้ดหรือเอฟเฟกต์เมื่อพลังงานเหลือน้อย
            end
        end
    },
    UseOptionPresets = {
        OptionsEnum.ByPassAdmin,
    }
}

2. การเพิ่มอาหารและเครื่องดื่ม (config/core/foods.lua)

เพิ่มไอเทมอาหารหรือเครื่องดื่มใหม่ พร้อมแอนิเมชันและโมเดลพร็อพ:

lua
["coffee"] = {
    status = {
        {
            name = "energy",
            value = 150
        },
        {
            name = "thirst",
            value = -50
        }
    },
    restrictJobs = {},
    anim = {
        flag = 49,
        dict = 'mp_player_intdrink',
        clip = 'loop_bottle',
        duration = 4 * Time.Second
    },
    prop = {
        model = "p_amb_coffeecup_01",
        bone = 18905,
        pos = vector3(0.13, 0.02, 0.08),
        rot = vector3(270.0, 0.0, 0.0)
    }
}

3. การตั้งค่าสิทธิพิเศษ (config/core/options.lua)

กำหนดค่า Preset สำหรับกลุ่มผู้เล่นพิเศษ (เช่น แอดมิน, VIP, หรือตำรวจ):

lua
OptionsEnum = {
    ByPassAdmin = 1,
    ByPassVIP = 2,
    ByPassPolice = 3,  -- เพิ่มสิทธิพิเศษใหม่
}

OptionPresets = {
    [OptionsEnum.ByPassPolice] = {
        Options = {
            ["IgnoreEatRestrictArea"] = true,  -- กินอาหารได้ทุกที่
            ["IgnoreJobEatFood"] = false,      -- กินอาหารที่จำกัดเฉพาะอาชีพอื่นไม่ได้
            ["Immortality"] = false,           -- ไม่เป็นอมตะ
        },
        GetDefaultTickValueUpdate = function(source)
            return -30  -- ลดค่าสถานะช้ากว่าปกติ 30%
        end,
        CheckAllow = function(source)
            local xPlayer = ESX.GetPlayerFromId(source)
            if not xPlayer then return false end
            return xPlayer.job.name == 'police' -- ตรวจสอบว่าเป็นตำรวจ
        end
    },

    [OptionsEnum.ByPassVIP] = {
        Options = {
            ["IgnoreEatRestrictArea"] = true,
            ["IgnoreJobEatFood"] = false,
            ["Immortality"] = false,
        },
        GetDefaultTickValueUpdate = function(source)
            return -50  -- ลดค่าสถานะช้าลง 50%
        end,
        CheckAllow = function(source)
            local xPlayer = ESX.GetPlayerFromId(source)
            if not xPlayer then return false end

            -- ตรวจสอบจากไอเทม VIP ในตัว
            local vipItems = {'vip_card', 'premium_card', 'gold_membership'}
            for _, itemName in ipairs(vipItems) do
                local item = xPlayer.getInventoryItem(itemName)
                if item and item.count > 0 then
                    return true
                end
            end
            return false
        end
    },

    [OptionsEnum.ByPassAdmin] = {
        Options = {
            ["IgnoreEatRestrictArea"] = true, -- กินอาหารที่ไหนก็ได้
            ["IgnoreJobEatFood"] = true,       -- กินอาหารได้หมดไม่สนจำกัดอาชีพ
            ["Immortality"] = true,            -- อมตะ ค่าสถานะไม่ลดเลย
        },
        CheckAllow = function(source)
            -- ตรวจสอบสิทธิ์แอดมิน
            local xPlayer = ESX.GetPlayerFromId(source)
            if not xPlayer then return false end
            return xPlayer.getGroup() == 'admin' or xPlayer.getGroup() == 'superadmin'
        end
    }
}

🔌 Public Exports

AFU.Status มี Export ให้เรียกใช้งานทั้งฝั่ง Client และ Server:

1. การดึง Shared Object สำหรับสร้าง UI

lua
-- Client Side Only
local afuStatus = exports["AFU.Status"]:getSharedObject()

local hungerStatus = afuStatus.GetPlayerStatus("hunger")
local hungerValue = hungerStatus.value          -- ค่าดิบปัจจุบัน
local hungerPercent = hungerStatus.getPercent() -- ค่าเปอร์เซ็นต์ (0-100)

2. การหยุดและเริ่มระบบสถานะ (Pause / Resume)

lua
-- Client Side
exports["AFU.Status"]:pause()
exports["AFU.Status"]:resume()
local isPaused = exports["AFU.Status"]:isPause()

-- Server Side (ระบุ source ของผู้เล่น)
local source = 1
exports["AFU.Status"]:pause(source)
exports["AFU.Status"]:resume(source)
local isPaused = exports["AFU.Status"]:isPause(source)

3. การรักษาค่าสถานะ (Heal)

lua
-- Client Side
exports["AFU.Status"]:heal()         -- รักษาทุกสถานะให้เต็ม
exports["AFU.Status"]:heal("hunger") -- รักษาเฉพาะความหิว

-- Server Side
local source = 1
exports["AFU.Status"]:heal(source)          -- รักษาทุกสถานะของผู้เล่นคนนั้น
exports["AFU.Status"]:heal(source, "hunger") -- รักษาเฉพาะความหิวของผู้เล่นคนนั้น

-- Server Side (รักษาทุกคนในเซิร์ฟเวอร์ โดยส่ง source = -1)
exports["AFU.Status"]:heal(-1)
exports["AFU.Status"]:heal(-1, "hunger")

4. การรีเซ็ตค่าสถานะ (Reset)

lua
-- Client Side
exports["AFU.Status"]:reset()         -- รีเซ็ตทุกสถานะเป็นค่าเริ่มต้น (Default)
exports["AFU.Status"]:reset("hunger") -- รีเซ็ตสถานะ hunger เป็นค่าเริ่มต้น

-- Server Side
local source = 1
exports["AFU.Status"]:reset(source)          -- รีเซ็ตทุกสถานะของผู้เล่นคนนั้น
exports["AFU.Status"]:reset(source, "hunger") -- รีเซ็ตสถานะ hunger ของผู้เล่นคนนั้น

-- Server Side (รีเซ็ตทุกคนในเซิร์ฟเวอร์)
exports["AFU.Status"]:reset(-1)

5. การดึงค่าพลังชีวิตและเกราะ (Get Health / Get Armor)

lua
-- Client Side Only
local health = exports["AFU.Status"]:getHealth() -- รับค่าพลังชีวิตปัจจุบันของผู้เล่น
local armor = exports["AFU.Status"]:getArmor()   -- รับค่าเกราะปัจจุบันของผู้เล่น

6. การตรวจสอบสิทธิพิเศษ (Has Option / Has Specific Option)

lua
-- ตรวจสอบสิทธิพิเศษตาม Option Preset
-- Client Side
local hasAdmin = exports["AFU.Status"]:hasOption(OptionsEnum.ByPassAdmin)
local hasVIP = exports["AFU.Status"]:hasOption(OptionsEnum.ByPassVIP)

-- Server Side
local source = 1
local hasAdmin = exports["AFU.Status"]:hasOption(source, OptionsEnum.ByPassAdmin)
local hasVIP = exports["AFU.Status"]:hasOption(source, OptionsEnum.ByPassVIP)

-- ตรวจสอบสิทธิพิเศษเฉพาะด้าน (Specific Option)
-- Client Side
local isImmortal = exports["AFU.Status"]:hasSpecificOption("Immortality")
local canEatAnywhere = exports["AFU.Status"]:hasSpecificOption("IgnoreEatRestrictArea")

-- Server Side
local isImmortal = exports["AFU.Status"]:hasSpecificOption(source, "Immortality")
local canEatAnywhere = exports["AFU.Status"]:hasSpecificOption(source, "IgnoreEatRestrictArea")

7. ตรวจสอบพื้นที่ Free Zone (Is In Free Zone)

lua
-- Client Side Only
local inFreeZone = exports["AFU.Status"]:isInFreeZone()
if inFreeZone then
    print("ผู้เล่นอยู่ในพื้นที่ Free Zone สถานะบางอย่างจะหยุดลดค่า")
end

❓ Troubleshooting

1. สคริปต์ไม่ทำงาน หรือเตือน License Error

  • ตรวจสอบว่าใส่ set afu_license "TOKEN" ใน server.cfg ก่อนบรรทัด ensure AFU.Status
  • ตรวจสอบว่า Token ยังไม่หมดอายุในหน้า My Orders ของ awayfromus.store

2. ค่าสถานะไม่บันทึกหรือไม่ลดลง

  • ตรวจสอบว่า oxmysql และ es_extended ทำงานปกติและ start ก่อน AFU.Status
  • ตรวจสอบว่าผู้เล่นไม่ได้อยู่ในพื้นที่ Free Zone หรือมีสิทธิ์ Immortality

3. ไอเทมอาหารกดใช้แล้วไม่มีผล

  • ตรวจสอบชื่อไอเทมใน config/core/foods.lua ให้ตรงกับชื่อไอเทมในระบบ Inventory (ESX)
  • ตรวจสอบว่าไอเทมถูกลงทะเบียนในตาราง items ของฐานข้อมูลแล้ว
  • ตรวจสอบการจำกัดอาชีพ (restrictJobs) หรือพื้นที่การกินอาหาร