[Include] PHY.inc [originally by adri1]
#1

PHY.inc
This include gives you functions to move various kinds of stuff (objects, vehicles, textdraws, etc...) like a physical movement. So you could give your server more "realistic" appearance.
The experimental filterscript was originally created by adri1, I make it functional by adding new things.
Original code: https://sampforum.blast.hk/showthread.php?tid=592930

First I'll show the functions and macros, later I'll show some example codes.
  • Functions
There's 26 functions and 2 callbacks:

pawn Код:
native PHY_Create(type_id, Float:fX, Float:fY, Float:fZ);
native PHY_Finish(slotid);
native PHY_Start(slotid, mode = PHY_MODE_LAUNCH, interval = 20);
native PHY_SetPos(slotid, Float:fX, Float:fY, Float:fZ);

native PHY_SetMode(slotid, mode);
native PHY_SetType(slotid, type);
native PHY_SetTypeID(slotid, type_id);
native PHY_SetSpeed(slotid, Float:speed);
native PHY_SetAcc(slotid, Float:acceleration);
native PHY_SetAngle(slotid, Float:angle);
native PHY_SetHeightAngle(slotid, Float:h_angle);
native PHY_SetBound(slotid, Float:bound);
native PHY_RestarMovement(slotid);

native PHY_GetMode(slotid);
native PHY_GetType(slotid);
native PHY_GetTypeID(slotid);
native PHY_GetTick(slotid);
native PHY_GetSpeed(slotid);
native PHY_GetAcc(slotid);
native PHY_GetAngle(slotid);
native PHY_GetHeightAngle(slotid);
native PHY_GetBound(slotid);

native PHY_Init();
native PHY_Stop();
native PHY_IsValid(slotid);
native PHY_GetPoolSize();

forward PHY_OnUpdate(slotid, Float:fX, Float:fY, Float:fZ, Float:speed, tick, direction);
forward PHY_OnFinish(slotid, Float:fX, Float:fY, Float:fZ, Float:speed, tick);

Main functions:
PHY_CreateSearch an unused slot for start a new movement.
  • Parameters:
    • type_id - the type ID of what we want to move (objectid, vehicleid, etc...)
    • fX, fY, fZ - the start coordinates
  • return: the slotid found
PHY_FinishFinish a movement.
  • Parameters:
    • slotid - the slotid of movement we want to finish
  • return: 1
PHY_StartStart a movement
  • Parameters:
    • slotid - the slotid we want to start
    • mode = PHY_MODE_LAUNCH - mode of movement
    • interval = 20 - interval (in mms) for update ALL the existent movements (only works if the update timer wasn't started)
  • return: 1
PHY_SetPosSet a new position for a movement.
  • Parameters:
    • slotid - the slotid we want to set the new pos.
    • fX, fY, fZ - coordinates.
  • return: 1
PHY_InitInit the include. This function must be processed before ANY other PHY's functions.
  • Parameters:
    • -this functions doesn't handle parameters-
  • return: -
PHY_StopStop the timer that updates all existent movements.
  • Parameters:
    • -this functions doesn't handle parameters-
  • return: -
PHY_IsValidCheck if a slot it's being used.
  • Parameters:
    • slotid - the slotid to check.
  • return: 1 if yes, 0 if not.
PHY_GetPoolSizeGet the last slot using.
  • Parameters:
    • -this functions doesn't handle parameters-
  • return: the last valid slot.

The next functions just have two parameters (PHY_Set*(slotid, ...)) and never return values:
PHY_SetMode
  • mode - Set the movement mode (none, launch, roll, vertical). I'll explain this later.
PHY_SetType
  • type - Set the type of what we want to move (objects, vehicles, textdraws, ...)
PHY_SetTypeID
  • type_id - Set the ID of what we want to move (objectid, vehicleid, etc...)
PHY_SetSpeed
  • Float: speed - Set the initial speed.
PHY_SetAcc
  • Float:acceleration - Set the acceleration(+)/deceleration(-) of the movement
PHY_SetAngle
  • Float:angle - Set the angle direction.
PHY_SetHeightAngle
  • Float:h_ang - Set the height angle (vertical angle).
PHY_SetBound
  • Float:bound - Set the bound of the movement. In "Roll Mode", the bound is the maximun distance it can cover. In others modes, the bound is the the Z position (minimun).
PHY_RestarMovement
  • - This function just have one parameter (slotid). This restart the movement (start since 0 - useful for movements with non-end).

The next functions only have one parameter (PHY_Get*(slotid)) and return the value setted by "PHY_Set*(slotid, *)":
PHY_GetMode
  • Returns the movement mode.
PHY_GetType
  • Returns what are moving.
PHY_GetTypeID
  • Returns the ID of what is moving.
PHY_GetSpeed
  • Returns the initial speed.
PHY_GetAcc
  • Returns the acceleration/deceleration.
PHY_GetAngle
  • Returns the angle direction
PHY_GetHeightAngle
  • Returns the height angle.
PHY_GetBound
  • Returns the bound (in roll mode; maximun distance, in others mode: bound Z minimun).

Callbacks:
PHY_OnUpdateIs called when all movements are updated.
  • Parameters:
    • slotid - the slotid of the updated movement.
    • Float: fX, fY, fZ - the new coords.
    • Float: speed - the current speed (by now, just works in "Roll Mode").
    • tick - the time (in mms) lapsed.
    • direction - the movement direction (PHY_DIRECTION_UP/DOWN).
PHY_OnFinishIs called when the movement is finished. Direction ever will be "PHY_DIRECTION_DOWN".
  • Parameters:
    • slotid - the slotid of the finished movement.
    • Float: fX, fY, fZ - the new coords.
    • Float: speed - the final speed. In "LaunchMode" & "VerticalMode", the final speed is equal to the initial speed.
    • tick - the lapsed time (in mms)
  • Macros
    • Limits:
      • PHY_MAX_SLOTS - amount of slots. (default is "50").
    • Accelerations:
      • PHY_GRAVITY - Acceleration by gravity (9.81m/seg2)
      • PHY_FRICTION - Default acceleration (5.0m/seg2)
    • Movement modes:
      • PHY_MODE_NONE - Nothing. The movement won't be updated.
      • PHY_MODE_LAUNCH - Parabolic movement.
      • PHY_MODE_ROLL - Orizontal movement.
      • PHY_MODE_VERTICAL - Vertical movement or free fall.
    • Types:
      • PHY_TYPE_NONE - Nothing.
      • PHY_TYPE_OBJECT - Move a object.
      • PHY_TYPE_VEHICLE - Move a vehicle.
      • PHY_TYPE_PLAYER - Move a player.
      • PHY_TYPE_NPC - Move a NPC. This type has a bad sync.
      • PHY_TYPE_ACTOR - Move an actor, you may get problems with many actors moving at same time (ackslimit issues!).
      • PHY_TYPE_PICKUP - Move a pickup. This type has a bad sync (but can be fixed (see examples!))
      • PHY_TYPE_TEXTDRAW - Move a textdraw.
    • Directions:
      • PHY_DIRECTION_UP - The movement is getting heigth (up)
      • PHY_DIRECTION_DOWN - The movement is losing heigth (down)

Example codes:

1. Create a parabolic movement, simple. Using a object:
pawn Код:
CMD:launch(playerid)
{
    new slotid = PHY_Create(0xFFFF, 0.0, 0.0, 2.33); // Search a free slot. If nothing is found, it will return "-1".
    // Put "0xFFFF" as "type_id" because we don't know if we found a freeslot.
    // Relax, later we will set the objectid with "PHY_SetTypeID".
   
    // Check if a free slot wasn't found (and so avoid a possible crash)
    if(slotid == -1) return SendClientMessage(playerid, 0xFF0000FF, "[<!>] There's not free slots. Try later.");

    new objectid = CreateObject(1946, 0.0, 0.0, 2.33, 0.0, 0.0, 0.0); // Create a basket ball

    // A free slot has been found
    PHY_SetType(slotid, PHY_TYPE_OBJECT); // We'll move a object
    PHY_SetTypeID(slotid, objectid); // We'll move what "objectid" returned.
    PHY_SetSpeed(slotid, 15.0); // Set an initial speed of 10.0 m/seg2
    PHY_SetAcc(slotid, -PHY_GRAVITY); // Set an acceleration (in this case, as it's negative it's an deceleration). As is "LaunchMode", is deceleration by gravity.
    PHY_SetAngle(slotid, 90.0); // Set a direction angle of 90°
    PHY_SetHeightAngle(slotid, 45.0); // Set an height angle of 45° (will cover the maximun distance possible).
    PHY_SetBound(slotid, 2.33); // Set a bound. On this case Z limit.
    // Still the movement wont be updated. We have to use "PHY_Start".
    PHY_Start(slotid, PHY_MODE_LAUNCH); // Start the movement in "LaunchMode".
    return 1;
}
2. roll a ball.
pawn Код:
CMD:roll(playerid)
{
    new slotid = PHY_Create(objectid, 0.0, 0.0, 2.33);
    if(slotid == -1) return SendClientMessage(playerid, 0xFF0000FF, "[<!>] There's not free slots. Try later.");

    new objectid = CreateObject(1946, 0.0, 0.0, 2.33, 0.0, 0.0, 0.0);
   
    PHY_SetType(slotid, PHY_TYPE_OBJECT);
    PHY_SetTypeID(slotid, objectid);
    PHY_SetSpeed(slotid, 10.0); // Set an initial speed of 10.0 m/seg2
    PHY_SetAcc(slotid, -PHY_FRICTION); // Set a deceleration of 5.0m/seg2. If the value is positive, the object "increases" his speed, else it decrease.
    PHY_SetAngle(slotid, 90.0); // Set an angle direction
    PHY_SetHeightAngle(slotid, 0.0); // We don't need this value
    PHY_SetBound(slotid, 3000.0); // Set the maximun distance this can cover. We use "3000" for be sure that this will cover all his possible distance.
    PHY_Start(slotid, PHY_MODE_ROLL); // And the ball is rolling :P
    return 1;
}
On these examples, object's position must be updated manually, and too when we want to stop the movement.
pawn Код:
public PHY_OnUpdate(slotid, Float:fX, Float:fY, Float:fZ, Float:speed, tick, direction)
{
    if(PHY_GetType(slotid) == PHY_TYPE_OBJECT)
    {
        SetObjectPos(PHY_GetTypeID(slotid), fX, fY, fZ);
    }
    return 1;
}

public PHY_OnFinish(slotid, Float:fX, Float:fY, Float:fZ, Float:speed, tick)
{
    PHY_Finish(slotid);
    return 1;
}

3. launch a missile on vertical direction and up, later when the object tries to fall we make him to explode!
pawn Код:
CMD:misil(playerid)
{
    SetPlayerTime(playerid, 0, 0);
   
    new slotid = PHY_Create(0xFFFF, 0.0, 0.0, 2.33);
    if(slotid == -1) return SendClientMessage(playerid, 0xFF0000FF, "[<!>] There's not free slots. Try later.");

    new objectid = CreateObject(345, 0.0, 0.0, 2.33, 90.0, 0.0, 0.0);
    PHY_SetType(slotid, PHY_TYPE_OBJECT);
    PHY_SetTypeID(slotid, objectid);
    PHY_SetSpeed(slotid, 25.0);
    PHY_SetAcc(slotid, -PHY_GRAVITY);
    PHY_SetAngle(slotid, 0.0); // We don't need this value
    PHY_SetHeightAngle(slotid, 0.0); // We don't need this value
    PHY_SetBound(slotid, 2.33);
    PHY_Start(slotid, PHY_MODE_VERTICAL);
    return 1;
}

public PHY_OnUpdate(slotid, Float:fX, Float:fY, Float:fZ, Float:speed, tick, direction)
{
    if(PHY_GetType(slotid) == PHY_TYPE_OBJECT)
    {
        SetObjectPos(PHY_GetTypeID(slotid), fX, fY, fZ);

        if(direction == PHY_DIRECTION_DOWN) The object is falling, this means that the object arrived at his maximum height possible
        {
            DestroyObject(PHY_GetTypeID(slotid)); // Destroy the object
        PHY_Finish(slotid); // End movement
        CreateExplosion(fX, fY, fZ, 6, 25.0);
    }
    }
    return 1;
}

Thats are just some examples of what you can do with this include. You can make a lot of things, just imagine them!
Here is some examples more:

- PHY_TYPE_OBJECT:
pawn Код:
/* PHY.inc - @misil_launcher

    * 1 object (misil).
    * Handle a MP5, look at where you want the misil go, and press N key.
*/


#include <a_samp>
#include <PHY>


public OnFilterScriptInit()
{
    PHY_Init();
    return 1;
}

public OnPlayerSpawn(playerid)
{
    GivePlayerWeapon(playerid, WEAPON_MP5, 1000);
    return 1;
}

public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
    if(newkeys & KEY_NO && GetPlayerWeapon(playerid) == WEAPON_MP5)
    {
    new Float:Pos[3], Float:VectZ, Float:angle, Float:h_ang;

    GetPlayerCameraPos(playerid, Pos[0], Pos[1], Pos[2]);
    GetPlayerCameraFrontVector(playerid, VectZ, VectZ, VectZ);
    Pos[2] += 3.5;
    h_ang   = atan2((Pos[2] + VectZ) - Pos[2], 1.0) + 15.0;

    GetPlayerPos(playerid, Pos[0], Pos[1], Pos[2]);        
        GetPlayerFacingAngle(playerid, angle);

    new objectid = CreateObject(345, Pos[0], Pos[1], Pos[2], h_ang, 0.0, angle, 150.0);
    new slotid = PHY_Create(objectid, Pos[0], Pos[1], Pos[2]);
    PHY_SetType(slotid, PHY_TYPE_OBJECT);
    PHY_SetSpeed(slotid, 30.0);
    PHY_SetAngle(slotid, angle);
    PHY_SetHeightAngle(slotid, h_ang);
    PHY_SetBound(slotid, Pos[2] - 1.5);
    PHY_SetAcc(slotid, -PHY_GRAVITY);
    PHY_Start(slotid, PHY_MODE_LAUNCH);
        return 1;
    }    
    return 1;
}

