Skip to content

About

Tetris-grid inventory for COREX Framework

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

Β 

History

17 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

corex-inventory

Tetris-grid inventory with weight, slots, drops, shops, and weapon support.

Part of the COREX Framework.

Install

Drop the corex-inventory folder into:

server-data/resources/[corex]/corex-inventory/

Dependencies

The Inventory manifest requires corex-core. The native inventory uses the framework's database setup; follow the full Recipe installation for the database and shared services.

ox_target is optional for the inventory itself, but required for its portable-vehicle look-at pickup interaction. The consumer calls ox_target directly; replacing the target library does not automatically adapt this interaction. Check that your selected target resource supports the actual exports and configuration you use. ox_lib is not a hard dependency of this inventory; other resources, including Admin, may require it.

Make sure the load order is:

ensure corex-core
ensure ox_target # Only when the portable-vehicle pickup interaction is enabled
ensure corex-inventory

Update

Back up the database, configuration and recovery data first. Select the reviewed compatible revision, merge configuration changes, and update with players disconnected. Do not overwrite local configuration blindly or delete inventory-recovery.json; it can contain unacknowledged player saves and must never be published.

Inventory database table

CoreX inventory data is stored in corex_inventories, leaving the generic inventories table available to replacements such as qb-inventory. On the first start after upgrading, an older CoreX-shaped inventories table is copied to the namespaced table and retained as corex_inventories_legacy. A table that does not contain CoreX's inventory_type, inventory_id, and hotbar columns is left untouched.

Docs

πŸ“– https://corex-zombies.gitbook.io/corex-docs/reference/native-inventory


Portable vehicles (pick up β†’ inventory β†’ deploy)

Players can turn a deployed, owned vehicle from a COREX vehicle catalog into a single inventory item so it survives server restarts and world wipes. This is no longer bicycle-only: cars, bikes, scooters, helicopters, and future vehicle catalogs can use the same flow. Requires ox_target (ensure ox_target before this resource).

Flow

  1. Player buys a vehicle from any type = "vehicle" shop backed by a COREX vehicle catalog.
  2. After spawn, the client registers the networked vehicle with the server; the server sets portable vehicle state bags on the entity.
  3. Player aims at their vehicle with ox_target β†’ Pick up vehicle.
  4. The vehicle is removed from the world and a portable_vehicle item is added with metadata: owner, catalogId, plate, model, label, itemName.
  5. From inventory, Use closes the bag, spawns the vehicle in front of the player, and auto-enters the driver seat by default.

Pickup does not use the global player β€œbusy” lock (TrySetBusy), so it still works if another action left isBusy stuck; a short cooldown prevents double-submit spam.

Ownership & persistence

Where What is stored
Inventory row metadata.owner = COREX player.identifier; metadata.catalogId, metadata.model, metadata.plate
World entity (while parked) State bags set after successful registration (corexPortableVehicleOwner, etc.)

If the item stays in the backpack, ownership survives reconnect and restart because it is saved with the inventory payload.

Relevant files

Area File
Pickup / spawn-from-item / ox_target client/rental_bicycle.lua (compat filename; portable vehicle implementation)
Shop spawn hook + exports (SetActiveRentalVehicle, …) client/main.lua
Purchase plate, finalize, pickup, deploy events server/main.lua
Item definition shared/items.lua β†’ portable_vehicle

Server events (reference)

  • corex-inventory:server:finalizePortableVehicle β€” attaches ownership to a freshly spawned vehicle (catalog + plate + model match).
  • corex-inventory:server:pickupPortableVehicle β€” validates owner, adds portable_vehicle, deletes entity for all clients.
  • corex-inventory:server:deployPortableVehicleFromItem β€” validates metadata, removes item, spawns client-side deploy + finalize.

Server-side validation uses allowed model hashes from the metadata catalogId, not client-only vehicle-class checks. rental_bicycle events/items are still accepted as compatibility aliases.


Add a new portable vehicle system

You do not need to copy rental_bicycle.lua or create new pickup/deploy events for every vehicle type. Add a vehicle catalog in corex-core, point a vehicle shop at that catalog, and choose which inventory item should represent the vehicle.

1. Add a vehicle catalog

File: server-file/resources/[corex]/corex-core/shared/vehicles.lua

Corex.SharedVehicles["car_rental"] = {
    id = "car_rental",
    label = "Car Rental",
    subtitle = "BASIC CARS",
    currency = "cash",
    purchaseLabel = "Deploy Car",

    -- true = vehicles in this catalog can be picked up with ox_target.
    portable = true,

    -- Optional. If omitted, vehicles use Config.PortableVehicles.ItemName
    -- from corex-inventory/config.lua, which defaults to "portable_vehicle".
    inventoryItem = "portable_vehicle",

    vehicles = {
        {
            model = "blista",
            label = "Blista",
            category = "compact",
            price = 1200,
            description = "Small reliable city car.",

            -- Optional per-vehicle override.
            -- portable = false disables pickup for this vehicle only.
            portable = true
        },
        {
            model = "sanchez",
            label = "Sanchez",
            category = "bike",
            price = 900
        }
    }
}

2. Add a shop that uses the catalog

File: server-file/resources/[corex]/corex-inventory/shared/shops.lua

