Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Topics - Sebastian


Racing System
(with checkpoints)

This is basic and ready for you to use and even customize !

Some info about how it works?! Somebody /startrace, and then, for the next 20seconds (by def), people can join it and race.
It loads all the saved tracks to check if everything is alright, then free the table so we don't unnecessary keep a lot of data in the memory. So, we load it only when we need it.
(didn't start the script with this idea though, so IF -big if- there are some bugs, I'm pretty sure it is because of the few changes I did to the 'mechanism')
The racing track is using checkpoints, together with 2 markers on radar: 1 for the next cp, 1 for the second next cp.
You can join as many racers as you want in a race, but I've limited it to const race_max_spots = 20;
(so, just change that if you want more)
There is a likes variable too, saved in the database, but never used. I consider it needs to be a lil' bit more hardcoded
in each server, as you need to know who voted already, when players have some time for voting, etc
For more, check it out!

My Racing System is something everybody can use in their servers, as a side activity.
I also suggest you to use some GUI on it :P

Available commands:
  • /race - info and list of cmds
  • /startrace //<trackID> <newVehModel> <newLaps> - all params are optional!
  • /joinrace
  • /quitrace
  • /flip
  • /lastcp

Developer mode:
  • /racedev - toggle developer mode
  • /createtrack <name> //<laps> - name must be 1-word
  • /createcp - creates the next checkpoint position


Some things/functions you might already have

[noae]const COLOR_BLUE = "[#4baaff]";
const COLOR_GREY = "[#b0b0b0]";
const COLOR_WHITE = "[#ffffff]";

[noae]function random( min, max )
        if ( min < max )
                return rand() % (max - min + 1) + min.tointeger();
        else if ( min > max )
                return rand() % (min - max + 1) + max.tointeger();
        else if ( min == max )
                return min.tointeger();

function GetTok(string, separator, n, ...)
    local m = vargv.len() > 0 ? vargv[0] : n,
    tokenized = split(string, separator),
    text = "";
    if (n > tokenized.len() || n < 1) return null;
    for (; n <= m; n++)
        text += text == "" ? tokenized[n-1] : separator + tokenized[n-1];
    return text;

function NumTok( string, separator )
    local tokenized = split(string, separator);
    return tokenized.len();

Some a lil' bit more custom, but still
thought, you might want to edit them
[noae]function devprint( text )
MSG( COLOR_GREY + text + "" );
print( text );

function pMSG( text, player )
return MessagePlayer( COLOR_BLUE + text, player );

function MSG( text )
return Message( COLOR_BLUE + text );

function SQLC( db, column )
    return GetSQLColumnData( db, column );


1.First, we must load the RacingSystem.nut
then, for the future, we gonna check if tracks data is good
[noae]function onScriptLoad()
dofile( "scripts/RacingSystem.nut" );
2.Then we make sure we rage quit the players when needed
[noae]function onPlayerPart( player, reason )
if( racedev == player.ID ) racedev = null;
QuitTrack( player );
function onPlayerDeath( player, reason )
QuitTrack( player );

function onPlayerKill( player, killer, reason, bodypart )
QuitTrack( player );

function onPlayerTeamKill( player, killer, reason, bodypart )
QuitTrack( player );

3.Now, onPlayerCommand
[noae]else if ( cmd == "race" )
pMSG( "Racing System by Sebastian (aka sseebbyy)", player );
pMSG( "Commands: (/) racedev, startrace, joinrace, quitrace, flip, lastcp", player );

else if( cmd == "startrace" )
if( !text ) return AnnounceRace();

local param = array( NumTok( text, " " ) );

local i = 0;
for( i = 0; i < param.len(); i++ ) param[i] = GetTok( text, " ", i+1 );

if( ( param.len() == 1 ) && IsNum( param[0] ) ) return AnnounceRace( param[0] );
else if( ( param.len() == 2 ) && IsNum( param[1] ) ) return AnnounceRace( param[0], param[1] );
else if( ( param.len() == 3 ) && IsNum( param[2] ) ) return AnnounceRace( param[0], param[1], param[2] );
else return pMSG( COLO_GREY + "Error - One/more params are not numbers. Every parameter must be number.", player );

else if( cmd == "joinrace" )
JoinTrack( player );

else if ( cmd == "quitrace" )
QuitTrack( player );

else if ( cmd == "flip" )
local veh = player.Vehicle;
            if ( !veh ) pMSG( COLOR_GREY + "You need to be in a vehicle to use this command.", player );
local rot = veh.Rotation;
                veh.Rotation = Quaternion( 0.0, 0.0, veh.z, veh.w ); // by Xmair
                pMSG( COLOR_BLUE + "Vehicle flipped.", player);

else if ( cmd == "lastcp" )
LastCP( player );

else if( cmd == "racedev" )
if( racedev == player.ID ) return devExit( player );
else if( racedev == null ) return devEnter( player );

else if( cmd == "createtrack" )
if( racedev == null ) return pMSG( COLOR_GREY + "Error - You must be in the developer mode!", player );
else if( racedev != player.ID ) return pMSG( COLOR_GREY + "Error - You must be in the developer mode!", player );
else if( !text ) return pMSG( COLOR_GREY + "Error - Correct Syntax: /" + cmd + " <name> <laps?>", player );

local track,
name = GetTok( text, " ", 1 );

if( NumTok( text, " " ) != 2 )
track = CreateTrack( name, player );
if( track )
Race.ID = track.ID;
pMSG( COLOR_BLUE + "[RACEDEV] " + player.Name + " created a new racetrack " + name, player );

local laps = GetTok( text, " ", 2 );
if( ( laps != null ) && !IsNum( laps ) ) return pMSG( COLOR_GREY + "Error - Second parameter '<laps>' must be a number!", player );

track = CreateTrack( name, player, laps.tointeger() );
if( track )
Race.ID = track.ID;
pMSG( COLOR_BLUE + "[RACEDEV] " + player.Name + " created a new racetrack " + name + " with " + laps + " laps.", player );

else if( cmd == "createcp" )
if( racedev == null ) return pMSG( COLOR_GREY + "Error - You must be in the developer mode!", player );
else if( racedev != player.ID ) return pMSG( COLOR_GREY + "Error - You must be in the developer mode!", player );

local tid = Race.ID;
if( tid == null ) return pMSG( "Unfortunately, there is no race announced yet.", player );

local track = trackTable.rawget( tid );
CreateCP( tid, player.Pos );
pMSG( COLOR_BLUE + "[RACEDEV] " + track.Name + " got a new checkpoint by " + player.Name, player );

4.Finally, the magic function
[noae]function onCheckpointEntered( player, checkpoint )
if( Race.ID != null && trackTable.rawin( Race.ID ) )
local tid = Race.ID,
track = trackTable.rawget( tid );

if( track.pptTable.rawin( player.ID ) )
local ppt = track.pptTable.rawget( player.ID );
if( ppt.UCP.ID != checkpoint.ID ) return 0;

ReachCP( player );
I've been hunting this for a while, and finally did it!

With the help of our beloved @Thijn  , we have all the tools we need to properly load
Custom Objects/Maps in GTA Map Editors
  • MEd (the one I'm gonna use in my video tutorials)
  • KEd (updated version of MooMapper)
Yes, Thijn made yet another great converter:

Short theory about how things work:
Simply redoing what R* did: place all needed .dff .txd inside Vice City/models/gta3.img.
Then, we need to register them in some .ide file (just like we do in vc:mp, in .xml, just different format) to let the game know which .txd we want for the specified .dff, etc.
Once we did that too, we must let the game know we created a new .ide file that we want to load, so, we just open Vice City/data/gta_vc.dat and write it down there too.

That's it!
Now the game knows we have new objects, so we can just start do our maps with Map Editors.
PS: The Single Player won't load anymore though, as we are pretty sure crossing some limits there.
That's why I suggest you to make a copy of the game, which will be used only for Mapping.

Good luck in mapping!

I've split this tutorial in 2 as we may need 2 different things:
  • Load just the custom objects, and then create our own maps from scratch
  • Load entire custom maps from store/maps/ and edit them through the Editor

For the ones who fits the second option, it might help watching the first video tutorial too.

PS: It might look complicated, but it is not. It's easy. All you need is some practice.

HOW TO load and play with your VC:MP Custom Objects in Map Editor ! (aka Med)
So, in order to do this, you will need:
1.   Your custom objects' .txd and .dff
2.   (any) IMG Editor
3.   Map Editor (MEd)

I also suggest you to create a copy of your Vice City and use it for such jobs, as we gonna edit files inside.

So, let's start:
1.   Add custom objects (.txd and .dff) inside gta3.img
We will do it with IMG Editor.
(always rebuild archive after)
2.   Convert .xml to .ide and load it into gta_vc.dat
We gonna use Thijn's converter for it.
Preferably to create a separated folder for our custom maps, so we have everything organized.
3.   Open MEd and load your new VCMP Mapping
4.   Create a new .ipl file and start mapping with your custom objects!
5.   Once you finished, save all the progress/changes.
6.   Convert the new <mapname>.ipl to .xml and load it in your server
7.   Start server and check what have you accomplished!

If last time we learnt how to load and play with VC:MP Custom Objects in MEd, this time we gonna learn
HOW TO Load entire custom maps and objects in MEd !
So you will be able to do changes to the already made-map.
I suggest you to make a copy of your server store folder before such jobs, so you don't lose anything.

In order to start, make sure you have:
1.   all the .txd .dff files of the custom map
2.   objects.xml from store/objects/ where all the above objects are registered
3.   map.xml from store/maps/ of the wanted map
4.   and ofc MEd, IMG Editor

Let's start!
1.   Load all the .txd and .dff into the gta3.img and rebuild the archive!
2.   Convert objects.xml to .ide and place it in the wanted folder in VCMP Mapping/data/vcmp_maps/
3.   Convert map.xml to .ipl and place it in the same location as above
4.   Load the new added .ide and .ipl inside gta_vc.dat
MAKE SURE that your new map won't conflict with some other maps.ide/.ipl !
If you have an object on id 6000 on 2 maps.ide, the object will be defined only one – the first time.
So, to avoid such unpleasures, comment the other maps, if they are not part of this new one!
5.   Open MEd, load VCMP Mapping, and check your new map's box so it will load.
6.   Do all the edits you want to the custom map you added.
7.   Save all the progress, close MEd/KEd and convert the new map.ipl to .xml and replace it in your server files.
8.   Start server and see if it worked!

Sorry for being late, but I've faced a surprise which is just amazing!
The Bullet Holes I told you about, won't be just local, but synced on everybody's screen !!
What ?? Yes!  And all just by client-side. (no data is sent to server)

(onPlayerShoot is called for everybody, not just for the local player)

I've set a limit for bullet holes, as we don't want to use too many resources.
(even if I'm not sure how hard will this hit some low-end pc)
So, if you face lag when playing alongside other players, reply to this post with your pc details, and according to the replies I get, I will try to find a way around to fix it.

How does it work ?
Well, it creates a sprite on the hit position, in client side.
With help from habi, sprites are rotated to be facing the player in the moment of shooting, so they won't look like ugly dots around.
Every player has a limit of 10 bullet holes that can create, so once the limit is touched, the first one created will be removed, and so on.

Sprites won't be removed, because:
Quote from: MEGAMIND on Oct 14, 2020, 06:24 AMSuggestion : Donot let the holes fade away, it will bring more realism,  if anyone passes by he/she may see that someone here fought here before

But, as I said, if some players will start facing lag using this script, then I will rethink it and solve it out.
Meanwhile, big thanks goes to @habi for his math skills which I Iack alot !

That's all I guess, so I will just post the code which you need to use CLIENT-SIDE
Also, better save the "hole.png" and place it in server/store/sprites

const MAX_PLAYERS = 100;
llplayer <- World.FindLocalPlayer();

/* per player */
const MAX_HOLES = 10; // -1 for never removing holes, 0 for turning off the effect

local bulletTable = array( MAX_PLAYERS ),
holes = array( MAX_PLAYERS ),
last_hole_picked = array( MAX_PLAYERS );

bulletTable[ llplayer.ID ] = {};
holes[ llplayer.ID ] = 0;
last_hole_picked[ llplayer.ID ] = 0;

class leHole
    inst = null;
    ID = null;

function Player::PlayerShoot( player, weapon, hitEntity, hitPosition )
    if( hitEntity && hitEntity.Type == OBJ_BUILDING )
CreateBulletHole( player, hitPosition );

function CreateBulletHole( player, pos )
local ppos = player.Position;
if( MAX_HOLES == 0 ) return 0;
else if( !bulletTable[ player.ID ] )
// this means the 'player' was not registered by this client, yet
bulletTable[ player.ID ] = null;
bulletTable[ player.ID ] = {};
holes[ player.ID ] = 0;
last_hole_picked[ player.ID ] = 0;

local   hole,
id = holes[ player.ID ],
angle = atan2( pos.X - ppos.X, pos.Y - ppos.Y );

if( MAX_HOLES != -1 && holes[ player.ID ] == MAX_HOLES )
if( bulletTable[ player.ID ].rawin( last_hole_picked[ player.ID ] ) )
id = last_hole_picked[ player.ID ];
local lhp = id + 1;

hole = bulletTable[ player.ID ].rawget( id );
hole.inst = null;
bulletTable[ player.ID ].rawdelete( id );
holes[ player.ID ]--;

if( last_hole_picked[ player.ID ] == MAX_HOLES-1 ) lhp = 0;

last_hole_picked[ player.ID ] = lhp;

bulletTable[ player.ID ].rawset( id, leHole() );
hole = bulletTable[ player.ID ].rawget( id );
hole.ID = id;

hole.inst = GUISprite( "hole.png", VectorScreen( 0, 0 ) );
hole.inst.Alpha = 90;

hole.inst.AddFlags( GUI_FLAG_3D_ENTITY );
hole.inst.Set3DTransform( Vector( pos.X, pos.Y, pos.Z ),  Vector( -PI/2, 0, -angle ), Vector( 0.35, 0.35, 0.0 ) );
fixsprite( hole.inst );
centersprite( hole.inst );
holes[ player.ID ]++;

@habi 's magic
// habi's magic
function move( pos, distance, angle )
local newx = pos.X - sin( angle ) * distance,
newy = pos.Y + cos( angle ) * distance;
return Vector( newx, newy, pos.Z ); //assuming z more or less same.

function move2( pos, pangle, dis, angle )
return move( pos, dis, pangle + angle )
function fixsprite( sp )
local x = sp.Position3D,
rot = sp.Rotation3D,
size = sp.Size3D, //(pos,pangle,dis,angle)
newPos = move2( x, rot.Z, 1, PI );

sp.Position3D = newPos;
function centersprite( sp )
local x = sp.Position3D,
rot = sp.Rotation3D,
size = sp.Size3D, //(pos,pangle,dis,angle)
newPos = move2( x, rot.Z, size.X / 2, PI / 2 );

newPos.Z += 1.15;
sp.Position3D = newPos;

PS: If you find bugs, let me know!

Just like R* did ?![spoiler=R* work][/spoiler]

Lately, I've been spending my time lighting up buildings for my server's map, because it was too dark.
(check the last seconds of the video to see what I'm talking about)

I recorded a video tutorial about it, maybe it will help some of you.

[spoiler=Editing textures]
Editing the textures in order to keep the windows only, and remove everything else, was cut from the full video.
It is something you can achieve through other softwares too - but I shown you the very basic way instead.

Editing the textures is up to you and your skills.

Im gonna use a way that's basic and everyone can do.
For this, we gonna need TXD Workshop and  TXD Magic we already have.

This 222.txd is mine for such things. As you can see, this is howfinal products should look.
(so we remove everything and leave just what we wanna see lighted up in the darkness)

So, first, I'm gonna light up the textures.
I'm using PHOTOSCAPE because it is an easy software.

Now, here comes the "trick". We must create a copy of those textures, and edit them.
(but before, add "_lighted" sufix to your textures' names, so they don't conflict with the originals)

We gonna use the "alpha way". So, in the copies we created, we gonna paint with white everything we wanna keep visible in-game, and with black everything we wanna hide.

In order to make it look realistic, we should hide one/two windows, as rarely buildings have all lights opened.
(better to start with that idea - I just remembered now to tell you)

Ok, so we have done the first one; we move to the second one.

Also finished the second one. As I said, we make white just what we want to keep visible.

OH! totally forgot.
The black'n'white textures must be in .BMP format.
(we don't need .png for them anymore, so we delete them)

Now, comes the TXD Workshop trick. That software allows us to set an alpha variant for our texture.
( TXD Magic doesn't )

As you can see, both images mixed into one, and only the white part was kept visible.
So, we just open it now with TXD Magic. It reads it as a .png with transparency.
That's what we need.

So, all that matters is the result:
texture with transparency!

Hello there!

Today I will show you my way of lighting up
buildings' windows !


In order to light them up, we will edit the original
object and remove everything else except windows.
Then, move the windows out of the building a bit, so
they won't interfere with each other. (nor with the LOD)
3rd step is to light them up through Blender.


Used:     MEd ( to export the object )
   Blender ( to edit the object ) with I/O DFF plugin!
   .TXD Magic ( to deal with .txd files )
   7zip ( to archive in .7z the files for vcmp )

__1st STEP_____________
We are going to export the object we wanna light up.
(using MEd)

__2nd STEP_____________
Once we got the .dff and .txd files, we can export the
needed textures out of the .txd (as .PNG)
(as I said, we need only the windows, so we will get rid of
the rest of the object, later)

The easiest and fastest way is to guess what textures
you need, by looking at the object itself and the .txd file.
(so you extract the textures you see)

__3rd STEP_____________
We take every texture apart and edit it.
(lighting up, cutting)
All we care about are the windows, so that's all we gonna
Ok, I did that in the pause, so here is the result.
(but I also kept the lighted up .png textures, because
Blender won't load textures with transparency)
((renamed the .dff and .txd as we don't need conflicts))

__4th STEP_____________
Load the object in Blender.
as we can see, there is no texture loaded.
Why ? because we also renamed the original textured.
We added the sufix "_lighted" so the model can't recognize it

We must set them, so we gonna look in the list of textures of
the model, and find our textures' names.

We found them, so now we have to remove everything else.

Now we need to select the faces we want to keep (windows part)
(( we select them with right-click and do multiple selection
by keeping SHIFT pressed down ))

Then separate them from the rest which we will delete later.
(( press 'space' key and write 'separate'.
Now, we have 2 objects. We can remove the other one
and keep the one we just created.
We can also remove anything else like collisions.
Those faces are all that matter ))

After that, we move the faces a bit.
(since we gonna spawn the new object in the same position
as our target object, we don't want them to interfere.
Just like R* did - see the image >no image< )

When we done with that, we must replace the textures with
the ones with more light on.
^ we already did that, earlier.

We must now paint the 'Vertex' of the object in bright white
otherwise, the object won't be bright.
they are lighted windows afterall; they must be as visible
as posible.

Then, we export the .dff
(( if you get such error, then there are some textures
registered but not used, with no textures, or something like
that. We just remove them ))

Done. The export gave no errors anymore.

__5th STEP_____________
We archive the .dff and .txd into an .7z with sufix "_unp"
(like "myname_unp.7z") and place it inside store directory.
Then we register the object inside store/objects/
(( use flag 8 for objects with transparency ))
And create a static object inside store/maps/

Now, since we did everything, we can join the server and
see our work ;p

Registering the object in store/objects/
<object id="0">
<flags value="8"/>
<collision type="none"/>
<texture path="night_windows.txd"/>
<model path="wshbuildws20_nt.dff" distance="1000" />
<time on="20" off="5"/>

Spawning the object as a static one, via .xml, in store/maps/
<item model="6000" name="wshbuildws20_nt">
<position x="-39.41270447" y="-1106.622192" z="14.09233856" />
<rotation format="axisangle" x="0" y="0" z="0.7071067691" angle="0.7071067691" />

As the title say, /recordkey seems to crash once you press a button.
@Xmair confirmed that it is not working in rel004 either.

Follow the instructions on the video!

We need to change world. iD for them to update
#32 was fixed once and forever !
You can start using it again if you want.

Meanwhile, wiki is still down, so keep using: AdTec wiki (current) or Thijn wiki (outdated)

Tried to join a server from the list, but game didn't launch?

[spoiler=READ THIS]

Your Vice City is clean, Single Player works, but cannot join to any server?
Then your gta_vc.exe must be the wrong version!
You should use Version 1.0 .

If you have it, but it still not works, try this:
Try this patch:

Credits for the fix find: @Rahil [/spoiler]

Browser CRASH after UPDATE fail ?!

[spoiler=READ THIS]

Getting CRASH after VC:MP updater fails ? SEE THIS!

I think the problem is the updater link only, so we need a working one: Thijn's !
But, in order to change it, we need to open browser, which we can't.
This being said, you can change Settings.uft file with mine, which have fixed update link.

1.Go to %LOCALAPPDATA%\Vice City Multiplayer\browser
2.Replace Settings.uft with the one in archive!

After this change, you must set your Nickname and VC's path again.

Facing this error?
Cannot access the masterlist ?

The Update URL Link is down, for some reason, and will be back up when developers are back.
Until then, we are using a mirror link.
Go to Tools->Settings and change that Updater URL with:

Also the Masterlist URL has a mirror:
BUT default Masterlist is working now, so you should stick to !

All of this, thanks to @Thijn

PS:  Thijn also has a mirror for the wiki:

And here is the complete backup of wiki,  by AdTec!

Tutorials / Record cool frames, all alone!
Oct 03, 2019, 10:58 AM
Here is a short tutorial where I show and explain how you can record yourself,
from different angle, like somebody else is recording you !

There is no big deal, actually, but you can take one of the best frames. ;)
Keep Drifting! video was recorded just like that.

Long story, short ?
Just run 2 instances of VC:MP, in windowed mode, and start (fraps?) recording from the one with different angle.
Then return to your first screen where you have full control, and do your magic


While I was working on the Hydraulics' Alternative, I've found some handling settings that improve Cuban's Drifting ability.
In the past, I've used only downloaded handling - but now, I got my own.

Why is mine better than others' ? Because mine can be used in any type of server. (even RPG)
It's not based on increasing speed to the vehicle, so it will not look out of space.
It fits any background!

[spoiler=Default Cuban Hermes .XML]
<?xml version="1.0" encoding="ASCII"?>
<name>Cuban Hermes</name>














vehicle.SetHandlingData( 9, 0.5 ); // Traction Multiplier
vehicle.SetHandlingData( 11, 0.6 ); // Traction Bias
vehicle.SetHandlingData( 14, 30 ); // Acceleration
vehicle.SetHandlingData( 17, 40 ); // Brake Deceleration

PS: For the bridge neons, credits go to @PerikiyoXD !
REUPLOADED! jump to min1 - boring introduction

Playing with handlings, I got some good drifting one and started to play.
Wanted to check other players' videos about drifting, but guess what !?
There are not many, and not even that watchable.

What about provoking you guys to showoff your skills in drifting ?
@Hanney , you are not too old for this sh*t! Show us what you have got!

PS: Waiting reply, Honney!
PS2: Will upload the handling later today.

Hydraulics' Alternative
"  I'm presenting you the future  "

Synced, enabled by a command, actioned by keys
Best alternative to Voodoo's Hydraulics, inspired by SA*
Customizable anti-spam is implemented, to avoid chaos-makers (or not :P )
NUMPAD 8, 5, 4 and 6 are used for Front, Rear, Left and Right leans.
Shift is used to increase vehicle's height.*

[spoiler=Instalation guide]
1.Registering locals, usually in the top of the script
local shift = BindKey( true, 0x10, 0, 0 );
local num8 = BindKey( true, 0x68, 0, 0 );
local num4 = BindKey( true, 0x64, 0, 0 );
local num6 = BindKey( true, 0x66, 0, 0 );
local num5 = BindKey( true, 0x65, 0, 0 );

/*     Hydraulics System done by Sebastian!     */
/*     Don't change the settings - too risky       */

local hyd_top = 2.4, // high level - actioned when pressing SHIFT - set 0 to remove the uppering (safer gameplay)
hyd_z = -0.1, // Centre of Mass Z
hyd_zl = 0.7, // Upper Limit variation -
hyd_lean = 1.4, // front lean
hyd_oplean = -1.4, // rear lean
hyd_side = 0.5, // right lean
hyd_opside = -0.5, // left lean
hyd_mark = -0.001, // trick
hyd_25 = array( 1000, 0 ), // had to do with the UpperLimit variation
hyd_ticks = array( 100, 0 ), // anti-spam of everyplayer
hyd_tickslimit = 600; // interval of time a player can bounce again (in miliseconds)

2. This goes under onPlayerJoin( player ) to reset player's ticks count
function onPlayerJoin( player )
hyd_ticks[ player.ID ] = 0;

3. This goes under onPlayerCommand( player, cmd, text )
switch( cmd )
case "hydraulics":
if( !player.Vehicle ) return MessagePlayer( "[#00AAAA]Error - You must be driving a car!", player );
else if( player.VehicleSlot != 0 ) return MessagePlayer( "[#00AAAA]Error - Only the driver can action the hydraulics!", player );

local veh = player.Vehicle,
z = veh.GetHandlingData( 7 );

if( z != hyd_z )
veh.ResetHandlingData( 20 );
hyd_25[ veh.ID ] = hyd_zl;
veh.SetHandlingData( 20, hyd_25[ veh.ID ] );
veh.SetHandlingData( 7, hyd_z );

MessagePlayer( "[#00FFFF]Hydraulics were enabled !", player );
hyd_25[ veh.ID ] = 0;
veh.ResetHandlingData( 20 );
veh.ResetHandlingData( 7 );
MessagePlayer( "[#00AAAA]Hydraulics were disabled !", player );

veh.AddSpeed( Vector( 0, 0, 0 ) ); // used for the handling rule 24 to take effect

4. Telling buttons what to do 8) via onKeyDown( player, key )
switch( key )
case shift:
case num8:
case num5:
case num4:
case num6:
if( !player.Vehicle ) return 0;
else if( player.VehicleSlot != 0 ) return 0;
else if( hyd_25[ player.Vehicle.ID ] == 0 ) return 0;
else if( ( GetTickCount() - hyd_ticks[ player.ID ] ) < hyd_tickslimit ) return 0;

local veh = player.Vehicle,
low = veh.GetHandlingData( 20 ),
val6 = veh.GetHandlingData( 6 ),
val5 = veh.GetHandlingData( 5 );

hyd_ticks[ player.ID ] = GetTickCount();
PlaySound( veh.World, 336, veh.Pos );

switch( key )
case shift:
if( low < hyd_top ) veh.SetHandlingData( 20, hyd_top );
else veh.SetHandlingData( 20, hyd_25[ veh.ID ] );

veh.AddSpeed( Vector( 0, 0, 0 ) );

case num8: // front
case num5: // rear
if( low < hyd_top )
if( key == num8 ) return veh.SetHandlingData( 6, val6 + hyd_oplean );
else return veh.SetHandlingData( 6, val6 + hyd_lean );
veh.SetHandlingData( 20, hyd_25[ veh.ID ] + hyd_mark );
veh.AddSpeed( Vector( 0, 0, 0 ) );
if( key == num8 ) return veh.SetHandlingData( 6, val6 + hyd_lean );
else return veh.SetHandlingData( 6, val6 + hyd_oplean );

case num4: // left
case num6: // right
if( low < hyd_top )
if( key == num4 ) return veh.SetHandlingData( 5, val5 + hyd_side );
else return veh.SetHandlingData( 5, val5 + hyd_opside );
veh.SetHandlingData( 20, hyd_25[ veh.ID ] + hyd_mark );
veh.AddSpeed( Vector( 0, 0, 0 ) );
if( key == num4 ) return veh.SetHandlingData( 5, val5 + hyd_opside );
else return veh.SetHandlingData( 5, val5 + hyd_side );

5. Last step takes us to onKeyUp( player, key )
switch( key )
case num8: // front
case num5: // rear
case num4: // left
  case num6: // right
if( !player.Vehicle ) return 0;
else if( player.VehicleSlot != 0 ) return 0;
else if( hyd_25[ player.Vehicle.ID ] == 0 ) return 0;

local veh = player.Vehicle,
low = veh.GetHandlingData( 20 ),
deflow = hyd_25[ veh.ID ];

if( low == ( deflow + hyd_mark ) )
veh.SetHandlingData( 20, hyd_top );
if( key == num8 || key == num5 ) return veh.ResetHandlingData( 6 );
else return veh.ResetHandlingData( 5 );
if( key == num8 || key == num5 ) return veh.ResetHandlingData( 6 );
else return veh.ResetHandlingData( 5 );

PS: It could be a lot better/more real, but there is some bug happening due vc:mp or vc engine, so I couldn't use the method I've used in this video.
PS2: Not all vehicles will respond properly to this alternative, so be careful. Will try to find what's bothering other vehicles...
PS3: Because I was forced to use handling rule 24 instead of 25, vehicle can be more sensible when highered (after pressing shift). In order to remove the uppering, set hyd_top to 0 and that's it.
Missing Voodoo's hydraulics ? Here they are, synced !

Will share the code with you within a week.
I just need to do some more testing and adjustments.

I've made this post so I can share what I've found, with you.
Don't know how many of you know, but you can play with the engine more than R* did when about special features of vehicles.
Didn't test too much, but will update when I have news.
Also, if you have your own discoveries, feel free to share. Will put it in the list.

Handling.cfg explained:

Flags calculator:
Original Author: @maxorator
Modified by: @MEGAMIND

1. Emergency Lights/Taxi Light can be used even if the vehicle is not properly categorized

Take the Flying Delly as example.
All you need to do, is adding this <specials></specials> category and play with the settings inside, like colors, position, if the lights should be turned on all the time or not, etc
[spoiler=Taxi Light]

[spoiler=Police style]


[spoiler=FBI style]


2. Heli weapons will work only with heli flags, in .xml

Simple: Even with the weapons code inserted, weapons won't be active, if you use different flags than heli's.
So, in order to use Hunter's weapons, you gonna add heli's flags + specials + helidata.
Then, via script, you can play how much you want with the flags, because when you gonna reset the flags to heli's, weapons will be still working.

Heli's flags:
<flags>08028000</flags>[spoiler=Hunter's settings]


[spoiler=Sea Sparrow's settings]


3. RC Vehicles and Boats ALL vehicles are looping their animations!

So ? Well, try setting animation 0 of group 0, while being inside a vehicle. Your player will start walking without stopping :P

Maybe developers can follow this method of looping animations, for some proper function ?!

4. SA vehicles imported to VC:MP won't lose their wheels :c (like this)

If your custom vehicle follows SA's .dff example, then you won't be able to remove the wheel. 
with vehicle.SetTyre( tyre, status ) e.g. vehicle.SetTyre( 0, 2 )
SA's .dff way ?? Yeah. SA engine needs just one wheel for a vehicle, in the .dff.
Then, in game, it just duplicates it to all the needed spots.

SanAndreas vs ViceCity

5. Custom vehicles return no handling data (when GetHandlingRule or vehicle.GetHandlingData)

Unfortunately, server is not taking the info out of our .7z archives;
here is a work-around:

Note: Don't play with handling rule 8, because no matter value you will set, vehicle will go directly to Vector(0,0,0) when touching the water/sea.

6. EXTRA FLAGS can go in mix with other features!

YES! A day ago I've found out that a vehicle with Hunter properties can also get the TANK's rocket in the same time !
And you can also go for hermes' flames too, mixed with firetruk's water splashing, and anything else you want!

My luck ? The vehicle I was testing, was having this in the XML
Seems like, without this, the extra flags won't be activated.
- 00000001h - SIREN
- 00000002h - HYDRAULICS
- 00000004h - BARON
- 00000008h - BFROTATION
- 00000010h - EXHAUST
- 00000020h - ENGINEFLAP
- 00000040h - TANK
- 00000080h - FIRETRUCK
- 00000100h - AI_POLICE
- 00000200h - AI_SWAT
- 00000400h - AI_PREDATOR
- 00000800h - AI_TANK
- 00001000h - AI_BARRACKS
- 00002000h - AI_FBI
- 00004000h - AI_VICE
- 00008000h - AI_FIRETRUCK
- 00010000h - AI_AMBULANCE
- 00020000h - AI_TAXI
- 00040000h - RCAUDIO
- 00080000h - REVBEEP
- 00100000h - GEARTHUD
- 00200000h - NOMAXALTITUDE

[spoiler=Hunter weps + tank explosion]


[spoiler=Jetpack with real flames]


7. We can add more working blades than we are used to

Thanks the trick number 6 we can add even the "skimmer" blade and make it work, just by activating extra flag:
00000008h - BFROTATIONUnfortunately, VC's engine is forcing some of the blades to stick to the middle of the model

  • you cannot mix lights styles (e.g.: taxi light with some emergency lights)
  • light style + heli weapons is posible
  • you can use special lights on helicopters too - don't know about the others, but it must work also. (boat tested, but no lights shown up)
  • even if you trick the flags, like I did with the Flying Delly, you cannot make weapons work when vehicle is a car.
    It must be helicopter.

[spoiler=Gallery] - helicannon + lights

<author></author> setting acutally does something,
so when using downloaded vehicles in your server, don't forget to add the setting and the name.