Back to Main Page

I have no idea how far this project will go, I used to write hundreds of lines of code a day, nowadays I am lucky if I write 100 in a week.

I will start this page but there's no telling how long or short it will end up being.


Air Vehicle Effects - GVE for air vehicles...

* Functionality now moved into VEP *

Seems a long time ago since I posted this, which was the beginning of turning Helicopter Effects into GVE. May 2017 to be precise...

Helicopter Effects was born in November 2016 and like all my early mods, it irks me that it could have been better than it was. It probably wouldn't take me anywhere near as long to rewrite it but the difference is, back then modding was everything I did for almost the whole day, every day. I used to moderate the forums, answer questions, provide help and write mods, for over 14 hours a day most days. Now, it's a different story...

So 24th June 2019 marks the start... will 25th June mark the end? Who knows...

Not looking promising... watching memory values to try and see where the nozzle angles are stored on the Hydra, see lots of things changing, see nothing that matches the nozzle positions.

A night of no sleep, sitting at my PC at 5:30am and bingo, there on screen are the VTOL angles smiling back at me. Tested on the Hydra and the Avenger, both report accurate values. The values seem to be way out there in the memory ranges, I haven't seen any values this far from the vehicle base address before but who cares, they are there and I found them.

Not only that but I found the helicopter rotor blade speed as well, which means the effects can be properly rotor-speed based. That's important for the spindown as I will no longer have to use a rough-guess timer to know when the rotors have spun down.

Now I know where all these values are in version 1604.1, I can flip through older versions and set offsets for each version as required. A few weeks back I also finally managed to understand what things like *(int*) means with regards to pointers and data, which means my reading and writing memory values just got a bit cleaner. If only I had learned this stuff 3 years ago. :-(

Update 25-06-2019: As sleep clearly wasn't on the cards today, I decided to write a configuration builder mod for the AVE. Vehicles can have different types of effect generators, Rotors, Afterburners, Exhausts etc... and they can have multiple types of effect generator on the same vehicle.

In the video below, I configure the Bombushka, which has 4 propellers and an exhaust under each propeller, which points downwards. In less than a minute (when you're not going slow for a video) setting up eight generators is just a few button presses. Once the configurations are saved, it will use them next time you get into that vehicle.

Here's a 4 1/2 minute video showing the configuration process and how it sets itself with the right config when you change vehicle types. The effect generator classes are completely modular, so adding a new generator type is pretty simple.


Update 26-06-2019: A day of maths... a day of failure, how quick it all comes tumbling down. It seems what I have learned is worth Jack-shit.

Funny really, in the space of an hour or so after posting that last update, things changed. Out came the matrices and suddenly, things aren't tumbling quite so hard. In these images, yellow lines are propeller generator directions, pink lines are exhausts.

The actual problem I had been having, was calculating the direction of the exhausts when they weren't pointing in the direction of the aircraft, like here on the Bombushka. This was critical maths for me, because the VTOL aircraft are going to need this same code when the jets (Hydra) or propellers (Avenger) adjust the directions.

One more short video, this is something I have even impressed myself with... full VTOL compatibility with the generator tracking. The bright pink generator on the Hydra is an Afterburner, I like to colour code everything so I can see exactly what generators are in effect while I am testing. The spheres are a set radius and don't reflect the actual size of the effect area, they show the location and the lines show the direction.


Update 27-06-2019: Slight disappointment today when I noticed that the nozzle angles aren't correct when they are rotated backwards... however, when they are rotated down, we get some of this.

The nozzles don't have any rotating probes, in fact, the whole system has changed the way things work. I am trying to get each effect generator to use just a single spawn point generator, meaning much less particles. But the nozzle aims at the target on the ground with a random +/- .5f factor, which I am going to multiply by the height above the ground to create a wider spread as you take off.

Particle sizes are also fixed right now (as in single size), just so I could get the whole generating system working. But on the whole things are progressing well, although there is an undercurrent of trouble not far ahead. I still need more matrix code to get things fully working and I am struggling to get my head around that at the moment.

Wrote a small windows app to play with matrices, fed them some values, watched what was happening, then translated what I had learned into AVE to get the effect generator placement and direction working properly.

There was a video here but I deleted it...

Update 28-06-2019: So lay in bed last night, a problem came to mind, I had seen the effects of this problem but it hadn't occurred to me why it was happening. It's all about the area a projected circle hits on the ground...

You can see here, that the area in the centre gets no effects generated in it. In fact, the idea of projecting a circle is a fairly flawed idea but it's quick and that's the important part. However, the problem is easily solved... to some extent at least.

By rescaling the radius of the propeller generator each time it spawns a particle, a larger area of the floor is hit. It's still probably not ideal and at the time of writing this, is untried...

There is a video here however, showing the Hydra and its effects.


What the heck... have another video. This time, the Cargobob using the new system.


You know, I have been chasing a problem for ages and I am now convinced that it is an anti-modding action by Rockstar. In certain aircraft, pressing Insert (to reset the scripts) forces you into FPV mode in the cockpit and the switch camera control is useless. Pressing Insert again resets the view back to normal and the controls work fine... or so I thought. I have just been flying in the P45 and all of a sudden, I am locked into FPV mode. Some aircraft don't have this problem and that's what makes me believe it's an in-game thing, not a mod-related thing. Even if I remove any mods that affect cameras in any way, this problem still happens.

Anyway, back to this mod... some very late night offset watching found a few-more interesting items. I now have the rotor and propeller speeds, as well as the speeds as a ratio.

Interesting facts you never needed to know, Part 1:

The idle speed of a propeller is 48.1250, full speed is 55.0 and reverse is 43.1200. The ratios of those are surprising, idle is .5, full is 1.0 and reverse is .4... as I am sure you can spot, 48.1250 is not half of 55.0, so that's kinda odd.

Helicopters have no idle, it's either full speed or nothing, apart from spin-up or spin-down... full speed is 59.600

The result of having those, is I can do updates until the spin-down is below a certain value, instead of a default fixed time for everything. Of course, all the people who already have this info but never share it, are now going "Huh, yeah... knew all that years ago". Funny how that works... eh?

Update 30-06-2019: Spent far too long chasing a bug tonight in one piece of code, that wasn't in that piece of code. It seems that GET_ENTITY_HEIGHT_ABOVE_GROUND throws in the towel under certain conditions. That caused some code not to run, which in turn made it seem like another piece of code was going faulty. So I fixed that with an extension function HeightAboveWorld(), which checks what you are over, i.e. water or ground and then returns the height over the correct surface.

The end result of all that, is I now have both water and dust working for all generator types and it actually looks better than the original HE. Scary to think HE took me months probably and this has all been done in a week... including the config tool to set vehicles up. It's more efficient, it's more accurate and it works with all air vehicles. Although the jetpack looks shit because of how the camera hides particles when you're too close and the jetpack is a close-up vehicle. I don't care though, it's a shit vehicle, so it can happily have shit effects to go with it.

Because of how I have written it, it should drop into VEP pretty quickly. The main driver is an AirVehicleEffect class and that holds an AirVehicleConfig class, which in turn holds a list of EffectGenerator classes. Those classes are what define each generator. There are 5 types (Rotor, Propeller, Nozzle, Exhaust and Afterburner) which all derive from the abstract base EffectGenerator class, much like Ped and Vehicle derive from the Entity class in GTA V.

The AirVehicleConfig class is basically a wrapper class for the serialisation process. All you need to do to make it work, is you get into a vehicle, the mod checks the Dictionary<int, AirVehicleConfig> collection, which uses the model hash as a key. It passes that to the AirVehicleEffect class, that configures its collection of EffectGenerators and then you just do MyAirVehicleEffect.Update(elapsedGameTime) and everything happens from there. That then does a foreach (EffectGenerator eg in EffectGenerators) loop and calls eg.Update(elapsedGameTime) on those.

By making things so modular, it makes things easily expandable. I mean, the onTick() function is pretty much just this. The top 7 lines are in every mod I write, it's just standard stuff for me. But by disconnecting so much from the main mod, it makes it easy to plug into something else, to be controlled by it.

    int currentGameTime = Game.GameTime;
    int elapsedGameTime = currentGameTime - LastGameTime;
    LastGameTime = currentGameTime;

    // A collection of lines that process the player's current state, along with the player's vehicle
    if (PlayerPed != Game.Player.Character) PlayerPed = Game.Player.Character;
    if (PlayerPed.IsSittingInVehicle() && PlayerVehicle != PlayerPed.CurrentVehicle) SetNewVehicle();

    // If all conditions pass, update the vehicle effect
    if (PlayerVehicle != null && IsValidVehicle && VehicleEffect != null)
        if (PlayerVehicle.Model.IsHelicopter)
            if (PlayerVehicle.GetRotorSpeedRatio() > .3f) VehicleEffect.Update(elapsedGameTime);
        else if (PlayerVehicle.Model.IsPlane && PlayerVehicle.GetBoneIndex("prop_1") != -1)
            if (PlayerVehicle.GetPropSpeedRatio() > .2f) VehicleEffect.Update(elapsedGameTime);
        else if (PlayerVehicle.EngineRunning)

Integration into VEP is now complete, took a little more effort than expected but all seems to be working fine. Planes taxiing in Fort Zancudo are detected, which is something new, although they have afterburners, so their effect is limited.

Update 01-07-2019: Now that all functionality for this has been moved into VEP, this project is no longer needed. Unlike GVE, this uses the same particle types for both NPC and Player, which means there doesn't need to be a *player only* version of the mod. The player's vehicle will be collected and handled just like any other air vehicle. If anything is updated in this though, updates will be on this page.

Update 02-07-2019: Added FPS compensation code so it works better at lower frame-rates. The spawn point rotation used the elapsed time to determine how far to advance, the problem with that is that on lower frame-rates, like 30fps, it advanced twice as far but only spawned half as often. So now, if it detects a lower frame rate, it will call the update twice and only advance at half the rate, meaning the spawn pattern is consistent with a 60fps update. My 1604 version runs at 60fps, my 1032 version is FPS locked at 29.97 through ENB, they both now look the same with regards to the effects.

Short video of a 30fps vs 60fps comparison.


This video gives a good demonstration of how effective the new single-point system is (or double with 30fps) compared with the old 8-point system. You can also see the ring of effects is a bit more organic and less like a ring of smoke. There's an increased variety in scale ratios, which as well as the radius variation, has really worked well.

Amusing to see this video getting disliked... it's a technical demonstration video FFS, not something to sit down to watch with some popcorn. Maybe I should have added some music./s

Update 07-07-2019: Noticed some phasing issues with the rotor particle generation, really weird but a pair of Cargobobs seemed to be going through a particle phase-loop of spawn, then fade out, then spawn, then fade out. Not sure what was causing it but I added some code today that further optimises performance by cycling through the generators each frame, instead of doing them all at once. Also improved the fps compensation code, which should be more reliable. Finally added a random start to the effect rotator value, meaning that the start point of each sequence is different, creating a bit more variation. All of that seems to have eradicated the phasing issue, so it was worth doing.