Shops["Car Rental"] = {
    label = "Car Rental",
    type = "vehicle",
    catalogId = "car_rental",
    npc = {
        model = "s_m_m_autoshop_02",
        coords = vector4(1518.0, 1708.0, 109.0, 90.0),
        scenario = "WORLD_HUMAN_CLIPBOARD",
        icon = "fa-car",
        interactLabel = "[E] Car Rental",
        interactDistance = 2.5
    },
    spawnPoint = vector4(1514.0, 1705.0, 109.0, 90.0),
    items = {}
}

3. Use a custom item, if needed

Most systems can use the default portable_vehicle item. If you want a custom item like rental_bicycle, add it to shared/items.lua and set inventoryItem on the catalog or vehicle.

['rental_helicopter'] = {
    label = 'Helicopter',
    weight = 20.0,
    size = {w = 3, h = 3},
    stackable = false,
    usable = true,
    image = 'default.png',
    iconMetadataKey = 'model',
    rarity = 'epic'
}

Then in the catalog:

inventoryItem = "rental_helicopter"

You can also set it per vehicle:

{
    model = "buzzard",
    label = "Buzzard",
    price = 25000,
    inventoryItem = "rental_helicopter"
}

Rules

  • portable = true on a catalog makes the catalog portable.
  • portable = false on a vehicle blocks only that vehicle.
  • inventoryItem on a vehicle overrides inventoryItem on the catalog.
  • If no inventoryItem is set, the system uses Config.PortableVehicles.ItemName, default portable_vehicle.
  • rental_bicycle is just a custom item for bike_rental; the pickup/deploy logic is still the same portable vehicle system.

Dynamic item icons (NUI)

Icons are chosen in html/script.js via getItemImageSrc(item, itemDef). Item definitions from shared/items.lua are sent to the UI as itemsData.

Optional fields on any item

['some_item'] = {
    label = 'Some item',
    image = 'default.png',          -- fallback if dynamic icon cannot be resolved
    iconMetadataKey = 'model',      -- read this key from item.metadata
    -- iconFilenamePattern is OPTIONAL:
    -- if omitted, pattern defaults to "%s.png" β†’ images/<value>.png
    iconFilenamePattern = 'pack_%s.png',  -- optional; must contain one "%s"
    -- ...
}

Examples

  • Same style as bike models: only set iconMetadataKey = 'model' β†’ files html/images/bmx.png, cruiser.png, etc. (sanitized lowercase).
  • Custom prefix: iconFilenamePattern = 'loot_%s.png' β†’ html/images/loot_gold.png when metadata.tier would need iconMetadataKey = 'tier' β€” adjust key/pattern to match your metadata.

Invalid or missing metadata falls back to image, then images/<item_name>.png, then default.png (via onerror).


Combat skill engine boundaries

corex-inventory/client/weapons.lua only applies a combat-skill effect when the FiveM/GTA V boundary supports it without inventing native behavior.

Skill effect Current inventory-side status
Recoil / Steady Aim Uses COREX's own additive recoil plus the documented SHAKE_GAMEPLAY_CAM path. The skill multiplier scales COREX's configured shake intensity; no undocumented raw native hash is required.
Quick Reload (reloadSpeed = 0.80) server/reload_runtime.lua owns an opaque timed reload. The client plays the normal reload animation and cannot spend/increase reserve ammo itself. Death, weapon switch, reconnect/session change and expiry cancel the pending reload.
Iron Sights (aimSpeed = 0.70) Uses an aim-capable scripted camera transition. The default 220 ms transition becomes 154 ms for the skill, then the scripted camera is destroyed and normal GTA camera control resumes.
Akimbo Pistols/SMGs render an off-hand copy of the equipped weapon. Each detected primary shot can request exactly one additional round; the server validates skill/category/weapon/ammo progression/rate before authorizing the second shot. weaponDamage = 0.85 is applied while Akimbo is active.
Weapon Modder Craft mod items at a workbench, equip the weapon, then use `/weaponmod <grip
Headshot Pro / Executioner Locally owned victims use entityDamaged, GET_PED_LAST_DAMAGE_BONE, live health and a control fence. For remote COREX zombies, Zombies matches the attacker's engine hit to the native owner's damage observation and routes the authorized bonus to that owner. Inventory does not submit attacker-selected remote bonus damage.

Primary Cfx references: citizenfx/fivem GameEventFunctions.cpp, and citizenfx/natives entries for SET_CAM_AFFECTS_AIMING, DOES_WEAPON_TAKE_WEAPON_COMPONENT, GIVE_WEAPON_COMPONENT_TO_PED, SET_PLAYER_WEAPON_DAMAGE_MODIFIER, SHOOT_SINGLE_BULLET_BETWEEN_COORDS, GET_PED_LAST_DAMAGE_BONE, IS_ENTITY_DEAD, and SHAKE_GAMEPLAY_CAM.

tests/test_weapon_skill_engine_contracts.py checks source structure only. test_weapon_actions_integration.py, test_weapon_metadata_boundary.py and test_client_reload.py execute actual server/client Lua with controlled external boundaries. They cover transactions, stale replies, session changes and cancellation, but do not replace native gameplay acceptance for camera easing, off-hand rendering, or cross-owner Headshot/Executioner damage. Update server and client together: reload messages carry request correlation and completion tokens. Confirmed reloads also advance metadata.ammoRevision; pre-reload ammo/Akimbo reports are rejected, and newer inventory snapshots restore the authoritative ammo generation. Legacy items without a revision use zero. Preserve this field during item transfers.


Community

πŸ’¬ https://discord.gg/G95rtnb9sg

License

Released under the MIT License.

About

Tetris-grid inventory for COREX Framework

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages