Skip to content

Add vehicle model special ability API part1#5016

Draft
Allerek wants to merge 3 commits into
multitheftauto:masterfrom
Allerek:vehicles_abilities_part1
Draft

Add vehicle model special ability API part1#5016
Allerek wants to merge 3 commits into
multitheftauto:masterfrom
Allerek:vehicles_abilities_part1

Conversation

@Allerek

@Allerek Allerek commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Important

Everything is a subject to change

Summary

This pull request adds a client-side vehicle special ability API for applying selected GTA SA native vehicle behaviors to vehicles whose model ID would not normally receive those behaviors.

New Lua functions:

setVehicleModelSpecialAbility(vehicle, ability)
getVehicleModelSpecialAbility(vehicle)

Aliases are also available:

setVehicleSpecialAbility(vehicle, ability)
getVehicleSpecialAbility(vehicle)

Supported ability names:

"none"
"towtruck"
"packer"
"fireTruckWater"
"fireTruckLadder"

Example usage:

local model = engineRequestModel("vehicle", 525)
engineImportTXD(engineLoadTXD("custom_towtruck.txd"), model)
engineReplaceModel(engineLoadDFF("custom_towtruck.dff"), model)

local vehicle = createVehicle(model, x, y, z)
setVehicleModelSpecialAbility(vehicle, "towtruck")
local ability = getVehicleModelSpecialAbility(vehicle)
if ability == "towtruck" then
    outputDebugString("Vehicle has towtruck behavior")
end

The API currently exposes these native behavior paths:

  • towtruck

    • Enables the original towtruck hook movement, towbar lookup, tow line physics, attach behavior, and detach/drop behavior.
    • The actual tow attach point still comes from the model data used by GTA's native towbar lookup.
  • packer

    • Enables original packer-style misc_a ramp rotation.
    • Uses MTA-side handling for custom moving collision/audio where native paths were unsafe for custom model layouts.
  • fireTruckWater

    • Enables original firetruck water cannon behavior from model 407.
    • Uses GTA's native FireTruckControl path for aiming, effects, audio, and hit handling.
  • fireTruckLadder

    • Enables original firetruck ladder movement behavior from model 544.
    • Initializes the fire ladder chassis state that GTA normally sets only when constructing a real MODEL_FIRELA vehicle.
  • none

    • Explicitly disables the special ability override for that vehicle.

Getter behavior:

getVehicleModelSpecialAbility(vehicle)

returns one of:

"none"
"towtruck"
"packer"
"fireTruckWater"
"fireTruckLadder"

If no override has been set, original GTA models report their native default ability:

-- model 525
getVehicleModelSpecialAbility(towtruck) -- "towtruck"

-- model 443
getVehicleModelSpecialAbility(packer) -- "packer"

-- model 407
getVehicleModelSpecialAbility(firetruck) -- "fireTruckWater"

-- model 544
getVehicleModelSpecialAbility(firetruckLadder) -- "fireTruckLadder"

Other models default to:

"none"

Special ability overrides are cleared when:

  • the vehicle model is changed with setElementModel,
  • the underlying DFF for that model ID is replaced,
  • the underlying DFF for that model ID is restored,
  • the engine-requested model is unloaded and requested again.

This prevents stale behavior state from carrying over to a different DFF/COL/component layout.

Implementation notes:

  • The towtruck behavior is integrated by extending the native model checks used by towbar lookup, tow line/drop physics, and towtruck misc component behavior.
  • The packer behavior preserves native visual rotation but avoids unsafe native moving-collision paths for custom packer meshes.
  • The firetruck water cannon behavior calls the native firetruck control routine for vehicles configured with fireTruckWater.
  • The firetruck ladder behavior mirrors native MODEL_FIRELA chassis setup and calls native moving-collision ladder logic for configured custom ladder models.
  • Debug-only on-screen ability information is drawn for vehicles with a configured model ability to help diagnose hook resolution while testing.

Motivation

MTA can request new vehicle model IDs at runtime with engineRequestModel, but several GTA SA vehicle behaviors are hardcoded to original model IDs. This means a custom model that is visually and structurally built like a towtruck, packer, firetruck, or fire ladder cannot naturally use the original game behavior when it lives on a newly requested model ID.

This change allows resources to opt a vehicle into one of those native special behavior paths explicitly, without permanently spoofing the vehicle's real model ID.

The main goals are:

  • Allow custom towtrucks to tow vehicles using the original towtruck mechanics.
  • Allow custom packers to move their ramp like the original packer.
  • Allow custom firetrucks to use the original water cannon behavior.
  • Allow custom fire ladder trucks to use the original ladder movement behavior.
  • Keep original GTA models reporting and using their native default behavior when no override was set.
  • Avoid carrying special behavior state across model replacement, model restore, or model ID reuse.

