Skip to content

Fix aircraft not working on custom vehicle models - #5181

Open
TheCrazy17 wants to merge 2 commits into
multitheftauto:masterfrom
TheCrazy17:aircraft-custom-models
Open

Fix aircraft not working on custom vehicle models#5181
TheCrazy17 wants to merge 2 commits into
multitheftauto:masterfrom
TheCrazy17:aircraft-custom-models

Conversation

@TheCrazy17

@TheCrazy17 TheCrazy17 commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Planes, helicopters and Vortex cloned with engineRequestModel now behave like the model they were cloned from. Full breakdown by vehicle below.

Model Fixes
Hydra Guns, homing missiles, gunsight, missile lock-on reticle & camera, VTOL nozzle turn + thrust vectoring (plane and hover mode), ground wheel steering exemption, door, jet engine sound, landing gear, adjustable nozzle-angle readout
Hunter Minigun, missile lock, gunsight, door
Rustler Guns, door, landing gear
Cropduster Door, smoke trail
Shamal Door, jet engine sound, landing gear
Nevada Door, landing gear
Stunt Plane Door / rear wheel visibility, smoke trail toggle key, smoke particle spawn
AT-400 Landing gear, boarding/exit stair alignment, door collision model, exit door-height exemption, G-key closest-car targeting distance, jumbo shadow, jet engine sound
Andromada Loading ramp physics, door, jet engine sound, jumbo shadow, cargo door creak sound, landing gear
Vortex Traction/hover feel, suspension cushion, ground-rest exemption, steering, camera distance, thrust and turn damping, flyer-collision exemption, car-style crash damage, fan FX, hovercraft audio flag, engine sound, physics keep-alive, door panel
RC Baron Flight (thrust/control response), camera, engine sound
Sea Sparrow Water landing physics, buoyancy, mounted gun spread
Leviathan Buoyancy constants, physics keep-alive
Skimmer Boat physics (capsize recovery, water-landing damping, aquaplaning, steering, water drag), buoyancy constants, wheel status, splash FX, wake trail, propeller-spin render, boat camera (mode selection + framing), first-person culling
Police Maverick Native searchlight (horn key)
RC Bandit, RC Raider, RC Goblin Engine sound
RC Tiger Engine sound, mounted gun spread
Sparrow Mounted-gun-spread resolver now recognises it (shares code with Sea Sparrow)

Stock vehicles are untouched; every hook resolves a custom model ID back to the one it was cloned from and falls through unchanged otherwise.

Motivation

Part of #1861. This started much smaller: get the Hunter's minigun and the Hydra's missiles firing on a cloned model. Testing that surfaced a much bigger problem; nothing about a cloned aircraft matches native code, since every system that decides what a vehicle is (the flight model, the weapon code, the audio entity, the constructors, the cameras) does it with a hardcoded model ID comparison, and a clone made with engineRequestModel carries an ID of its own. Fixing only the guns would have shipped a plane that could shoot but couldn't take off right, had no engine sound, and used the wrong camera.

It wasn't the plan to turn this into a PR this size. Splitting it up was considered, but a lot of these fixes share a resolved model ID across several native compares in the same function, a seven-way door switch collapsing into one resolve, for example; doing that piecemeal across separate PRs would have meant reopening already-merged code and reverifying register liveness a second time on the same instructions, which is exactly the kind of change that's easy to get subtly wrong in inline assembly. So the PR grew to cover the whole class of bug in one pass instead, merging every hook that could be merged to keep the total line count as small as the scope allows. It ended up being several days of work, most of it disassembly verification rather than writing code.

One thing worth calling out: the Vortex is implemented natively as a CPlane, not a boat class, despite behaving like a hovercraft in gameplay. That's why several of its fixes live in the same plane-specific functions as the Hydra's, and why a few hooks below end up fixing the Vortex and the Skimmer together off the same shared load even though they're unrelated vehicle types on paper.

Test plan

Tested with the attached Lua script (spawns a clone of each vehicle behind a chat command, e.g. /sethydra, /setvortex) against a stock instance of the same model, side by side, for every vehicle listed in the table above. Confirmed stock vehicles behave exactly as before the change.

aircraft-test.zip

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.

Planes and helicopters work out what they are by comparing their model index
against hardcoded IDs, or by rebasing it into a jump table, across the flight
model, the weapon code, the constructors, the audio entity and the cameras. A
model created by engineRequestModel carries an ID of its own and matched none
of them, so a cloned aircraft flew as a generic plane with no guns, no VTOL,
no doors, no engine sound and the wrong camera. The Skimmer, Vortex, Sea
Sparrow, RC Tiger, AT-400 and Andromada have the same problem in their own
boat physics, hover physics, weapon spread, ped entry and shadow code. Every
one of those checks now resolves a custom model to the one it was cloned
from.
Comment thread Client/mods/deathmatch/logic/CClientVehicle.cpp Outdated
Comment thread Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp
Model IDs are unsigned, so sign extending them into the resolver calls
was wrong even if harmless today. Switched every naked hook to a zero
extending load instead, same instruction length so nothing else changes.
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