Skip to content

Client Systems

Artmines edited this page Nov 3, 2025 · 3 revisions

Client Systems

Complete technical reference for all client-side systems: wound detection, treatment, infection, healing, and environmental damage.


Table of Contents

  1. Wound System
  2. Treatment System
  3. Infection System
  4. Wound Healing System
  5. Environmental Damage
  6. Data Structures

Wound System

File: client/wound_system.lua (2024 lines)

What It Does

  • Monitors player health every 100ms to detect damage
  • Identifies weapon used and body part hit
  • Calculates realistic bullet behavior (lodging, penetration, fragmentation)
  • Creates wound entries with pain/bleeding levels
  • Manages wound progression over time
  • Applies bleeding damage every 30 seconds

Damage Detection Loop

-- Runs every 100ms (10 times per second)
CreateThread(function()
    while true do
        Wait(100)
        local currentHealth = GetEntityHealth(PlayerPedId())
        if currentHealth < PlayerHealth and not ApplyingMedicalDamage then
            -- Damage detected! Process wound creation
        end
        PlayerHealth = currentHealth
    end
end)

Tip

The ApplyingMedicalDamage flag prevents false wounds from bleeding ticks or infection damage.

Ballistic System

Distance affects bullet behavior:

Distance Handgun Rifle Shotgun
0-10m Pass through Pass through Pellets (6-12)
10-30m 5% lodge chance Pass through 30% lodge
30-50m 30% lodge chance 5% lodge 60% lodge
50m+ 60% lodge chance 30% lodge 100% lodge

Lodge Effects:

  • through - Clean wound, normal healing (1.0x infection risk)
  • stuck - Bullet lodged, requires surgery (2.0x infection risk)
  • fragmented - Bullet shattered, complex surgery needed (2.5x infection risk)

Body Part Mapping

The system maps RedM bone IDs to body parts:

local boneMapping = {
    [31086] = 'HEAD',      -- SKEL_Head
    [14284] = 'SPINE',     -- SKEL_Spine3
    [11816] = 'STOMACH',   -- SKEL_Spine0
    [23553] = 'UPPERBODY', -- Left shoulder
    [51826] = 'LARM',      -- Left upper arm
    [61163] = 'LHAND',     -- Left hand
    -- ... 15 body parts total
}

Supported Body Parts: HEAD, NECK, SPINE, UPPERBODY, LOWERBODY, LARM, LHAND, RARM, RHAND, LLEG, LFOOT, RLEG, RFOOT, STOMACH

Warning

Known Issue: Shotgun pellet detection may miss at extreme angles (>80° from center mass).

Wound Progression

Every 2 minutes (unified medical progression tick):

  • Untreated wounds: Pain and bleeding increase by ~15% chance per tick
  • Treated wounds with bandage: Protected from progression
  • Expired bandages: 50% of symptoms return, infection risk begins

Treatment System

File: client/treatment_system.lua (787 lines)

What It Does

  • Handles all 4 treatment types
  • Manages time-based effects and expiration
  • Tracks treatment effectiveness
  • Prevents duplicate treatments on same body part

1. Bandages (4 Types)

Type Heal Bleed Reduction Pain Reduction Duration Decay
Cloth +8 HP -2 -2 3 min 60% effectiveness
Cotton +12 HP -4 -4 5 min 70% effectiveness
Linen +18 HP -6 -6 8 min 80% effectiveness
Sterile +25 HP -8 -8 12 min 95% effectiveness

How Bandages Work:

  1. Immediate Effect: Restores HP, reduces bleeding/pain
  2. Active Protection: Prevents wound progression while active
  3. Expiration: After duration, 50% of reductions return
  4. Infection Risk: After 60-second grace period, risk begins

Important

Bandage Maintenance Required: Bandages expire (3-12 min) before wounds fully heal (10-40 min). Players must regularly replace bandages to maintain healing. This is intentional design to encourage realistic medical roleplay and ongoing wound care.

2. Tourniquets (Emergency)

Purpose: Stop severe bleeding immediately (limbs only)

Type Success Rate Max Duration Pain Increase
Rope 80% 20 min +2
Leather 85% 25 min +3
Cloth 90% 25 min +2
Medical 98% 30 min +1

Applicable To: LARM, RARM, LLEG, RLEG, LHAND, RHAND, LFOOT, RFOOT

Warning

If a tourniquet is not removed within its max duration, it will start causing damage (simulating tissue death from blood loss).

3. Medicines (Pain Relief)

Applied to ALL body parts with pain (not specific to one wound):

Type Effectiveness Heal Duration Side Effects
Laudanum 85% +25 HP 5 min Drowsiness
Morphine 95% +35 HP 7.5 min Euphoria, addiction risk (5%)
Whiskey 60% +10 HP 3 min Intoxication
Quinine 70% +15 HP 10 min Nausea

4. Injections (Fast-Acting)

Type Heal Duration Effects
Adrenaline +40 HP 5 min Stamina boost, rapid heartbeat
Cocaine +20 HP 3 min Euphoria, anxiety, addiction risk (25%)
Strychnine +10 HP 2 min Tremors, convulsions (toxic in high doses)
Saline +15 HP 10 min Rehydration

Note

Addiction risk is currently cosmetic (notification only). Full addiction system planned for v0.3.0.


Infection System

File: client/infection_system.lua (616 lines)

What It Does

  • Monitors expired bandages for infection risk
  • Progresses infections through 4 stages
  • Applies stage-based effects (stamina drain, movement penalty)
  • Manages cure progression (requires multiple treatments)

Infection Stages

Stage Percentage Effects Cure Required
1 25-49% Early infection, mild burning 2-3 antiseptic doses
2 50-74% Redness/swelling, -10 stamina 3-4 antibiotics
3 75-89% Fever, -20 stamina, -5% speed 4-5 antibiotics
4 90-100% Severe, -30 stamina, -15% speed, 2 HP/min damage 5-7 antibiotics OR surgery

How Infections Start

  1. Bandage is applied (starts fresh)
  2. Grace period: 60 seconds (no infection risk)
  3. After grace period: Roll every 2 minutes
  4. Base chance: 15%
  5. Multipliers:
    • Bullet stuck: 2.0x (30% total)
    • Bullet fragmented: 2.5x (37.5% total)
    • Clean wound: 1.0x (15% total)

Cure System

Item Cure Progress Uses Needed Availability
Antibiotics 40% per use 3 uses Pharmacist (grade 2+)
Alcohol 25% per use 4 uses General store
Cocaine 15% per use 7 uses Black market

Tip

After curing an infection, players gain temporary immunity to prevent immediate re-infection.


Wound Healing System

File: client/wound_healing.lua (231 lines)

What It Does

  • Tracks healing progress when conditions are met
  • Converts fully healed wounds into permanent scars
  • Maintains medical history

Healing Requirements

  1. ✅ Bleeding level = 1 (minimum possible)
  2. ✅ Active bandage applied
  3. ✅ Time elapsed (varies by wound type)
  4. ✅ No new damage to same body part

Healing Times by Wound Type

Wound Type Heal Time Scar Type
Cutting (knife, machete) 10 min Slash scar
Shot Through (clean gunshot) 15 min Entry/exit scar
Post-Surgery (bullet removed) 25 min Surgical scar
Fragmented (shattered bullet) 35 min Complex scar
Explosive (dynamite, fire) 40 min Burn scar
Crushing (animal, trampled) 20 min Tissue damage scar

Tip

Bandage Maintenance Workflow

To successfully heal wounds into scars:

  1. Apply bandage (sterile recommended for best results)
  2. Wait for bandage to expire (3-12 minutes)
  3. Reapply fresh bandage before healing timer resets
  4. Repeat until wound fully heals (10-40 minutes total)

Example: A gunshot wound (15 min heal time) requires 2-3 bandage changes with sterile bandages (12 min each).

This mechanic encourages realistic medical roleplay and ongoing patient care rather than "set and forget" healing.


Environmental Damage

File: client/envanim_system.lua (516 lines)

What It Does

  • Detects fall damage with height/velocity calculations
  • Creates fractures and bone breaks
  • Handles animal attack damage
  • Manages leg injury ragdoll effects

Fall Damage Thresholds

Height Normal Landing Ragdoll Landing Result
< 3m No damage No damage Safe
3-8m Minor injury Minor injury Bruising, pain level 2-3
8-15m Fracture Fracture (6m+) Bone crack, requires splint
15m+ Bone Break Bone Break (10m+) Complete break, requires surgery

Fracture System

Fractures are tracked separately from wounds in the player_fractures table:

PlayerFractures[bodyPart] = {
    type = "fracture",           -- or "bone_break"
    severity = 5,                 -- 1-10 scale
    painLevel = 5,                -- Pain from fracture
    mobilityImpact = 0.2,         -- 20% movement reduction
    healingProgress = 0.0,        -- 0-100%
    requiresSurgery = false,      -- True for bone breaks
    description = "Fractured left leg from 12m fall"
}

Animal Attack System

Dangerous animals within 50m are tracked:

Animal Damage Type Pain Bleeding Special
Bear Mauling 8 7 Multiple wounds
Cougar Clawing 7 6 Fast attacks
Wolf Biting 6 5 Pack behavior
Alligator Crushing 9 8 Limb damage
Boar Goring 5 4 Charge attacks

Tip

Leg fractures have a 5-25% chance (based on severity) to cause ragdoll when walking/running, simulating instability.


Data Structures

PlayerWounds (Core Wound Data)

PlayerWounds = {
    ['HEAD'] = {
        painLevel = 5,                -- 0-10 scale
        bleedingLevel = 3,            -- 0-10 scale
        currentHealth = 75.0,         -- Current body part HP
        maxHealth = 100.0,            -- Maximum body part HP
        healthPercentage = 75.0,      -- Percentage for NUI color
        weaponData = "SmallPistol",   -- Weapon category
        timestamp = 1234567890,       -- os.time() when created
        isScar = false,               -- Is this a healed scar?
        scarTime = nil,               -- os.time() when healed (if scar)
        metadata = {
            weaponHash = -1234567,    -- Game weapon hash
            weaponType = ".45 Colt",  -- Display name
            bulletStatus = "through", -- "through", "stuck", "fragmented"
            requiresSurgery = false,  -- Does bullet need removal?
            description = "Moderate .45 Colt wound to head...",
            shooterDistance = 15.2,   -- Distance from shooter (meters)
            ballisticType = "handgun" -- Used for distance calculations
        },
        treatments = {},              -- Treatment history for this wound
        infections = {}               -- Infection status for this wound
    },
    ['LARM'] = {...},
    -- ... other body parts
}

ActiveTreatments (Treatment Tracking)

ActiveTreatments = {
    ['HEAD'] = {
        treatmentType = "bandage",       -- Type: bandage, tourniquet, medicine, injection
        itemType = "cotton",             -- Specific item used
        appliedTime = GetGameTimer(),    -- When applied (game time, not os.time)
        expirationTime = GetGameTimer() + 300000,  -- When expires (5 min later)
        appliedBy = 5,                   -- Server ID who applied it
        originalPainLevel = 5,           -- Pain level before treatment
        originalBleedingLevel = 3,       -- Bleeding level before treatment
        painReduction = 3,               -- Amount of pain reduced
        bleedingReduction = 3,           -- Amount of bleeding reduced
        isActive = true,                 -- Still active?
        metadata = {
            label = "Cotton Bandage",
            description = "...",
            originalEffectiveness = 70,  -- Starting effectiveness %
            bleedingReduced = 4,         -- From config
            immediateHeal = 12           -- HP restored on application
        }
    }
}

PlayerInfections (Infection Tracking)

PlayerInfections = {
    ['LARM'] = {
        stage = 2,                       -- 1-4 progression level
        startTime = GetGameTimer(),      -- When infection started
        lastProgressCheck = GetGameTimer(),  -- Last time we checked for progression
        metadata = {
            causeDescription = "Dirty bandage infection from cotton bandage",
            symptoms = {
                "Redness and swelling",
                "Mild fever",
                "Pain when moving"
            },
            treatments = {
                {item = "antibiotics", timestamp = 1234567890, progress = 40}
            }
        }
    }
}

HealingTimers (Healing to Scars)

HealingTimers = {
    ['HEAD'] = {
        woundType = "shot_through",      -- Type determines heal time
        startTime = GetGameTimer(),      -- When healing started
        healTime = 15,                   -- Minutes required (from config)
        lastCheck = GetGameTimer(),      -- Last check time
        scarType = "entry_exit_scar",    -- What scar it becomes
        description = "Clean gunshot wound healing"
    }
}

PlayerFractures (Bone Fractures)

PlayerFractures = {
    ['LLEG'] = {
        type = "fracture",               -- "fracture" or "bone_break"
        severity = 5,                    -- 1-10 scale
        painLevel = 5,                   -- Pain from fracture
        mobilityImpact = 0.2,            -- 20% speed reduction
        healingProgress = 0.0,           -- 0-100% healed
        requiresSurgery = false,         -- Bone break requires surgery
        description = "Left leg fractured from 12m fall",
        timestamp = os.time()
    }
}

← Architecture | Next: Server Systems →

📖 QC-AdvancedMedic

🏠 Home


📚 Documentation

  1. Architecture
  2. Client Systems
  3. Server Systems
  4. Database Schema

⚙️ Configuration

  1. Configuration
  2. Translation System
  3. API Reference

🛠️ Development

  1. Extending the System
  2. Performance Optimization

⚠️ Support

  1. Known Issues

🔗 Links


v0.3.1-alpha

Clone this wiki locally