Vice City: Multiplayer

VC:MP Discussion => Support => Tutorials => Topic started by: Sebastian on Mar 08, 2021, 12:59 PM

Title: [work-around fix] Custom Vehicles return no handling
Post by: Sebastian on Mar 08, 2021, 12:59 PM
If you have ever added a custom vehicle in your server, and later tried to edit it's handling, you know for sure that
Custom Vehicles return no handling data

This happens because server is not taking the info out of yourcars.7z, so it will always return 0 when tring to read some handling rule/data.
If you played long enough with handlings, you could notice that once you vehicle.SetHandlingData, then vehicle.GetHandlingData will return the value you just setted earlier.

So what this means? We must load the handling everytime we create a new vehicle, no ?
No.

There is SetHandlingRule (http://wiki.adtec.ovh/wiki/Scripting/Squirrel/Functions/SetHandlingRule) which sets the handling of the model and not the vehicle instance!
"Yeah, but we knew this already. What's the thing with it?!"
Well, here comes the magic. If you set it once, then all the vehicles with that model will get the wanted handling, and return the correct values whenever using GetHandlingRule( model, rule ) or vehicle.GetHandlingData( rule ).

(the work-around) Personally, I'm setting all the Handling Rules when server stars. This way, no matter when I want to create a new vehicle during the gameplay, it will get the presetted handlings by "default", and I will be able to play with it's handling data however I want.
Even vehicle.ResetHandlingData( rule ) will return back to the value you setted through SetHandlingRule( model, rule, val ), so it is a very safe alternative.

Here is a function example of how it should work:
[noae][noae]function RegisterHandling( model, path )
{
    print( "Registering handling " + model + " from " + path );

        local file = ReadTextFromFile( path );
       
        local   bias = GetBetweenEvery( file, "<bias>", "</bias>" ),
                x = GetBetweenEvery( file, "<x>", "</x>" ),
                y = GetBetweenEvery( file, "<y>", "</y>" ),
                z = GetBetweenEvery( file, "<z>", "</z>" ),
                drivetype = GetBetween( file, "<drivetype>", "</drivetype>" ),
                enginetype = GetBetween( file, "<enginetype>", "</enginetype>" );

        if( drivetype == "4" ) drivetype = 52;
        else if( drivetype == "F" ) drivetype = 70;
        else if( drivetype == "R" ) drivetype = 82;

        if( enginetype == "P" ) enginetype = 80;
        else if( enginetype == "D" ) enginetype = 68;
        else if( enginetype == "E" ) enginetype = 69;
       
        SetHandlingRule( model, 1, GetBetween( file, "<mass>", "</mass>" ).tofloat() );
        if( x.len() == 2 )
        {
            // dimensions
            SetHandlingRule( model, 2, x[0].tofloat() );
            SetHandlingRule( model, 3, y[0].tofloat() );
            SetHandlingRule( model, 4, z[0].tofloat() );

            // centre of mass
            SetHandlingRule( model, 5, x[1].tofloat() );
            SetHandlingRule( model, 6, y[1].tofloat() );
            SetHandlingRule( model, 7, z[1].tofloat() );
        }
        else
        {
            SetHandlingRule( model, 5, x[0].tofloat() );
            SetHandlingRule( model, 6, y[0].tofloat() );
            SetHandlingRule( model, 7, z[0].tofloat() );
        }
        // SetHandlingRule( model, 8, GetBetween( file, "<percentsubmerged>", "</percentsubmerged>" ).tofloat() ); // at the moment, it is buggy to set this value. (vehicles will teleport when touching water)
        SetHandlingRule( model, 9, GetBetween( file, "<multiplier>", "</multiplier>" ).tofloat() );
        SetHandlingRule( model, 10, GetBetween( file, "<loss>", "</loss>" ).tofloat() );
        SetHandlingRule( model, 11, bias[0].tofloat() );
        SetHandlingRule( model, 12, GetBetween( file, "<numofgears>", "</numofgears>" ).tofloat() );
        SetHandlingRule( model, 13, GetBetween( file, "<maxspeed>", "</maxspeed>" ).tofloat() );
        SetHandlingRule( model, 14, GetBetween( file, "<acceleration>", "</acceleration>" ).tofloat() );
        SetHandlingRule( model, 15, drivetype.tofloat() );
        SetHandlingRule( model, 16, enginetype.tofloat() );
        SetHandlingRule( model, 17, GetBetween( file, "<deceleration>", "</deceleration>" ).tofloat() );
        SetHandlingRule( model, 18, bias[1].tofloat() );
        SetHandlingRule( model, 19, GetBetween( file, "<steeringlock>", "</steeringlock>" ).tofloat() ); // "<abs>", "</abs>" ).tofloat() );
        SetHandlingRule( model, 20, GetBetween( file, "<forcelevel>", "</forcelevel>" ).tofloat() );
        SetHandlingRule( model, 21, GetBetween( file, "<dampening>", "</dampening>" ).tofloat() );
        SetHandlingRule( model, 22, GetBetween( file, "<seatoffset>", "</seatoffset>" ).tofloat() );
        SetHandlingRule( model, 23, GetBetween( file, "<damagemultiplier>", "</damagemultiplier>" ).tofloat() );
        SetHandlingRule( model, 24, GetBetween( file, "<upperlimit>", "</upperlimit>" ).tofloat() );
        SetHandlingRule( model, 25, GetBetween( file, "<lowerlimit>", "</lowerlimit>" ).tofloat() );
        SetHandlingRule( model, 26, bias[2].tofloat() );
        SetHandlingRule( model, 27, GetBetween( file, "<antidive>", "</antidive>" ).tofloat() );
        SetHandlingRule( model, 28, ("0x" + GetBetween( file, "<flags>", "</flags>" )).tofloat() );
        SetHandlingRule( model, 29, GetBetween( file, "<front>", "</front>" ).tofloat() );
        SetHandlingRule( model, 30, GetBetween( file, "<rear>", "</rear>" ).tofloat() );
        SetHandlingRule( model, 31, 0.0 );
        SetHandlingRule( model, 32, 0.0 );
        SetHandlingRule( model, 33, 0.0 );
        print( ". Loaded handling for " + model );
}
[/noae][/noae]
Example: RegisterHandling( 6400, "/XMLs/mycar.xml" );
I/O Functionality thanks to @SLC ! (https://forum.vc-mp.org/?topic=6116)

So, you must have your XMLs extracted out of the .7z archives, somewhere (e.g: server/XMLs/here) in your server files, for the server to access them.
Unfortunately, I don't know how to open an archive through script, to load them directly from inside. If you know how to, land a hand ;p

PS: The only thing you should not do is using ResetHandlingRule( model, rule ), because it will return to the 'default' value: 0
PS2: SetHandlingRule( model, 8, .. ) was commented due to a weird behaviour of the game.
( no matter what value you set it, the vehicle will get teleported to Vector(0,0,0) when touching th water )
(( in order to recover things back, just use ResetHandlingData/Rule( 8 ) ))