This is especially useful for resources that use engineRequestModel to add new vehicle models while still expecting original GTA SA special vehicle functionality.

Test plan

towtruck1.zip
Testing was done with the local towtruck1 test resource under:

Bin/server/mods/deathmatch/resources/towtruck1

The test resource includes custom replacement assets for:

towtruck.txd / towtruck.dff
towtruck2.txd / towtruck2.dff
packer.txd / packer.dff
firetruk.txd / firetruk.dff
firela.txd / firela.dff

A shareable copy of the test resource is prepared under:

towtruck1_pr_test_resource/towtruck1

That copy intentionally contains 0-byte placeholder .txd and .dff files only, so third-party/proprietary model assets are not included in the PR. Before running that copy, replace the placeholders with valid vehicle model files using the same filenames listed above. If the placeholders are left in place, custom model import/replacement tests are expected to fail; this is intentional.

Manual commands:

/testtow
/testtow2
/testpacker
/testfire
/testladder
/testabilities
/testabilityreset

Expected behavior:

  • /testtow

    • Spawns a custom towtruck model.
    • Applies towtruck.
    • Vehicle should rotate the tow hook, attach nearby towable vehicles, keep tow line physics, and detach/drop normally.
  • /testtow2

    • Spawns the second custom towtruck model.
    • Applies towtruck.
    • Used to verify behavior does not depend on a single custom DFF.
  • /testpacker

    • Spawns a custom packer model.
    • Applies packer.
    • Player is warped into the vehicle after spawn.
    • Ramp should move with original-style input and should not throw the camera upward.
    • Ramp moving sound should play while the ramp moves.
    • Moving collision should follow the custom ramp.
  • /testfire

    • Spawns a custom firetruck model.
    • Applies fireTruckWater.
    • Water cannon should aim/fire using original firetruck controls and effects.
  • /testladder

    • Spawns a custom fire ladder model.
    • Applies fireTruckLadder.
    • Ladder should respond to original ladder controls.
  • /testabilities

    • Spawns a matrix of original and custom vehicles with all supported ability values:
default
none
towtruck
packer
fireTruckWater
fireTruckLadder
  • The resource prints each case to the F8 console.
  • Client-side checks print PASS or FAIL for both getter aliases:
getVehicleModelSpecialAbility(vehicle)
getVehicleSpecialAbility(vehicle)
  • /testabilityreset
    • Runs client-side reset/replacement tests.
    • Covers:
      • custom-to-custom setElementModel reset,
      • custom-to-original setElementModel reset,
      • original default getter behavior,
      • explicit "none" behavior,
      • invalid ability rejection,
      • alias setter behavior,
      • engineReplaceModel reset,
      • engineRestoreModel reset,
      • engineFreeModel plus re-request behavior,
      • replacing towtruck2 assets onto the same custom towtruck model ID.

Important F8 checks:

[towtruck1] PASS [...]
[towtruck1] FAIL [...]

The expected result is no FAIL lines.

Specific reset cases that should pass:

same-id-before-towtruck2-replace
same-id-after-towtruck2-replace
same-id-before-original-towtruck-replace
same-id-after-original-towtruck-replace
default-original-towtruck
default-original-packer
default-original-firetruck
default-original-firetruck-ladder
default-original-towtruck-explicit-none
default-original-packer-explicit-towtruck
default-original-firetruck-explicit-none
default-original-firetruck-ladder-explicit-none

Native behavior checks:

  • Towtruck:

    • Hook rotates in the same direction/range as the original towtruck.
    • Towed vehicle attaches at the DFF-defined towbar/hook location.
    • Towed vehicle can be dropped/detached by lowering it to the ground.
    • Tow line retains original physics when no vehicle is attached.
  • Packer:

    • Ramp moves with original-style controls.
    • Camera does not jump far above the vehicle when the ramp moves.
    • Moving collision follows the ramp.
    • Ramp sound plays while moving.
  • Firetruck water:

    • Water cannon fires with original controls.
    • Water cannon audio/effects are present.
    • Water cannon hit events still flow through existing MTA event handling.
  • Firetruck ladder:

    • Ladder movement responds to original controls.
    • Custom ladder model receives fire ladder chassis initialization.

Checklist

  • Your code should follow the coding guidelines.
  • Smaller pull requests are easier to review. If your pull request is beefy, your pull request should be reviewable commit-by-commit.

@FileEX

FileEX commented Jul 7, 2026

Copy link
Copy Markdown
Member

#4330

@Allerek

Allerek commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

#4330

this one is way more extensive

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants