Understanding better usages for spheres

Started by Mötley, Aug 08, 2016, 06:51 PM

Previous topic - Next topic

Mötley

Okay So I had other methods of using spheres but I hate my methods. So I went into a big hunt in script releases in VCMP and LU, then I noticed Juppi's pay n spray release in LU "Awesome/amazing scriptwriter btw".

How in the heck did he determine what sphere is what, I am mind fu$#ed. I love it though,
So with that I want to take this as a learning opportunity.

The entire script is below \/.

Please I would really love to understand his method better as well in general, I would love the learning opportunity PLEASE :D

/*
Pay'n'Spray
--------------------------------------------------
This is a script which enables Pay'n'Sprays in LU.

Author: Juppi
*/

// Settings
SPHERE_COLOUR <- ::Colour( 25, 25, 255 );
const SPHERE_RADIUS = 3.0;
const GARAGE_RADIUS = 15.0; // Garage activation radius

enum VEHICLE_TYPE
{
NORMAL, // Normal vehicles which can be re-sprayed
EMERGENCY, // Emergency vehicles
NOTFORGARAGE, // Too big/not supported vehicles
};

// Storage
const MAX_GARAGES = 3;
g_Garages <- array( MAX_GARAGES, null );


function onScriptLoad()
{
print( "Liberty Unleashed Pay'n'Spray script loaded" );

// Install the Pay'n'Sprays
InitGarages();

// Set up a constant timer to process the garages
NewTimer( ProcessGarages, 750, 0 );

return 1;
}

/*
 * A storage class for garage information.
 * This includes static data like position etc. but also the status of the garage
 */
class CPayNSpray
{
// Construct a new garage
function constructor( id, pos, campos, camlookat )
{
ID = id;
Pos = pos;
CamPos = campos;
CamLookAt = camlookat;

::CreateBlip( ::BLIP_PNS, pos );

local sphere = ::CreateSphere( pos, SPHERE_RADIUS, ::SPHERE_COLOUR );
if ( sphere )
{
sphere.Type = ::MARKER_TYPE_VEHICLE;
Sphere = sphere.ID;
}
}

// The GTA ID of this garage
ID = 0;

// Garage position used for processing.
// This is also the sphere position inside the garage
Pos = null;

// Camera settings - we don't want the camera to be inside the garage
CamPos = null;
CamLookAt = null;

// The ID of the sphere inside the garage
Sphere = 0;

// Is the garage door open or closed?
IsOpen = false;

// Is this garage processing any vehicle at the moment?
IsProcessingVehicle = false;

// How long has the vehicle been processed? (Required by some timed stuff)
Time = 0;

// The player/vehicle who/which are being processed
Player = null;
Vehicle = null;
}

/*
 * This function initialises the garages and sets their info.
 */
function InitGarages()
{
g_Garages[ 0 ] = CPayNSpray( PORTLAND_PAYNSPRAY_GARAGE, Vector( 925.3, -361.9, 10.8 ), Vector( 925.9, -335.9, 14.3 ), Vector( 925.5, -346.4, 14.3 ) ); // Portland PnS
g_Garages[ 1 ] = CPayNSpray( STAUNTON_PAYNSPRAY_GARAGE, Vector( 382.4, -493.6, 25.7 ), Vector( 362.2, -492.2, 27.8 ), Vector( 369.6, -493.0, 27.8 ) ); // Staunton PnS
g_Garages[ 2 ] = CPayNSpray( SSV_PAYNSPRAY_GARAGE, Vector( -1144.4, 35.1, 58.8 ), Vector( -1126.2, 33.6, 61.9 ), Vector( -1132.2, 33.9, 61.3 ) ); // Shoreside PnS
}

/*
 * This func finds and returns a garage based on the sphere ID
 */
function FindGarage( sphereID )
{
for ( local i = 0; i < MAX_GARAGES; i++ )
{
if ( g_Garages[ i ].Sphere == sphereID ) return g_Garages[ i ];
}

return null;
}

/*
 * Processing of the garages. Almost everything is done here, including
 * automatic doors etc.
 */
function ProcessGarages()
{
local players = GetPlayers();

if ( !players ) return; // No point in processing if there are no players in-game

// Vars used by the processing loop
local garage = null;
local player = null, id = 0, plrs = 0;
local needsopening = false;

for ( local i = 0; i < MAX_GARAGES; i++ )
{
garage = g_Garages[ i ];

// If the garage is not processing a vehicle right now, process automatic doors
if ( !garage.IsProcessingVehicle )
{
player = null;
id = 0;
plrs = 0;
needsopening = false;

while ( id < MAX_PLAYERS && plrs < players )
{
player = FindPlayer( id );
if ( player && player.Spawned )
{
// Check if the player is within the activation radius of this garage
if ( GetDistance( player.Pos, garage.Pos ) < GARAGE_RADIUS )
{
// If so, and they're in a vehicle, flag the garage to be opened after the loop
if ( player.Vehicle ) needsopening = true;
}
plrs++;
}
id++;
}

// Process the door if needed
if ( garage.IsOpen && !needsopening )
{
CloseGarage( garage.ID );
garage.IsOpen = false;
}
else if ( !garage.IsOpen && needsopening )
{
OpenGarage( garage.ID );
garage.IsOpen = true;
}
}

// If the garage is processing a car, do some timed stuff
else
{
garage.Time++;

if ( garage.Time == 6 )
{
if ( garage.Vehicle.Health < 1000.0 )
SmallMessage( garage.Player, "~b~New engine and paint job. The cops won't recognize you!", 3000, 0 );

else SmallMessage( garage.Player, "~b~Hope you like the new color.", 3000, 0 );

PlayFrontEndSound( garage.Player, 61 );

// Fix the vehicle and respray it
garage.Vehicle.Fix();

// This should create some really funky colours
garage.Vehicle.RGBColour1 = Colour( rand() % 256, rand() % 256, rand() % 256 );
garage.Vehicle.RGBColour2 = Colour( rand() % 256, rand() % 256, rand() % 256 );

// Ready! Release the player and open the door
garage.Player.Frozen = false;

RestoreCamera( garage.Player );

garage.IsProcessingVehicle = false;
garage.Player = null;
garage.Vehicle = null;
garage.Time = 0;
garage.IsOpen = true;

OpenGarage( garage.ID );
}
}
}
}