/* PHY.inc */
public PHY_OnUpdate(slotid, Float:fX, Float:fY, Float:fZ, Float:speed, tick)
{
    if(PHY_GetType(slotid) == PHY_TYPE_OBJECT)
    {
        SetObjectPos(PHY_GetTypeID(slotid), fX, fY, fZ);
    }
    return 1;
}

public PHY_OnFinish(slotid, Float:fX, Float:fY, Float:fZ, Float:speed, tick)
{
    CreateExplosion(fX, fY, fZ, 6, 10.0);
    DestroyObject(PHY_GetTypeID(slotid));
    PHY_Finish(slotid);
    return 1;
}

- PHY_TYPE_PICKUP:
pawn Код:
/* PHY.inc - @animed_pickup
   
    * 1 pickup (invisible object).
    * 1 object, who will do the animed pickup, because we can't use "DestroyPickup" & "CreatePickup" and that the player's
      client load them so fast as to do the effect.
*/


#include <a_samp>
#include <PHY>

static animed_pickup[2];

public OnFilterScriptInit()
{
    PHY_Init();

    animed_pickup[0] = CreatePickup(19300, 1, 0.0, 0.0, 3.0); // create a invisible pickup
    animed_pickup[1] = CreateObject(1559, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0); // create the pickup object, who will do the "anime pickup"

    new slotid = PHY_Create(animed_pickup[1], 0.0, 0.0, 3.0);
    PHY_SetSpeed(slotid, 5.0);
    PHY_SetAcc(slotid, -PHY_GRAVITY);
    PHY_SetBound(slotid, 3.0);
    PHY_SetType(slotid, PHY_TYPE_PICKUP);
    PHY_Start(slotid, PHY_MODE_VERTICAL);
    return 1;
}

