Editable

Editable

Note: This documentation describes the functions in the editable folders. You are free to modify, extend, or adapt to fit your server's needs.


Client Side (client/editable/)

1. events.lua

Tuning Menu Exit Handling

  • handleExitEvent()

    • Safely closes the tuning menu when certain conditions are met.

    • Behavior:

      • Returns immediately if TuningDataStore.tuningIsActive is false or nil.

      • Calls closeTuningMenu(true) to close the menu and perform any cleanup.

    • Usage:

      • Used internally by death/vehicle cache events; can be reused if you add more exit triggers.

  • Death Events

    • baseevents:onPlayerDied

      • Triggered when the player dies.[1]

      • Behavior: Calls handleExitEvent() to ensure the tuning menu is closed on death.

    • izzy-ambulance:playerDied

      • Custom death event from the izzy-ambulance resource.

      • Behavior: Calls handleExitEvent() when this death event fires.

  • Vehicle Cache Listener

    • lib.onCache('vehicle', function(value, oldValue) ... end)

      • Listens for changes to the cached vehicle value in ox_lib.

      • Behavior:

        • If value is 0 or false (player no longer in a valid vehicle), it calls handleExitEvent().

      • Usage:

        • Ensures the tuning menu closes automatically when the player leaves or loses their vehicle.

Tuning Menu Hooks

  • onTuningMenuOpened()

    • Called when the tuning menu is opened.

    • Usage:

      • Add custom behavior such as disabling the HUD, disabling certain controls, or pausing other UI while the menu is active.

  • onTuningMenuExit()

    • Called when the tuning menu is closed.

    • Usage:

      • Restore things modified in onTuningMenuOpened(), for example re-enabling HUD, controls, or other UI.


2. priceCalculation.lua

Price Calculation Helpers

  • calculateModPrice(modCategory, num, vehiclePrice)

    • Calculates the price for a performance/visual mod based on its category and the vehicle’s base price.

    • Arguments:

      • modCategory (string): Name of the mod category (e.g. "modEngine", "modTransmission").

      • num (number): Mod index/level (usually the mod number being installed).

      • vehiclePrice (number): Base price of the current vehicle.

    • Behavior:

      • Splits vehiclePrice into 6 equal parts for calculations (vehiclePrice / 6).

      • Sets a default base mod price of 2500.

      • If ModPrices[modCategory] exists, uses that as the base price instead.

      • If modCategory is listed in affectedByVehiclePrice, the price scales with vehicle price and mod level:

        • Computes modMultiplier = (num + 1) * 0.25.

        • Replaces modPrice with vehiclePriceSplit * modMultiplier.

      • Returns the final price rounded up with math.ceil.

    • Returns:

      • Final mod price (number).

  • calculateToggleModPrice(modCategory, vehiclePrice)

    • Calculates install/uninstall prices for toggle-type mods (e.g. extras that are either on or off).

    • Arguments:

      • modCategory (string): Name of the mod category.

      • vehiclePrice (number): Base price of the current vehicle (unused in the default implementation, but available for customization).

    • Behavior:

      • Returns a table with two fixed prices:

        • uninstall = 1000

        • install = 4000

    • Returns:

      • Table { uninstall = number, install = number }.

    • Usage:

      • Customize this function if you want toggle mod prices to depend on vehiclePrice or modCategory.


3. vehicleReaction.lua

Vehicle Reaction Logic

  • handleCategoryChange(modCategory, mainVehicle, cloneVehicle)

    • Reacts when the user switches between mod categories in the tuning menu.

    • Arguments:

      • modCategory (string): The currently selected mod category (e.g. "modXenon").

      • mainVehicle (vehicle handle): The player’s actual vehicle entity.

      • cloneVehicle (vehicle handle): The preview/clone vehicle used in the tuning UI.

    • Behavior:

      • If modCategory == "modXenon":

        • Calls SetVehicleLights(mainVehicle, 2) and SetVehicleLights(cloneVehicle, 2) to turn the lights on for preview.

      • For any other category:

        • Calls SetVehicleLights(mainVehicle, 0) and SetVehicleLights(cloneVehicle, 0) to restore lights to default/off.

    • Usage:

      • Extend this to add category-specific reactions (e.g., show neon, change doors, etc.).

  • handleModChange(modCategory, mainVehicle, cloneVehicle)

    • Intended to react when an actual mod value changes within a category.

    • Arguments:

      • modCategory (string): The category of the mod changed.

      • mainVehicle (vehicle handle): The player’s actual vehicle.

      • cloneVehicle (vehicle handle): The preview vehicle.

    • Behavior:

      • Empty by default; no reaction is defined.

    • Usage:

      • Implement visual or physical reactions when a specific mod value is changed, such as updating engine sound, suspension height, or temporary effects in the preview.


Server Side (server/editable/)

1. invoicePayment.lua

Money Check

  • hasMoney(target, total)

    • Checks if a player has enough money to pay for a tuning invoice.

    • Arguments:

      • target (number): Server ID of the paying player (customer).

      • total (number): Total invoice amount.

    • Behavior:

      • Uses fs.framework.getMoney(target) to get the player’s balance.

      • Returns true if the balance is greater than or equal to total, otherwise false.

    • Returns:

      • true if the player can afford the invoice, otherwise false.

Invoice Billing

  • billPlayer(sender, senderJob, target, total, basket)

    • Handles payment flow when a mechanic bills a player for tuning work.

    • Arguments:

      • sender (number): Server ID of the mechanic issuing the invoice.

      • senderJob (string): Job name or business identifier of the mechanic.

      • target (number): Server ID of the customer being billed.

      • total (number): Total invoice amount to be paid.

      • basket (table): Details of the items/mods being billed (not used in default implementation but available for customization).

    • Behavior:

      • If total <= 0, returns true immediately (nothing to charge).

      • If hasMoney(target, total) is false, returns false (payment fails).

      • Removes total from the customer using fs.framework.removeMoney(target, total).

      • Splits the payment between the business and the mechanic:

        • firmPrice = math.floor(total * (ConfigSv.BusinessPercent / 100))

        • mechanicPrice = math.ceil(total * (ConfigSv.WorkerPercent / 100))

      • Credits the business with firmPrice via fs.framework.addBusinessMoney(senderJob, firmPrice).

      • Credits the mechanic with mechanicPrice via fs.framework.addMoney(sender, mechanicPrice).

      • Sends notifications:

        • To sender using fs.utils.notify(sender, locale('invoicePaidSender', mechanicPrice)).

        • To target using fs.utils.notify(target, locale('invoicePaidTarget', total, sender)).

      • Returns true when the transaction succeeds.

    • Returns:

      • true on successful billing or when total <= 0, otherwise false.

    • Usage:

      • Adapt this to integrate with different frameworks or to change how the revenue split and notifications work.


All files in the editable folders are intended for easy customization without affecting the core logic. For further customization, refer to the comments and structure in each file.

Last updated