/*
 * If the player enters a sphere we need to check whether
 * it's a garage sphere
 */
function onPlayerEnterSphere( player, sphere )
{
// Check if this is a global sphere and assigned to a garage
if ( !sphere.Owner )
{
local garage = FindGarage( sphere.ID );
if ( garage )
{
local vehicle = player.Vehicle;

// Check that the event was triggered by the vehicle driver
if ( player.ID == vehicle.Driver.ID )
{
local type = GetVehicleType( vehicle.Model );
if ( type == VEHICLE_TYPE.NORMAL )
{
// This is a normal vehicle - we can respray it

// Freeze the player
player.Frozen = true;

// Set some garage stuff for the process func
garage.IsProcessingVehicle = true;
garage.Player = player;
garage.Vehicle = player.Vehicle;
garage.IsOpen = false;

SetCameraMatrix( player, garage.CamPos, garage.CamLookAt );

CloseGarage( garage.ID );
}
else if ( type == VEHICLE_TYPE.EMERGENCY )
{
SmallMessage( player, "~b~Whoa! I don't touch nothing THAT hot!", 3000, 0 );

PlayFrontEndSound( player, 60 );
}
}
}
}

return 1;
}

/*
 * Security check that the player didn't leave while they were in a garage
 */
function onPlayerPart( player, reason )
{
local garage = null;
for ( local i = 0; i < MAX_GARAGES; i++ )
{
garage = g_Garages[ i ];

if ( garage.Player && garage.Player.ID == player.ID )
{
garage.IsProcessingVehicle = false;

garage.Player = null;
garage.Vehicle = null;

garage.Time = 0;
}
}

return 1;
}

/*
 * This function returns the type of the given vehicle model
 */
function GetVehicleType( model )
{
switch ( model )
{
// These vehicles are too big/otherwise not suitable for Pay'n'Spray. Don't process them
case VEH_LINERUNNER:
case VEH_TRASHMASTER:
case VEH_STRETCH:
case VEH_PREDATOR:
case VEH_BUS:
case VEH_TRAIN:
case VEH_DODO:
case VEH_COACH:
case VEH_RCBANDIT:
case VEH_AIRTRAIN:
case VEH_DEADDODO:
case VEH_SPEEDER:
case VEH_REEFER:
case VEH_ESCAPE:
case VEH_GHOST:
return VEHICLE_TYPE.NOTFORGARAGE;
break;

// Emergency/army vehicles - Pay'n'Spray don't want to touch nothing that hot
case VEH_FIRETRUCK:
case VEH_AMBULANCE:
case VEH_FBICAR:
case VEH_POLICE:
case VEH_ENFORCER:
case VEH_RHINO:
case VEH_BARRACKS:
return VEHICLE_TYPE.EMERGENCY;
break;

// Everything else is OK
default:
return VEHICLE_TYPE.NORMAL;
break;
}
}

Thijn

He saves the sphere ID in a variable inside the class.

So basically:

gSpheres <- array( 1, null );

gSpheres[0] = testSpheres();

class testSpheres
{
sphereId = 0;
function constructor()
{
local sphere = ::CreateSphere( pos, someradius, somecolor);
  if ( sphere )
  {
   sphereId = sphere.ID;
  }
}
}

Then you can do gSpheres[0].sphereId to get the ID.

Code is copy pasted, and probably doesn't work because how spheres are made, parameters all that shit. It should give you an idea though.

Mötley

Thank you This did give me a better idea/comprehension.


    The last idea I am trying to understand is to be capable of spiting things off,

    Like a bomb shop,

    Or even setting a camera matrix and putting that player in a virtual world similar to MTA for gta 3 for buying weapon options.

    In that case would I have to use something like
    [/list][code]function onPlayerEnterSphere(player, sphere) {
    if (sphere.ID == 0 ) {
    etc etc

     or is there a more professional way to specify the spheres

    ysc3839

    I want to know how to implement Open/CloseGarage.

    Mötley

    @ysc3839

    http://forum.vc-mp.org/?topic=2472.msg18087#msg18087



    @Thijn I still do not know how to use correct methods of many spheres and specifying them to there correct ones. So instead with pay n sprays I removed spheres and now I am checking if that player is in the vicinity, if so process the garage. "Loop methods, ;D it's not laggy as your mind would imagine, It's actually pretty clean"

    This is more professional in general as even Rockstar-North does not use spheres in the PNS :D.


    I'm going to attempt to continue to not use spheres for garages etc. Instead use spheres for there correct usages, like virtual worlds.