public OnPlayerPickUpPickup(playerid, pickupid)
{    
    SendClientMessage(playerid, -1, "* I'm an animed pickup!");
    return 1;
}

/* PHY.inc */
public PHY_OnUpdate(slotid, Float:fX, Float:fY, Float:fZ, Float:speed, tick)
{
    if(PHY_GetType(slotid) == PHY_TYPE_PICKUP && PHY_GetTypeID(slotid) == animed_pickup[1])
    {
        SetObjectPos(PHY_GetTypeID(slotid), fX, fY, fZ);
    }
    return 1;
}

public PHY_OnFinish(slotid, Float:fX, Float:fY, Float:fZ, Float:speed, tick)
{
    PHY_RestartMovement(slotid); // Start again
    return 1;
}

- PHY_TYPE_TEXTDRAW:
pawn Код:
/* PHY.inc - @countdown
* Un countdown in textdraw. Like in NFS.
*/


#include <a_samp>
#include <ZCMD>
#include <PHY>

static Text:CountTD[2];
static Count = 3;
static CountStr[][] = {"~r~GO!", "1", "2", "3"};


public OnFilterScriptInit()
{
   PHY_Init(); // Iniciar

   CountTD[0] = TextDrawCreate(643.000000, 145.000000, "_"); // Box
   TextDrawLetterSize(CountTD[0], 4.640000, 3.900000);
   TextDrawUseBox(CountTD[0], 1);
   TextDrawBoxColor(CountTD[0], 150);
   TextDrawTextSize(CountTD[0], -4.000000, 0.000000);

   CountTD[1] = TextDrawCreate(306.000000, 139.000000, "_"); // Count
   TextDrawBackgroundColor(CountTD[1], 255);
   TextDrawFont(CountTD[1], 2);
   TextDrawLetterSize(CountTD[1], 1.330000, 4.600000);
   TextDrawColor(CountTD[1], 16777215);
   TextDrawSetOutline(CountTD[1], 1);
   TextDrawSetProportional(CountTD[1], 1);
   return 1;
}

