Core-Injuries
📦 Requirements
| Dependency | Minimum Version | Purpose |
|---|---|---|
| FiveM Server Artifacts | 3095+ (June 2024) | Statebags, modern natives |
| ox_lib | v3.28.0+ | Notifications, context menus, callbacks, commands |
| ox_inventory | Latest | Crutch/wheelchair/armsling usable items |
| oxmysql | Latest | Optional — only for persistence feature |
⚠️ oxmysql is optional — disable
Config.Persistence.Enabled = falseif not using.
🚀 Installation
1. Download & Place
# Place in your resources directory
/resources/[core]/core-injuries/
Download core-wheelchair Place in same folder.
2. Server.cfg Load Order
ensure ox_lib
ensure ox_inventory
ensure oxmysql # Only if using persistence
ensure core-injuries
3. Configure (Required)
Edit files in config/ — all are unescrow'd and fully editable:
config/
├── ems.lua # EMS commands, menu settings
├── knockout.lua # Knockout thresholds
├── main.lua # Main toggles | Job names, framework override
├── persistence.lua # Database settings
└── injury.lua # Injury tier definitions | Prop models, bones, offsets
4. Add ox_inventory Items
Add to your ox_inventory/data/items.lua:
['crutch'] = {
label = 'Crutch',
weight = 1500,
stack = false,
close = true,
description = 'A medical crutch for walking assistance'
},
5. Database (If Persistence Enabled)
-- Run database/schema.sql manually, or enable AutoCreateTable in config/persistence.
-- Then restart once if using Auto Create
-- Table: core_crutches_injuries
6. Start Server
# Check console for:
# [core-injuries] Framework bridge: QBox (or QBCore/ESX/Standalone)
# [core-injuries] Version check: Latest version .x.x
⚙️ Configuration
All configuration files are in config/ and unescrow'd — modify freely without touching encrypted core logic.
config/main.lua — Main Toggles
Config.Enabled = true
Config.Debug = false
Config.DefaultTier = "minor"
Config.Features = {
InjuryTiers = true, -- Enable tier system
Knockout = true, -- Enable knockout mechanics
Persistence = false, -- Requires oxmysql
EMSMenu = true, -- Enable EMS context menu
Commands = true, -- Enable all commands
LegacyCompat = true, -- v1 event/command compatibility
SkinReloadWatch = true, -- Re-apply props on clothing change
PropValidation = true -- Periodic prop re-attachment check
}
config/main.lua — Framework Overrides
Config.Framework = {
ForceFramework = nil, -- nil=auto, or "qbox"/"qbcore"/"esx"/"standalone"
EMSJobName = "ambulance",
AdminPermission = "admin"
}
config/main.lua — EMS Commands & Menu
Config.EMS = {
Commands = {
ApplyInjury = "emsinjury",
Heal = "emsheal",
Menu = "emsmenu"
},
ContextMenu = {
Enabled = true,
Title = "EMS Injury Management",
Icon = "fa-solid fa-user-injured"
},
DurationBounds = {
minor = { min = 5, max = 30 },
moderate = { min = 15, max = 60 },
severe = { min = 30, max = 120 },
wheelchair = { min = 60, max = 240 },
armsling = { min = 10, max = 60 }
},
AllowCustomDuration = true,
InteractionRange = 3.0
}
config/injury.lua — Define Tiers
Config.Tiers = {
minor = {
Label = "Minor Injury",
ClipSet = "move_lester_CaneUp",
Prop = "crutch",
RequiredItem = "crutch",
MovementPenalty = { Sprint = true, Jump = true, WalkSpeed = 0.8 },
MinDuration = 5, MaxDuration = 15, DefaultDuration = 5,
CanSelfRemove = true
},
-- moderate, severe, wheelchair, armsling...
}
config/injury.lua — Prop Definitions
Config.Props = {
crutch = {
Model = `v_med_crutch01`,
Bone = "SKEL_R_Hand",
Offsets = { x = 1.18, y = -0.36, z = -0.20, rotX = -20.0, rotY = -87.0, rotZ = -20.0 },
Collision = false, Scale = 1.0
}
}
config/knockout.lua — Knockout Settings
Config.Knockout = {
Enabled = true,
MeleeEnabled = true,
MeleeHealthThreshold = 155,
WeaponEnabled = true,
WeaponDamageThreshold = 35,
Duration = 5500, -- ms unconscious
Regeneration = 2, -- HP per tick
RegenInterval = 450, -- ms per tick
Cooldown = 30000, -- ms before re-knockout
PostKnockoutTier = "minor",
PostKnockoutDuration = nil -- nil = tier default
}
config/persistence.lua — Database
Config.Persistence = {
Enabled = false,
TableName = "core_crutches_injuries",
AutoCreateTable = true,
LoadOnStart = true,
SyncInterval = 30000, -- ms between DB flushes
CleanupInterval = 300000 -- ms between expired row cleanup
}
🎒 ox_inventory Items Setup
The system requires usable items in ox_inventory. Each tier's RequiredItem must exist in your items.lua.
Required Items
| Item Name | Used By Tiers | Type | Weight |
|---|---|---|---|
crutch |
minor, moderate, severe | Usable | 1000 |
Item Usage Flow
- Player has active injury requiring specific item
- Player uses item from inventory (right-click → Use)
- Client calls
exports['core-injuries']:UseCrutch() - Server validates: injury active + item count ≥ 1 + tier matches item
- Server removes 1 item, clears injury, syncs to client
💡 Tip: Configure
CanSelfRemove = falseon severe/wheelchair tiers to force EMS interaction.
🗄️ Database Setup (Persistence)
Auto-Create (Recommended)
Enable in config/persistence.lua:
Config.Persistence = {
Enabled = true,
AutoCreateTable = true, -- Creates table on resource start
-- ...
}
Manual Schema
Run database/schema.sql:
CREATE TABLE `core_crutches_injuries` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`identifier` VARCHAR(60) NOT NULL,
`tier` VARCHAR(32) NOT NULL,
`expiry` BIGINT NOT NULL,
`source` VARCHAR(16) NOT NULL,
`custom_duration` BOOLEAN DEFAULT FALSE,
`cleared_by` VARCHAR(32) DEFAULT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY `unique_player` (`identifier`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Persistence Behavior
| Event | Database Action |
|---|---|
| Injury Applied | Saved to DB |
| Injury Cleared | Deleted from DB |
| Server Start | Restores active injuries |
💬 Commands
EMS Commands (Requires EMS job)
| Command | Syntax | Description |
|---|---|---|
/emsinjury |
/emsinjury <id> <tier> [minutes] |
Apply injury to player |
/emsheal |
/emsheal <id> |
Clear player's injury |
/emsmenu |
/emsmenu |
Open proximity context menu |
Admin (Requires Admin permission)
| Command | Syntax | Description |
|---|---|---|
/admininjury |
/admininjury <id> <tier> [minutes] |
Apply injury (bypasses EMS check) |
/adminheal |
/adminheal <id> |
Clear injury (bypasses EMS check) |
/knockout |
/knockout <id> [duration] |
Force knockout on player |
Player Commands
| Command | Syntax | Description |
|---|---|---|
/injury |
/injury |
Check your injury status & time remaining |
/crutchtime |
/crutchtime |
Legacy v1 — check remaining time |
Legacy v1 Commands (Compatibility)
| Command | Syntax | Notes |
|---|---|---|
/applycrutch |
/applycrutch [id] [minutes] |
Applies "minor" tier |
/crutchtime |
/crutchtime |
Shows remaining time |
🔌 Exports API
Client Exports (Lua)
-- Check if player has ANY injury tier active
local isInjured = exports['core-injuries']:IsInjured()
-- Returns: boolean
-- Get current injury tier name
local tier = exports['core-injuries']:GetInjuryTier()
-- Returns: string|nil ("minor", "moderate", "severe", "wheelchair", "armsling")
-- Get remaining time in seconds
local seconds = exports['core-injuries']:GetRemainingTime()
-- Returns: number|nil
-- Get injury source ("ems", "admin", "knockout", "command")
local source = exports['core-injuries']:GetInjurySource()
-- Returns: string|nil
-- Set injury VISUALLY ONLY (no server sync) — for cutscenes, scenes
local success = exports['core-injuries']:SetInjuryTier("moderate")
-- Returns: boolean
-- Clear injury VISUALLY ONLY (no server sync)
local success = exports['core-injuries']:ClearInjury()
-- Returns: boolean
-- Attempt to use crutch item from inventory (triggers server validation)
local success = exports['core-injuries']:UseCrutch()
-- Returns: boolean
-- Force re-apply visuals (prop + clipset) — useful after clothing change
exports['core-injuries']:ReapplyInjuryVisuals()
-- Returns: void
Server Exports (Lua)
-- Apply injury to player (REPLACES existing injury — tier transition)
-- @param src number - Player server ID
-- @param tier string - Tier key from Config.Tiers
-- @param minutes number|nil - Duration in minutes (nil = tier default, clamped to min/max)
-- @return boolean, string - success, errorMessage
local success, err = exports['core-injuries']:ApplyInjury(src, "moderate", 30)
-- Clear injury from player
-- @param src number - Player server ID
-- @param clearedBy string|nil - "ems_cleared", "expired", "self_removed", "crutch_used"
-- @return boolean, string - success, errorMessage
local success, err = exports['core-injuries']:ClearInjury(src, "ems_cleared")
-- Get full injury data for player
-- @param src number - Player server ID
-- @return table|nil - { tier, expiry, source, customDuration, clearedBy } or nil
local injury = exports['core-injuries']:GetInjury(src)
-- Check if player has active injury
-- @param src number - Player server ID
-- @return boolean
local isInjured = exports['core-injuries']:IsInjured(src)
-- Get remaining time in seconds
-- @param src number - Player server ID
-- @return number|nil - Seconds remaining or nil if not injured
local seconds = exports['core-injuries']:GetRemainingTime(src)