/* Comandos */
CMD:countdown()
{
   new slotid = PHY_Create(_:CountTD[1], -5.0, 139.0, -0.0);
   PHY_SetSpeed(slotid, 500.0);
   PHY_SetAcc(slotid, -400.0);
   PHY_SetAngle(slotid, 270.0);
   PHY_SetBound(slotid, 645.0);
   PHY_SetType(slotid, PHY_TYPE_TEXTDRAW);
   PHY_Start(slotid, PHY_MODE_ROLL, 5);

   TextDrawShowForPlayer(0, CountTD[0]);
   TextDrawShowForPlayer(0, CountTD[1]);
   return 1;
}

/* PHY.inc */
public PHY_OnUpdate(slotid, Float:fX, Float:fY, Float:fZ, Float:speed, tick)
{
    if(PHY_GetType(slotid) == PHY_TYPE_TEXTDRAW && PHY_GetTypeID(slotid) == _:CountTD[1])
   {
      TextDrawDestroy(CountTD[1]);

      CountTD[1] = TextDrawCreate(fX, 139.000000, CountStr[Count]);
      TextDrawBackgroundColor(CountTD[1], 255);
      TextDrawFont(CountTD[1], 2);
      TextDrawLetterSize(CountTD[1], 1.330000, 4.600000);
      TextDrawColor(CountTD[1], 16777215);
      TextDrawSetOutline(CountTD[1], 1);
      TextDrawSetProportional(CountTD[1], 1);

      TextDrawShowForPlayer(0, CountTD[1]);
   }
   return 1;
}

public PHY_OnFinish(slotid, Float:fX, Float:fY, Float:fZ, Float:speed, tick)
{
    new Float:acc = PHY_GetAcc(slotid); // store the initial acceleration
    PHY_Finish(slotid);

    if(acc > 0.0) // if it exceed the middle of screen
    {
    if(--Count != -1) return cmd_countdown(); // restart the movement

    TextDrawHideForPlayer(0, CountTD[0]);
        TextDrawHideForPlayer(0, CountTD[1]);
        return 1;
    }

    slotid = PHY_Create(_:CountTD[1], fX, 139.0, -0.0);
    PHY_SetSpeed(slotid, 50.0);
    PHY_SetAcc(slotid, 500.0);
    PHY_SetAngle(slotid, 270.0);
    PHY_SetBound(slotid, 645.0);
    PHY_SetType(slotid, PHY_TYPE_TEXTDRAW);
    PHY_Start(slotid, PHY_MODE_ROLL, 5);
    return 1;
}

- PHY_TYPE_VEHICLE:
pawn Код:
/* PHY.inc - @vehicle
* Compete in a race against a unoccupied vehicle, using PHY_MODE_ROLL.
*/


#include <a_samp>
#include <iZCMD>
#include <PHY>

enum RaceInfo_enum
{
    TimerCount,
    CountDown,
    Rival,
    WinnerID
}
static RaceInfo[RaceInfo_enum];
static vehicle;
static Text:RacePosTD[3];

public OnFilterScriptInit()
{
    PHY_Init();

    vehicle  = CreateVehicle(411, 1205.5000, 2255.0000, 6.7500 + 1.5, 180.0000, -1, -1, -1);

    RacePosTD[0] = TextDrawCreate(612.000000, 124.000000, "_");
    TextDrawBackgroundColor(RacePosTD[0], 255);
    TextDrawFont(RacePosTD[0], 1);
    TextDrawLetterSize(RacePosTD[0], 0.500000, 9.000000);
    TextDrawColor(RacePosTD[0], -1);
    TextDrawSetOutline(RacePosTD[0], 0);
    TextDrawSetProportional(RacePosTD[0], 1);
    TextDrawSetShadow(RacePosTD[0], 1);
    TextDrawUseBox(RacePosTD[0], 1);
    TextDrawBoxColor(RacePosTD[0], 150);
    TextDrawTextSize(RacePosTD[0], 427.000000, 31.000000);

    RacePosTD[1] = TextDrawCreate(436.000000, 126.000000, "1)~n~2)~n~~n~~r~~h~META:");
    TextDrawBackgroundColor(RacePosTD[1], 255);
    TextDrawFont(RacePosTD[1], 1);
    TextDrawLetterSize(RacePosTD[1], 0.490000, 2.000000);
    TextDrawColor(RacePosTD[1], -1);
    TextDrawSetOutline(RacePosTD[1], 0);
    TextDrawSetProportional(RacePosTD[1], 1);
    TextDrawSetShadow(RacePosTD[1], 1);

    RacePosTD[2] = TextDrawCreate(596.000000, 126.000000, "_");
    TextDrawAlignment(RacePosTD[2], 3);
    TextDrawBackgroundColor(RacePosTD[2], 255);
    TextDrawFont(RacePosTD[2], 2);
    TextDrawLetterSize(RacePosTD[2], 0.350000, 2.000000);
    TextDrawColor(RacePosTD[2], -1);
    TextDrawSetOutline(RacePosTD[2], 0);
    TextDrawSetProportional(RacePosTD[2], 1);
    TextDrawSetShadow(RacePosTD[2], 1);
    return 1;
}

/* Commands */
CMD:go(playerid)
{
    new vehicleid = CreateVehicle(411, 1211.5000, 2255.0000, 6.7500 + 1.5, 180.0, 0, 0, -1);
    PutPlayerInVehicle(playerid, vehicleid, 0);
    AddVehicleComponent(vehicleid, 1010);
    return 1;
}

CMD:start(playerid)
{
    RaceInfo[TimerCount]    = SetTimer("OnCountDown", 1000, true);
    RaceInfo[CountDown]     = 3;
    RaceInfo[Rival]         = playerid;
    RaceInfo[WinnerID]      = 0xFFFF;


    GameTextForAll("~w~3", 1000, 3);
    TogglePlayerControllable(playerid, false);
    SetCameraBehindPlayer(playerid);
    SetPlayerRaceCheckpoint(playerid, 1, 1211.0000, 1195.0000, 6.5400, 1211.0, 1190.0, 6.5400, 10.0);

    TextDrawShowForPlayer(playerid, RacePosTD[0]);
    TextDrawShowForPlayer(playerid, RacePosTD[1]);
    TextDrawShowForPlayer(playerid, RacePosTD[2]);
    return 1;
}

forward OnCountDown();
public OnCountDown()
{
    switch(--RaceInfo[CountDown])
    {
        case 2: GameTextForAll("~w~2", 1250, 3);
    case 1: GameTextForAll("~w~1", 1250, 3);
    case 0:
        {
        KillTimer(RaceInfo[TimerCount]);
        GameTextForAll("~r~Go!", 1500, 3);
        for(new i = 0; i <= GetPlayerPoolSize(); i++) TogglePlayerControllable(i, true);

        new slotid = PHY_Create(vehicle, 1205.5000, 2255.0000, 6.5400);
        PHY_SetSpeed(slotid, 0.0);
        PHY_SetAcc(slotid, 2.5 + (random(15) / 10.0));
        PHY_SetBound(slotid, 1075.0); // the maximun distance it can cover
        PHY_SetAngle(slotid, 180.0);
        PHY_SetType(slotid, PHY_TYPE_VEHICLE);
        PHY_Start(slotid, PHY_MODE_ROLL, 5);
        return 1;
    }
    }
    return 1;
}

public OnPlayerEnterRaceCheckpoint(playerid)
{
    if(RaceInfo[WinnerID] == 0xFFFF)
    {
    SendClientMessage(playerid, 0x00FF00FF, "* You won!");
    GivePlayerMoney(playerid, 30000);
    RaceInfo[WinnerID] = playerid;

    DisablePlayerRaceCheckpoint(playerid);
    }
    return 1;
}

/* PHY.inc */
public PHY_OnUpdate(slotid, Float:fX, Float:fY, Float:fZ, Float:speed, tick)
{
    if(PHY_GetType(slotid) == PHY_TYPE_VEHICLE)
    {
        static vehicleid;
    vehicleid = PHY_GetTypeID(slotid);
    SetVehiclePos(vehicleid, fX, fY, fZ);
    SetVehicleZAngle(vehicleid, 180.0);

    if(PHY_GetAcc(slotid) > 0.0)
    {
        static Float:Pos[3], Float:dist[2], str[50];

        GetPlayerPos(RaceInfo[Rival], Pos[0], Pos[1], Pos[2]);
        dist[0] = VectorSize(fX - 1211.0000, fY - 1195.0000, 0.0);
        dist[1] = VectorSize(Pos[0] - 1211.0000, Pos[1] - 1195.0000, Pos[2] - 6.5400);

        GetPlayerName(RaceInfo[Rival], str, 21);
        format(str, sizeof(str), "%s~n~%s~n~~n~%0.2f", (dist[0] < dist[1]) ? ("PHY") : (str), (dist[1] < dist[0]) ? ("PHY") : (str), dist[1]);
        TextDrawSetString(RacePosTD[2], str);
    }
    }
    return 1;
}

public PHY_OnFinish(slotid, Float:fX, Float:fY, Float:fZ, Float:speed, tick)
{
    new Float:acc = PHY_GetAcc(slotid);
    PHY_Finish(slotid);

    if(acc > 0.0) // Stop the vehicle
    {
    slotid = PHY_Create(vehicle, fX, fY, fZ);
    PHY_SetSpeed(slotid, speed);
    PHY_SetAcc(slotid, -30.0);
    PHY_SetBound(slotid, 3000.0);
    PHY_SetAngle(slotid, 180.0);
    PHY_SetType(slotid, PHY_TYPE_VEHICLE);
    PHY_Start(slotid, PHY_MODE_ROLL, 20);
    }

    if(RaceInfo[WinnerID] == 0xFFFF)
    {
    SendClientMessageToAll(0x00FFFFFF, "* You lost!");
    DisablePlayerRaceCheckpoint(RaceInfo[WinnerID]);
    RaceInfo[WinnerID] = -1;

    TextDrawSetString(RacePosTD[2], "_");
    TextDrawHideForPlayer(RaceInfo[Rival], RacePosTD[0]);
    TextDrawHideForPlayer(RaceInfo[Rival], RacePosTD[1]);
    TextDrawHideForPlayer(RaceInfo[Rival], RacePosTD[2]);
    }
    return 1;
}

Download: http://pastebin.com/Q3TfxXfw

Pictures:
Reply
#2

Nice include over there, could you possibly create a new video about the new functions?
Reply
#3

Thanks you.

Sorry, I tried it and I can't create a video (my netbook doesn't support Fraps or others)
If someone want to do one, I'll add it to the main post
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)