Advertisement
TheEnforced

RealVehicles-1.0.1_samp_filterscript

Sep 19th, 2014
559
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 66.38 KB | None | 0 0
  1. // Copyright 2014 Don Walt "Enforcer"
  2. // This work is distributed under the terms of the GNU General Public License
  3. //==============================================================================
  4. //
  5. // RealVehicle 1.0.1, Release Date 19-September-2014
  6. //
  7. //
  8. //
  9. //
  10. //             RealVehicle Filterscript by Don_Walt "Enforcer"
  11. //
  12. //
  13. //
  14. //
  15. // This filterscript aims to give sa-mp vehicles
  16. // an enhanced feeling of realism, by implementing
  17. // an advanced fuel system and by providing
  18. // informational in game textdraws.
  19. //
  20. // Credits go to:
  21. // Don_Walt "Enforcer", for most of the code
  22. // Srdjan, for sections of code taken from "Realistic fuel system 1.0"
  23. // ev0lution, for the Quaternion Converter include
  24. // DANGER1979, for QuatToEuler function
  25. // JernejL, for the vector transformation function
  26. //
  27. //==============================================================================
  28.  
  29.  
  30.  
  31. //------------------------------------------------------------------------------
  32. //                              basic includes
  33. //------------------------------------------------------------------------------
  34.  
  35. #include <a_samp>
  36. #include "../include/gl_common.inc"
  37.  
  38.  
  39.  
  40. //------------------------------------------------------------------------------
  41. //                                 defines
  42. //------------------------------------------------------------------------------
  43.  
  44. #define VEHTYPE_NONE        0
  45. #define VEHTYPE_SPORT       1
  46. #define VEHTYPE_COMMON      2
  47. #define VEHTYPE_OFFROAD     3
  48. #define VEHTYPE_TRUCK       4
  49. #define VEHTYPE_BIKE        5
  50. #define VEHTYPE_AIR         6
  51.  
  52. #define VEHPROP_NONE        0
  53. #define VEHPROP_PUSH        1
  54. #define VEHPROP_ELECTRIC    2
  55. #define VEHPROP_PETROL      3
  56. #define VEHPROP_DIESEL      4
  57. #define VEHPROP_GASTURBINE  5
  58. #define VEHPROP_AVIATION    6
  59.  
  60. #define FUELTYPE_NONE       0
  61. #define FUELTYPE_BATTERY    1
  62. #define FUELTYPE_REGULAR    2
  63. #define FUELTYPE_PREMIUM    3
  64. #define FUELTYPE_DIESEL     4
  65. #define FUELTYPE_AVIATION   5
  66.  
  67. #define FUELPRICE_NONE      0.0
  68. #define FUELPRICE_BATTERY   0.5 // not yet implemented
  69. #define FUELPRICE_REGULAR   2.5 // price (in SA dollars) per litre of fuel
  70. #define FUELPRICE_PREMIUM   3.8
  71. #define FUELPRICE_DIESEL    4.2
  72. #define FUELPRICE_AVIATION  6.8
  73.  
  74. #define REFUEL_RATE         0.5 // refuel at a rate of x Litres per 0.1 seconds
  75. #define REPAIR_RATE         0.5 // repair at a rate of x percent per 0.1 seconds
  76. #define REFUEL_COST         1.0 // fuel price multiplyer
  77. #define REPAIR_COST         2.0 // price (in SA dollars) per percent of repair
  78.  
  79. #define COLOR_DEAD 0xAFAFAFAA
  80. #define COLOR_GREEN 0x33AA33AA
  81. #define COLOR_LIGHTGREEN 0x9ACD32AA
  82. #define COLOR_DEATH 0xAA3333AA
  83. #define COLOR_LIGHTBLUE 0x33CCFFAA
  84. #define COLOR_YELLOW 0xFFFF00AA
  85. #define COLOR_WHITE 0xFFFFFFAA
  86. #define COLOR_ERROR 0xFF0000FF
  87. #define COLOR_PURPLE 0xC2A2DAAA
  88. #define COLOR_SERVER_MAIN_MSG 0xFFFFFFAA
  89. #define COLOR_SERVER_HELP_MSG 0x33CCFFAA
  90. #define COLOR_PRIVATE_MSG 0xFFFF00AA
  91. #define COLOR_GROUP 0xDAA520AA
  92. #define COLOR_ADMIN 0xFF40FFFF
  93. #define COLOR_PINK 0xFF40FFFF
  94.  
  95. #define COLOR_DISPATCH 0x456EAF67
  96. #define COLOR_TEAM_LAW 0x000047B2AA
  97. #define COLOR_TEAM_DRIVER 0x00B800AA
  98.  
  99.  
  100.  
  101. //------------------------------------------------------------------------------
  102. //                             custom includes
  103. //------------------------------------------------------------------------------
  104.  
  105. /*
  106.  *
  107.  * Quaternion Converter
  108.  * Allows simple conversion from quaternion angles (supplied by new SA-MP 0.3b functions) to yaw/pitch/roll
  109.  *
  110.  * NAME         Quaternion Converter
  111.  * AUTHOR       ev0lution
  112.  * FILE         quaternion.inc
  113.  * VERSION      1.0.0
  114.  * LICENSE      GNU General Public License (see below)
  115.  * COPYRIGHT    Copyright © 2010 ev0lution
  116.  *
  117.  *  This file is part of Quaternion Converter.
  118.  *
  119.  *  Quaternion Converter is free software: you can redistribute it and/or modify
  120.  *  it under the terms of the GNU General Public License as published by
  121.  *  the Free Software Foundation, either version 3 of the License, or
  122.  *  (at your option) any later version.
  123.  *
  124.  *  Quaternion Converter is distributed in the hope that it will be useful,
  125.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  126.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  127.  *  GNU General Public License for more details.
  128.  *
  129.  *  You should have received a copy of the GNU General Public License
  130.  *  along with Quaternion Converter.  If not, see <http://www.gnu.org/licenses/>.
  131.  *
  132.  */
  133.  
  134. stock QuaternionToYawPitchRoll(Float:quat_w,Float:quat_x,Float:quat_y,Float:quat_z,&Float:x,&Float:y,&Float:z) {
  135.     x = atan2(2*((quat_x*quat_y)+(quat_w+quat_z)),(quat_w*quat_w)+(quat_x*quat_x)-(quat_y*quat_y)-(quat_z*quat_z));
  136.     y = atan2(2*((quat_y*quat_z)+(quat_w*quat_x)),(quat_w*quat_w)-(quat_x*quat_x)-(quat_y*quat_y)+(quat_z*quat_z));
  137.     z = asin(-2*((quat_x*quat_z)+(quat_w*quat_y)));
  138.     return 1;
  139. }
  140.  
  141. stock QuaternionGetRoll(Float:quat_w,Float:quat_x,Float:quat_y,Float:quat_z,&Float:roll) {
  142.     roll = atan2(2*((quat_x*quat_y)+(quat_w+quat_z)),(quat_w*quat_w)+(quat_x*quat_x)-(quat_y*quat_y)-(quat_z*quat_z));
  143.     return 1;
  144. }
  145.  
  146. stock QuaternionGetPitch(Float:quat_w,Float:quat_x,Float:quat_y,Float:quat_z,&Float:pitch) {
  147.     pitch = atan2(2*((quat_y*quat_z)+(quat_w*quat_x)),(quat_w*quat_w)-(quat_x*quat_x)-(quat_y*quat_y)+(quat_z*quat_z));
  148.     return 1;
  149. }
  150.  
  151. stock QuaternionGetYaw(Float:quat_w,Float:quat_x,Float:quat_y,Float:quat_z,&Float:yaw) {
  152.     yaw = asin(-2*((quat_x*quat_z)+(quat_w*quat_y)));
  153.     return 1;
  154. }
  155.  
  156.  
  157.  
  158. // =============================================================================
  159. // =============================================================================
  160. // =============================================================================
  161. // code by DANGER1979, edited by Don Walt
  162. stock ConvertNonNormaQuatToEuler(Float: qw, Float: qx, Float:qy, Float:qz, &Float:heading, &Float:attitude, &Float:bank)
  163. {
  164.     new Float: sqw = qw*qw;
  165.     new Float: sqx = qx*qx;
  166.     new Float: sqy = qy*qy;
  167.     new Float: sqz = qz*qz;
  168.     new Float: unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
  169.     //åñëè normalised, - îäèí, â ïðîòèâíîì ñëó÷àå - ïîêàçàòåëü êîððåêöèè
  170.     new Float: test = qx*qy + qz*qw;
  171.     if (test > 0.499*unit)
  172.     { // singularity at north pole - îñîáåííîñòü íà ñåâåðíîì ïîëþñå
  173.         heading = 2*atan2(qx,qw);
  174.         bank = 3.141592653/2;
  175.         attitude = 0;
  176.         return 1;
  177.     }
  178.     if (test < -0.499*unit)
  179.     { // singularity at south pole - îñîáåííîñòü íà þæíîì ïîëþñå
  180.         heading = -2*atan2(qx,qw);
  181.         bank = -3.141592653/2;
  182.         attitude = 0;
  183.         return 1;
  184.     }
  185.     heading = atan2(2*qy*qw - 2*qx*qz, sqx - sqy - sqz + sqw);
  186.     bank = asin(2*test/unit);
  187.     attitude = atan2(2*qx*qw - 2*qy*qz, -sqx + sqy - sqz + sqw);
  188.     return 1;
  189. }
  190.  
  191. stock GetVehicleRotation(vehicleid, &Float:heading, &Float:attitude, &Float:bank)
  192. {
  193.     new Float:quat_w, Float:quat_x, Float:quat_y, Float:quat_z;
  194.     GetVehicleRotationQuat(vehicleid, quat_w, quat_x, quat_y, quat_z);
  195.     ConvertNonNormaQuatToEuler(quat_w,quat_x, quat_z, quat_y, heading, attitude, bank);
  196.  
  197.     if(heading<0) heading += 360; // heading be from 0 to 360degrees clockwise
  198.     attitude *= -1; // attitude be + for climb, - for descend, 0 for straight and level
  199.     bank *= -1; // bank be + for roll to right, - for roll to left
  200.     return 1;
  201. }
  202.  
  203. // code by Don Walt
  204. // get the velocity and altitude for a vehicle
  205. stock getVehicleVelocity(vehicleid, &Float:actual, &Float:ground, &Float:heading, &Float:attitude, &Float:altitude, unitSpeed, unitAngle, unitAltitude)
  206. {
  207.     // units;  speed: kmh/mph,  angle: mils/degrees,  altitude: meters/feet (0/1 respectively)
  208.    
  209.     // get velocity in KM/H
  210.     // ground/actual speed
  211.     new Float:speed_x;
  212.     new Float:speed_y;
  213.     new Float:speed_z;
  214.     GetVehicleVelocity(vehicleid, speed_x, speed_y, speed_z); // get the velocity for x y and z
  215.     actual = floatsqroot( (speed_x*speed_x) + (speed_y*speed_y) + (speed_z*speed_z) ) * 180.00; // get the actual speed
  216.     ground = floatsqroot( (speed_x*speed_x) + (speed_y*speed_y) ) * 180.00; // get the ground speed
  217.     // 175 KM/H In LV Police Car at max speed
  218.    
  219.    
  220.     // get the angles in degrees
  221.     //new Float:heading;
  222.     //new Float:attitude;
  223.     new Float:bank;
  224.     new Float:quat_w, Float:quat_x, Float:quat_y, Float:quat_z;
  225.    
  226.     GetVehicleRotationQuat(vehicleid, quat_w, quat_x, quat_y, quat_z);
  227.     ConvertNonNormaQuatToEuler(quat_w,quat_x, quat_z, quat_y, heading, attitude, bank);
  228.  
  229.     if(heading<0) heading += 360; // heading be from 0 to 360degrees clockwise
  230.     attitude *= -1; // attitude be + for climb, - for descend, 0 for straight and level
  231.     bank *= -1; // bank be + for roll to right, - for roll to left
  232.    
  233.    
  234.     // get the altitude in meters (samp uses meters as default unit)
  235.     new Float:pos_x;
  236.     new Float:pos_y;
  237.     //new Float:pos_z;
  238.     GetVehiclePos(vehicleid, pos_x, pos_y, altitude);
  239.    
  240.    
  241.     // convert to the desired units as specified in "unitSpeed, unitAngle, unitAltitude"
  242.     if(unitSpeed == 1){
  243.         actual *= 0.621371; // km/h to mph scale factor
  244.         ground *= 0.621371;
  245.     }
  246.     if(unitAngle == 0){
  247.         heading *= 6400/360; // degrees to mils scale factor
  248.         attitude *= 6400/360;
  249.     }
  250.     if(unitAltitude == 1){
  251.         altitude *= 3.28084; // m to ft scale factor
  252.     }
  253. }
  254.  
  255.  
  256.  
  257. // =============================================================================
  258. // =============================================================================
  259. // =============================================================================
  260. // code by JernejL
  261. // transforms a vector using a 4x4 matrix (translation and scaling is ignored, only 3x3 part is used, we only need rotation!)
  262. stock MatrixTransformVector(Float:vector[3], Float:m[4][4], &Float:resx, &Float:resy, &Float:resz) {
  263.     resz = vector[2] * m[0][0] + vector[1] * m[0][1] + vector[0] * m[0][2] + m[0][3];
  264.     resy = vector[2] * m[1][0] + vector[1] * m[1][1] + vector[0] * m[1][2] + m[1][3];
  265.     resx = -(vector[2] * m[2][0] + vector[1] * m[2][1] + vector[0] * m[2][2] + m[2][3]); // don't ask why -x was needed, i don't know either.
  266. }
  267.  
  268. // something for 0.3b
  269. stock RotatePointVehicleRotation(vehid, Float:Invector[3], &Float:resx, &Float:resy, &Float:resz, worldspace=0) {
  270.  
  271.     new Float:Quaternion[4];
  272.     new Float:transformationmatrix[4][4];
  273.  
  274.     GetVehicleRotationQuat(vehid, Quaternion[0], Quaternion[1], Quaternion[2], Quaternion[3]);
  275.  
  276.     // build a transformation matrix out of the quaternion
  277.     new Float:xx = Quaternion[0] * Quaternion[0];
  278.     new Float:xy = Quaternion[0] * Quaternion[1];
  279.     new Float:xz = Quaternion[0] * Quaternion[2];
  280.     new Float:xw = Quaternion[0] * Quaternion[3];
  281.     new Float:yy = Quaternion[1] * Quaternion[1];
  282.     new Float:yz = Quaternion[1] * Quaternion[2];
  283.     new Float:yw = Quaternion[1] * Quaternion[3];
  284.     new Float:zz = Quaternion[2] * Quaternion[2];
  285.     new Float:zw = Quaternion[2] * Quaternion[3];
  286.  
  287.     transformationmatrix[0][0] = 1 - 2 * ( yy + zz );
  288.     transformationmatrix[0][1] =     2 * ( xy - zw );
  289.     transformationmatrix[0][2] =     2 * ( xz + yw );
  290.     transformationmatrix[0][3] = 0.0;
  291.  
  292.     transformationmatrix[1][0] =     2 * ( xy + zw );
  293.     transformationmatrix[1][1] = 1 - 2 * ( xx + zz );
  294.     transformationmatrix[1][2] =     2 * ( yz - xw );
  295.     transformationmatrix[1][3] = 0.0;
  296.  
  297.     transformationmatrix[2][0] =     2 * ( xz - yw );
  298.     transformationmatrix[2][1] =     2 * ( yz + xw );
  299.     transformationmatrix[2][2] = 1 - 2 * ( xx + yy );
  300.     transformationmatrix[2][3] = 0;
  301.  
  302.     transformationmatrix[3][0] = 0;
  303.     transformationmatrix[3][1] = 0;
  304.     transformationmatrix[3][2] = 0;
  305.     transformationmatrix[3][3] = 1;
  306.  
  307.     // transform the point thru car's rotation
  308.     MatrixTransformVector(Invector, transformationmatrix, resx, resy, resz);
  309.  
  310.     // if worldspace is set it'll return the coords in global space - useful to check tire coords against tire spike proximity directly, etc..
  311.  
  312.     if (worldspace == 1) {
  313.         new Float:fX, Float:fY, Float:fZ;
  314.         GetVehiclePos(vehid, fX, fY, fZ);
  315.         resx += fX;
  316.         resy += fY;
  317.         resz += fZ;
  318.     }
  319. }
  320.  
  321.  
  322.  
  323. //------------------------------------------------------------------------------
  324. //                             global variables
  325. //------------------------------------------------------------------------------
  326.  
  327. new vehicleNames[212][] = { // Vehicle Names Version 2 - enforcer
  328.     "Landstalker",
  329.     "Bravura",
  330.     "Buffalo",
  331.     "Linerunner",
  332.     "Perrenial",
  333.     "Sentinel",
  334.     "Dumper",
  335.     "Firetruck",
  336.     "Trashmaster",
  337.     "Stretch",
  338.     "Manana",
  339.     "Infernus",
  340.     "Voodoo",
  341.     "Pony",
  342.     "Mule",
  343.     "Cheetah",
  344.     "Ambulance",
  345.     "Leviathan",
  346.     "Moonbeam",
  347.     "Esperanto",
  348.     "Taxi",
  349.     "Washington",
  350.     "Bobcat",
  351.     "Mr Whoopee",
  352.     "BF Injection",
  353.     "Hunter",
  354.     "Premier",
  355.     "Enforcer",
  356.     "Securicar",
  357.     "Banshee",
  358.     "Predator",
  359.     "Bus",
  360.     "Rhino",
  361.     "Barracks",
  362.     "Hotknife",
  363.     "Trailer 1", //artict1
  364.     "Previon",
  365.     "Coach",
  366.     "Cabbie",
  367.     "Stallion",
  368.     "Rumpo",
  369.     "RC Bandit",
  370.     "Romero",
  371.     "Packer",
  372.     "Monster",
  373.     "Admiral",
  374.     "Squalo",
  375.     "Seasparrow",
  376.     "Pizzaboy",
  377.     "Tram",
  378.     "Trailer 2", //artict2
  379.     "Turismo",
  380.     "Speeder",
  381.     "Reefer",
  382.     "Tropic",
  383.     "Flatbed",
  384.     "Yankee",
  385.     "Caddy",
  386.     "Solair",
  387.     "Berkley's RC Van",
  388.     "Skimmer",
  389.     "PCJ-600",
  390.     "Faggio",
  391.     "Freeway",
  392.     "RC Baron",
  393.     "RC Raider",
  394.     "Glendale",
  395.     "Oceanic",
  396.     "Sanchez",
  397.     "Sparrow",
  398.     "Patriot",
  399.     "Quad",
  400.     "Coastguard",
  401.     "Dinghy",
  402.     "Hermes",
  403.     "Sabre",
  404.     "Rustler",
  405.     "ZR-350",
  406.     "Walton",
  407.     "Regina",
  408.     "Comet",
  409.     "BMX",
  410.     "Burrito",
  411.     "Camper",
  412.     "Marquis",
  413.     "Baggage",
  414.     "Dozer",
  415.     "Maverick",
  416.     "News Chopper",
  417.     "Rancher",
  418.     "Ranger",
  419.     "Virgo",
  420.     "Greenwood",
  421.     "Jetmax",
  422.     "Hotring",
  423.     "Sandking",
  424.     "Blista Compact",
  425.     "Police Maverick",
  426.     "Boxville",
  427.     "Benson",
  428.     "Mesa",
  429.     "RC Goblin",
  430.     "Hotring Racer A", //hotrina
  431.     "Hotring Racer B", //hotrinb
  432.     "Bloodring Banger",
  433.     "Rancher",
  434.     "Super GT",
  435.     "Elegant",
  436.     "Journey",
  437.     "Bike",
  438.     "Mountain Bike",
  439.     "Beagle",
  440.     "Cropdust",
  441.     "Stunt",
  442.     "Tanker", //petro
  443.     "Roadtrain",
  444.     "Nebula",
  445.     "Majestic",
  446.     "Buccaneer",
  447.     "Shamal",
  448.     "Hydra",
  449.     "FCR-900",
  450.     "NRG-500",
  451.     "HPV1000",
  452.     "Cement Truck",
  453.     "Tow Truck",
  454.     "Fortune",
  455.     "Cadrona",
  456.     "Riot Truck",
  457.     "Willard",
  458.     "Forklift",
  459.     "Tractor",
  460.     "Combine",
  461.     "Feltzer",
  462.     "Remington",
  463.     "Slamvan",
  464.     "Blade",
  465.     "Freight",
  466.     "Streak",
  467.     "Vortex",
  468.     "Vincent",
  469.     "Bullet",
  470.     "Clover",
  471.     "Sadler",
  472.     "Firetruck LA", //firela
  473.     "Hustler",
  474.     "Intruder",
  475.     "Primo",
  476.     "Cargobob",
  477.     "Tampa",
  478.     "Sunrise",
  479.     "Merit",
  480.     "Utility",
  481.     "Nevada",
  482.     "Yosemite",
  483.     "Windsor",
  484.     "Monster A", //monstera
  485.     "Monster B", //monsterb
  486.     "Uranus",
  487.     "Jester",
  488.     "Sultan",
  489.     "Stratum",
  490.     "Elegy",
  491.     "Nighthawk", // raindance
  492.     "RC Tiger",
  493.     "Flash",
  494.     "Tahoma",
  495.     "Savanna",
  496.     "Bandito",
  497.     "Freight Flat", //freiflat
  498.     "Streak Carriage", //streakc
  499.     "Kart",
  500.     "Mower",
  501.     "Duneride",
  502.     "Sweeper",
  503.     "Broadway",
  504.     "Tornado",
  505.     "AT-400",
  506.     "DFT-30",
  507.     "Huntley",
  508.     "Stafford",
  509.     "BF-400",
  510.     "Newsvan",
  511.     "Tug",
  512.     "Trailer 3", //petrotr
  513.     "Emperor",
  514.     "Wayfarer",
  515.     "Euros",
  516.     "Hotdog",
  517.     "Club",
  518.     "Freight Carriage", //freibox
  519.     "Trailer 3", //artict3
  520.     "Andromada",
  521.     "Dodo",
  522.     "RC Cam",
  523.     "Launch",
  524.     "Police Cruiser LS",// (LSPD)
  525.     "Police Cruiser SF",// (SFPD)
  526.     "Police Cruiser LV",// (LVPD)
  527.     "Police Ranger",
  528.     "Picador",
  529.     "S.W.A.T. Tank",
  530.     "Alpha",
  531.     "Phoenix",
  532.     "Glendale",
  533.     "Sadler",
  534.     "Luggage Trailer A", //bagboxa
  535.     "Luggage Trailer B", //bagboxb
  536.     "Stair Trailer", //tugstair
  537.     "Boxville",
  538.     "Farm Plow", //farmtr1
  539.     "Utility Trailer" //utiltr1
  540. };
  541.  
  542. enum pInfo
  543. {
  544.     pVehicleid,
  545.     Float:pSpeedActual,
  546.     Float:pSpeedGround,
  547.     Float:pHeading,
  548.     Float:pAttitude,
  549.     Float:pAltitude,
  550. };
  551.  
  552. enum vInfo
  553. {
  554.     vModelid, // the vehicle model
  555.     vNumberPlate,
  556.     vLastPlayerid, // last player to drive this vehicle
  557.     Float:vDamage,
  558.     Float:vFuel, // in litres
  559.     vFuelType, // the fuel type currently in the tank, eg aviation fuel
  560.     Float:vTotalDistance,
  561.     Float:vDistanceThisPlayer, // distance travelled by this playerid in this vehid
  562.     Float:vDistanceRemaining, // distance left to travel on this tank of fuel
  563. };
  564.  
  565. new PlayerInfo[MAX_PLAYERS][pInfo];
  566. new VehicleInfo[MAX_VEHICLES][vInfo];
  567.  
  568. enum coordinate
  569. {
  570.     Float: x,
  571.     Float: y,
  572.     Float: z,
  573. }
  574.  
  575. new const fuelStations[][coordinate] =
  576. {
  577.     { 1595.5406, 2198.0520, 10.3863 },
  578.     { 2202.0649, 2472.6697, 10.5677 },
  579.     { 2115.1929, 919.9908, 10.5266 },
  580.     { 2640.7209, 1105.9565, 10.5274 },
  581.     { 608.5971, 1699.6238, 6.9922 },
  582.     { 618.4878, 1684.5792, 6.9922 },
  583.     { 2146.3467, 2748.2893, 10.5245 },
  584.     { -1679.4595, 412.5129, 6.9973 },
  585.     { -1327.5607, 2677.4316, 49.8093 },
  586.     { -1470.0050, 1863.2375, 32.3521 },
  587.     { -2409.2200, 976.2798, 45.2969 },
  588.     { -2244.1396, -2560.5833, 31.9219 },
  589.     { -1606.0544, -2714.3083, 48.5335 },
  590.     { 1937.4293, -1773.1865, 13.3828 },
  591.     { -91.3854, -1169.9175, 2.4213 },
  592.     { 1383.4221, 462.5385, 20.1506 },
  593.     { 660.4590, -565.0394, 16.3359 },
  594.     { 1381.7206, 459.1907, 20.3452 },
  595.     { -1605.7156, -2714.4573, 48.5335 },
  596.     { 1008.1107, -937.3372, 42.6493 },
  597.     { -2029.4047, 157.2388, 28.5722 }
  598. };
  599.  
  600. new Text:VehicleOperationDisplay[20][MAX_PLAYERS]; // 20 is the number of separate textdraws we need to do for this
  601.  
  602.  
  603.  
  604. //------------------------------------------------------------------------------
  605. //                             samp fuctions
  606. //------------------------------------------------------------------------------
  607.  
  608. public OnFilterScriptInit()
  609. {
  610.     print("\n -----------------------------------------");
  611.     print("--  Realistic Vehicle Performace Loaded  --");
  612.     print("--         by Don Walt \"Enforcer\"        --");
  613.     print(" -----------------------------------------\n");
  614.  
  615.     // init the vehicleinfo
  616.     for(new vehicleid=0; vehicleid<MAX_VEHICLES; vehicleid++){
  617.         VehicleInfo[vehicleid][vModelid] = -1;
  618.         VehicleInfo[vehicleid][vNumberPlate] = -1;
  619.         VehicleInfo[vehicleid][vLastPlayerid] = -1;
  620.         VehicleInfo[vehicleid][vDamage] = -1;
  621.         VehicleInfo[vehicleid][vFuel] = -1;
  622.         VehicleInfo[vehicleid][vFuelType] = -1;
  623.         VehicleInfo[vehicleid][vTotalDistance] = -1;
  624.         VehicleInfo[vehicleid][vDistanceThisPlayer] = 0;
  625.         VehicleInfo[vehicleid][vDistanceRemaining] = 0;
  626.     }
  627.  
  628.     SetTimer("updateTextDraws", 500, 1);
  629.  
  630.     return 1;
  631. }
  632.  
  633. public OnPlayerConnect(playerid)
  634. {
  635.     /* mapicon styles
  636.     0: MAPICON_LOCAL                Display in the player's local area
  637.     1: MAPICON_GLOBAL               Display always
  638.     2: MAPICON_LOCAL_CHECKPOINT     Display in the player's local area and has a checkpoint marker
  639.     3: MAPICON_GLOBAL_CHECKPOINT    Display always and has a checkpoint marker
  640.     */
  641.  
  642.     // set petrol station map icons
  643.     new iconid = 100;
  644.     // for every fuel station
  645.     for (new i=0; i<sizeof(fuelStations); i++)
  646.     {
  647.         iconid--;
  648.         SetPlayerMapIcon(playerid, iconid, fuelStations[i][x], fuelStations[i][y], fuelStations[i][z], 19, 0, MAPICON_LOCAL);
  649.     }
  650.    
  651.     // model name
  652.     VehicleOperationDisplay[0][playerid] = TextDrawCreate(2.000000, 439.000000, "Cruiser"); // 2,470     Police Cruiser LVPD     Velocity 500km/h 6400mils     Damage 000%     Fuel 000.0%
  653.     TextDrawAlignment(VehicleOperationDisplay[0][playerid], 1);
  654.     TextDrawBackgroundColor(VehicleOperationDisplay[0][playerid], 0x00000077);
  655.     TextDrawFont(VehicleOperationDisplay[0][playerid], 1);
  656.     TextDrawLetterSize(VehicleOperationDisplay[0][playerid], 0.200000, 0.700000); // 0.220000,0.800000 0.280000,1.000000
  657.     TextDrawColor(VehicleOperationDisplay[0][playerid], 0x88ED77FF);
  658.     TextDrawSetOutline(VehicleOperationDisplay[0][playerid], 0);
  659.     TextDrawSetProportional(VehicleOperationDisplay[0][playerid], 1);
  660.     TextDrawSetShadow(VehicleOperationDisplay[0][playerid], 1);
  661.     // display a box for the vehicle info
  662.     TextDrawUseBox(VehicleOperationDisplay[0][playerid], 1);
  663.     TextDrawBoxColor(VehicleOperationDisplay[0][playerid], 0x40404080);
  664.     TextDrawTextSize(VehicleOperationDisplay[0][playerid], 638.00, 7.00);
  665.  
  666.     // velocity ground
  667.     VehicleOperationDisplay[1][playerid] = TextDrawCreate(70.000000, 439.000000, "Velocity gnd"); // 2,470
  668.     TextDrawAlignment(VehicleOperationDisplay[1][playerid], 1);
  669.     TextDrawBackgroundColor(VehicleOperationDisplay[1][playerid], 0x00000077);
  670.     TextDrawFont(VehicleOperationDisplay[1][playerid], 1);
  671.     TextDrawLetterSize(VehicleOperationDisplay[1][playerid], 0.200000, 0.700000);
  672.     TextDrawColor(VehicleOperationDisplay[1][playerid], 0xFFFE80FF);
  673.     TextDrawSetOutline(VehicleOperationDisplay[1][playerid], 0);
  674.     TextDrawSetProportional(VehicleOperationDisplay[1][playerid], 1);
  675.     TextDrawSetShadow(VehicleOperationDisplay[1][playerid], 1);
  676.  
  677.     VehicleOperationDisplay[2][playerid] = TextDrawCreate(142.000000, 439.000000, "500km/h");
  678.     TextDrawAlignment(VehicleOperationDisplay[2][playerid], 3);
  679.     TextDrawBackgroundColor(VehicleOperationDisplay[2][playerid], 0x00000077);
  680.     TextDrawFont(VehicleOperationDisplay[2][playerid], 1);
  681.     TextDrawLetterSize(VehicleOperationDisplay[2][playerid], 0.200000, 0.700000);
  682.     TextDrawColor(VehicleOperationDisplay[2][playerid], -1);
  683.     TextDrawSetOutline(VehicleOperationDisplay[2][playerid], 0);
  684.     TextDrawSetProportional(VehicleOperationDisplay[2][playerid], 1);
  685.     TextDrawSetShadow(VehicleOperationDisplay[2][playerid], 1);
  686.  
  687.     // velocity actual
  688.     VehicleOperationDisplay[3][playerid] = TextDrawCreate(146.000000, 439.000000, "act");
  689.     TextDrawAlignment(VehicleOperationDisplay[3][playerid], 1);
  690.     TextDrawBackgroundColor(VehicleOperationDisplay[3][playerid], 0x00000077);
  691.     TextDrawFont(VehicleOperationDisplay[3][playerid], 1);
  692.     TextDrawLetterSize(VehicleOperationDisplay[3][playerid], 0.200000, 0.700000);
  693.     TextDrawColor(VehicleOperationDisplay[3][playerid], 0xFFFE80FF);
  694.     TextDrawSetOutline(VehicleOperationDisplay[3][playerid], 0);
  695.     TextDrawSetProportional(VehicleOperationDisplay[3][playerid], 1);
  696.     TextDrawSetShadow(VehicleOperationDisplay[3][playerid], 1);
  697.  
  698.     VehicleOperationDisplay[4][playerid] = TextDrawCreate(188.000000, 439.000000, "600km/h");
  699.     TextDrawAlignment(VehicleOperationDisplay[4][playerid], 3);
  700.     TextDrawBackgroundColor(VehicleOperationDisplay[4][playerid], 0x00000077);
  701.     TextDrawFont(VehicleOperationDisplay[4][playerid], 1);
  702.     TextDrawLetterSize(VehicleOperationDisplay[4][playerid], 0.200000, 0.700000);
  703.     TextDrawColor(VehicleOperationDisplay[4][playerid], -1);
  704.     TextDrawSetOutline(VehicleOperationDisplay[4][playerid], 0);
  705.     TextDrawSetProportional(VehicleOperationDisplay[4][playerid], 1);
  706.     TextDrawSetShadow(VehicleOperationDisplay[4][playerid], 1);
  707.  
  708.     // heading
  709.     VehicleOperationDisplay[5][playerid] = TextDrawCreate(192.000000, 439.000000, "head");
  710.     TextDrawAlignment(VehicleOperationDisplay[5][playerid], 1);
  711.     TextDrawBackgroundColor(VehicleOperationDisplay[5][playerid], 0x00000077);
  712.     TextDrawFont(VehicleOperationDisplay[5][playerid], 1);
  713.     TextDrawLetterSize(VehicleOperationDisplay[5][playerid], 0.200000, 0.700000);
  714.     TextDrawColor(VehicleOperationDisplay[5][playerid], 0xFFFE80FF);
  715.     TextDrawSetOutline(VehicleOperationDisplay[5][playerid], 0);
  716.     TextDrawSetProportional(VehicleOperationDisplay[5][playerid], 1);
  717.     TextDrawSetShadow(VehicleOperationDisplay[5][playerid], 1);
  718.  
  719.     VehicleOperationDisplay[6][playerid] = TextDrawCreate(239.000000, 439.000000, "6400mils");
  720.     TextDrawAlignment(VehicleOperationDisplay[6][playerid], 3);
  721.     TextDrawBackgroundColor(VehicleOperationDisplay[6][playerid], 0x00000077);
  722.     TextDrawFont(VehicleOperationDisplay[6][playerid], 1);
  723.     TextDrawLetterSize(VehicleOperationDisplay[6][playerid], 0.200000, 0.700000);
  724.     TextDrawColor(VehicleOperationDisplay[6][playerid], -1);
  725.     TextDrawSetOutline(VehicleOperationDisplay[6][playerid], 0);
  726.     TextDrawSetProportional(VehicleOperationDisplay[6][playerid], 1);
  727.     TextDrawSetShadow(VehicleOperationDisplay[6][playerid], 1);
  728.  
  729.     // elevation
  730.     VehicleOperationDisplay[7][playerid] = TextDrawCreate(244.000000, 439.000000, "ptc");
  731.     TextDrawAlignment(VehicleOperationDisplay[7][playerid], 1);
  732.     TextDrawBackgroundColor(VehicleOperationDisplay[7][playerid], 0x00000077);
  733.     TextDrawFont(VehicleOperationDisplay[7][playerid], 1);
  734.     TextDrawLetterSize(VehicleOperationDisplay[7][playerid], 0.200000, 0.700000);
  735.     TextDrawColor(VehicleOperationDisplay[7][playerid], 0xFFFE80FF);
  736.     TextDrawSetOutline(VehicleOperationDisplay[7][playerid], 0);
  737.     TextDrawSetProportional(VehicleOperationDisplay[7][playerid], 1);
  738.     TextDrawSetShadow(VehicleOperationDisplay[7][playerid], 1);
  739.  
  740.     VehicleOperationDisplay[8][playerid] = TextDrawCreate(285.000000, 439.000000, "6400mils");
  741.     TextDrawAlignment(VehicleOperationDisplay[8][playerid], 3);
  742.     TextDrawBackgroundColor(VehicleOperationDisplay[8][playerid], 0x00000077);
  743.     TextDrawFont(VehicleOperationDisplay[8][playerid], 1);
  744.     TextDrawLetterSize(VehicleOperationDisplay[8][playerid], 0.200000, 0.700000);
  745.     TextDrawColor(VehicleOperationDisplay[8][playerid], -1);
  746.     TextDrawSetOutline(VehicleOperationDisplay[8][playerid], 0);
  747.     TextDrawSetProportional(VehicleOperationDisplay[8][playerid], 1);
  748.     TextDrawSetShadow(VehicleOperationDisplay[8][playerid], 1);
  749.  
  750.     // altitude
  751.     VehicleOperationDisplay[9][playerid] = TextDrawCreate(289.000000, 439.000000, "Alt");
  752.     TextDrawAlignment(VehicleOperationDisplay[9][playerid], 1);
  753.     TextDrawBackgroundColor(VehicleOperationDisplay[9][playerid], 0x00000077);
  754.     TextDrawFont(VehicleOperationDisplay[9][playerid], 1);
  755.     TextDrawLetterSize(VehicleOperationDisplay[9][playerid], 0.200000, 0.700000);
  756.     TextDrawColor(VehicleOperationDisplay[9][playerid], 0xFFFE80FF);
  757.     TextDrawSetOutline(VehicleOperationDisplay[9][playerid], 0);
  758.     TextDrawSetProportional(VehicleOperationDisplay[9][playerid], 1);
  759.     TextDrawSetShadow(VehicleOperationDisplay[9][playerid], 1);
  760.  
  761.     VehicleOperationDisplay[10][playerid] = TextDrawCreate(328.000000, 439.000000, "50000ft");
  762.     TextDrawAlignment(VehicleOperationDisplay[10][playerid], 3);
  763.     TextDrawBackgroundColor(VehicleOperationDisplay[10][playerid], 0x00000077);
  764.     TextDrawFont(VehicleOperationDisplay[10][playerid], 1);
  765.     TextDrawLetterSize(VehicleOperationDisplay[10][playerid], 0.200000, 0.700000);
  766.     TextDrawColor(VehicleOperationDisplay[10][playerid], -1);
  767.     TextDrawSetOutline(VehicleOperationDisplay[10][playerid], 0);
  768.     TextDrawSetProportional(VehicleOperationDisplay[10][playerid], 1);
  769.     TextDrawSetShadow(VehicleOperationDisplay[10][playerid], 1);
  770.  
  771.     // damage
  772.     VehicleOperationDisplay[11][playerid] = TextDrawCreate(338.000000, 439.000000, "Damage");
  773.     TextDrawAlignment(VehicleOperationDisplay[11][playerid], 1);
  774.     TextDrawBackgroundColor(VehicleOperationDisplay[11][playerid], 0x00000077);
  775.     TextDrawFont(VehicleOperationDisplay[11][playerid], 1);
  776.     TextDrawLetterSize(VehicleOperationDisplay[11][playerid], 0.200000, 0.700000);
  777.     TextDrawColor(VehicleOperationDisplay[11][playerid], 0xFFFE80FF);
  778.     TextDrawSetOutline(VehicleOperationDisplay[11][playerid], 0);
  779.     TextDrawSetProportional(VehicleOperationDisplay[11][playerid], 1);
  780.     TextDrawSetShadow(VehicleOperationDisplay[11][playerid], 1);
  781.  
  782.     VehicleOperationDisplay[12][playerid] = TextDrawCreate(386.000000, 439.000000, "100%");
  783.     TextDrawAlignment(VehicleOperationDisplay[12][playerid], 3);
  784.     TextDrawBackgroundColor(VehicleOperationDisplay[12][playerid], 0x00000077);
  785.     TextDrawFont(VehicleOperationDisplay[12][playerid], 1);
  786.     TextDrawLetterSize(VehicleOperationDisplay[12][playerid], 0.200000, 0.700000);
  787.     TextDrawColor(VehicleOperationDisplay[12][playerid], -1);
  788.     TextDrawSetOutline(VehicleOperationDisplay[12][playerid], 0);
  789.     TextDrawSetProportional(VehicleOperationDisplay[12][playerid], 1);
  790.     TextDrawSetShadow(VehicleOperationDisplay[12][playerid], 1);
  791.  
  792.     // fuel
  793.     VehicleOperationDisplay[13][playerid] = TextDrawCreate(397.000000, 439.000000, "Fuel");
  794.     TextDrawAlignment(VehicleOperationDisplay[13][playerid], 1);
  795.     TextDrawBackgroundColor(VehicleOperationDisplay[13][playerid], 0x00000077);
  796.     TextDrawFont(VehicleOperationDisplay[13][playerid], 1);
  797.     TextDrawLetterSize(VehicleOperationDisplay[13][playerid], 0.200000, 0.700000);
  798.     TextDrawColor(VehicleOperationDisplay[13][playerid], 0xFFFE80FF);
  799.     TextDrawSetOutline(VehicleOperationDisplay[13][playerid], 0);
  800.     TextDrawSetProportional(VehicleOperationDisplay[13][playerid], 1);
  801.     TextDrawSetShadow(VehicleOperationDisplay[13][playerid], 1);
  802.  
  803.     VehicleOperationDisplay[14][playerid] = TextDrawCreate(435.000000, 439.000000, "500.0L");
  804.     TextDrawAlignment(VehicleOperationDisplay[14][playerid], 3);
  805.     TextDrawBackgroundColor(VehicleOperationDisplay[14][playerid], 0x00000077);
  806.     TextDrawFont(VehicleOperationDisplay[14][playerid], 1);
  807.     TextDrawLetterSize(VehicleOperationDisplay[14][playerid], 0.200000, 0.700000);
  808.     TextDrawColor(VehicleOperationDisplay[14][playerid], -1);
  809.     TextDrawSetOutline(VehicleOperationDisplay[14][playerid], 0);
  810.     TextDrawSetProportional(VehicleOperationDisplay[14][playerid], 1);
  811.     TextDrawSetShadow(VehicleOperationDisplay[14][playerid], 1);
  812.  
  813.     VehicleOperationDisplay[15][playerid] = TextDrawCreate(465.000000, 439.000000, "100.0%");
  814.     TextDrawAlignment(VehicleOperationDisplay[15][playerid], 3);
  815.     TextDrawBackgroundColor(VehicleOperationDisplay[15][playerid], 0x00000077);
  816.     TextDrawFont(VehicleOperationDisplay[15][playerid], 1);
  817.     TextDrawLetterSize(VehicleOperationDisplay[15][playerid], 0.200000, 0.700000);
  818.     TextDrawColor(VehicleOperationDisplay[15][playerid], -1);
  819.     TextDrawSetOutline(VehicleOperationDisplay[15][playerid], 0);
  820.     TextDrawSetProportional(VehicleOperationDisplay[15][playerid], 1);
  821.     TextDrawSetShadow(VehicleOperationDisplay[15][playerid], 1);
  822.  
  823.     VehicleOperationDisplay[16][playerid] = TextDrawCreate(512.000000, 439.000000, "50.0L/100km");
  824.     TextDrawAlignment(VehicleOperationDisplay[16][playerid], 3);
  825.     TextDrawBackgroundColor(VehicleOperationDisplay[16][playerid], 0x00000077);
  826.     TextDrawFont(VehicleOperationDisplay[16][playerid], 1);
  827.     TextDrawLetterSize(VehicleOperationDisplay[16][playerid], 0.200000, 0.700000);
  828.     TextDrawColor(VehicleOperationDisplay[16][playerid], -1);
  829.     TextDrawSetOutline(VehicleOperationDisplay[16][playerid], 0);
  830.     TextDrawSetProportional(VehicleOperationDisplay[16][playerid], 1);
  831.     TextDrawSetShadow(VehicleOperationDisplay[16][playerid], 1);
  832.  
  833.     // fuel type
  834.     VehicleOperationDisplay[17][playerid] = TextDrawCreate(516.000000, 439.000000, "Petrol");
  835.     TextDrawAlignment(VehicleOperationDisplay[17][playerid], 1);
  836.     TextDrawBackgroundColor(VehicleOperationDisplay[17][playerid], 0x00000077);
  837.     TextDrawFont(VehicleOperationDisplay[17][playerid], 1);
  838.     TextDrawLetterSize(VehicleOperationDisplay[17][playerid], 0.200000, 0.700000);
  839.     TextDrawColor(VehicleOperationDisplay[17][playerid], -1);
  840.     TextDrawSetOutline(VehicleOperationDisplay[17][playerid], 0);
  841.     TextDrawSetProportional(VehicleOperationDisplay[17][playerid], 1);
  842.     TextDrawSetShadow(VehicleOperationDisplay[17][playerid], 1);
  843.  
  844.     // total vehicle distance
  845.     VehicleOperationDisplay[18][playerid] = TextDrawCreate(567.000000, 439.000000, "Distance");
  846.     TextDrawAlignment(VehicleOperationDisplay[18][playerid], 1);
  847.     TextDrawBackgroundColor(VehicleOperationDisplay[18][playerid], 0x00000077);
  848.     TextDrawFont(VehicleOperationDisplay[18][playerid], 1);
  849.     TextDrawLetterSize(VehicleOperationDisplay[18][playerid], 0.200000, 0.700000);
  850.     TextDrawColor(VehicleOperationDisplay[18][playerid], 0xFFFE80FF);
  851.     TextDrawSetOutline(VehicleOperationDisplay[18][playerid], 0);
  852.     TextDrawSetProportional(VehicleOperationDisplay[18][playerid], 1);
  853.     TextDrawSetShadow(VehicleOperationDisplay[18][playerid], 1);
  854.  
  855.     VehicleOperationDisplay[19][playerid] = TextDrawCreate(597.000000, 439.000000, "5000000km");
  856.     TextDrawAlignment(VehicleOperationDisplay[19][playerid], 1);
  857.     TextDrawBackgroundColor(VehicleOperationDisplay[19][playerid], 0x00000077);
  858.     TextDrawFont(VehicleOperationDisplay[19][playerid], 1);
  859.     TextDrawLetterSize(VehicleOperationDisplay[19][playerid], 0.200000, 0.700000);
  860.     TextDrawColor(VehicleOperationDisplay[19][playerid], -1);
  861.     TextDrawSetOutline(VehicleOperationDisplay[19][playerid], 0);
  862.     TextDrawSetProportional(VehicleOperationDisplay[19][playerid], 1);
  863.     TextDrawSetShadow(VehicleOperationDisplay[19][playerid], 1);
  864.    
  865.     return 0;
  866. }
  867.  
  868. public OnPlayerUpdate(playerid)
  869. {
  870.     // if fuel is 0, turn the engine off
  871.     if(IsPlayerConnected(playerid) && IsPlayerInAnyVehicle(playerid) && GetPlayerState(playerid) == PLAYER_STATE_DRIVER){
  872.         new vehicleid = GetPlayerVehicleID(playerid);
  873.        
  874.         if(VehicleInfo[vehicleid][vFuel] < 0.2){ // less than 200ml in the fuel tank
  875.             vehicleParamsSet(vehicleid, 0, -1, -1, -1, -1, -1, -1); // turn engine off
  876.         }
  877.     }
  878.  
  879.     return 1;
  880. }
  881.  
  882. ShowVehicleOperationDisplay(playerid)
  883. {
  884.     for(new i=0; i<20; i++){
  885.         TextDrawShowForPlayer(playerid,VehicleOperationDisplay[i][playerid]);
  886.     }
  887. }
  888.  
  889. HideVehicleOperationDisplay(playerid)
  890. {
  891.     for(new i=0; i<20; i++){
  892.         TextDrawHideForPlayer(playerid,VehicleOperationDisplay[i][playerid]);
  893.     }
  894. }
  895.  
  896. public OnPlayerEnterVehicle(playerid, vehicleid)
  897. {
  898.     // if this vehicle has not been initialized
  899.     if(VehicleInfo[vehicleid][vTotalDistance] < 0){ // if distance travelled is -1
  900.         vehicleInfoInit(vehicleid, playerid);
  901.     }
  902.  
  903.     return 1;
  904. }
  905.  
  906. public OnPlayerExitVehicle(playerid, vehicleid)
  907. {
  908.     HideVehicleOperationDisplay(playerid);
  909.  
  910.     return 1;
  911. }
  912.  
  913. public OnPlayerStateChange(playerid, newstate, oldstate)
  914. {
  915.     if(IsPlayerInAnyVehicle(playerid) && newstate==PLAYER_STATE_DRIVER){
  916.         ShowVehicleOperationDisplay(playerid);
  917.     }
  918.  
  919.     return 1;
  920. }
  921.  
  922. public OnPlayerCommandText (playerid, cmdtext[])
  923. {
  924.     new cmd[256+1];
  925.     new idx;
  926.     cmd = strtok(cmdtext, idx);
  927.  
  928.     // toggle the engine
  929.     if (!strcmp (cmdtext, "/v", true))
  930.     {
  931.         new vehicleid = GetPlayerVehicleID(playerid);
  932.  
  933.         vehicleParamsToggle(vehicleid, 1, 0, 0, 0, 0, 0, 0);
  934.    
  935.         return 1;
  936.     }
  937.     // set fuel to 20
  938.     if (!strcmp (cmdtext, "/fuel20", true))
  939.     {
  940.         new vehicleid = GetPlayerVehicleID(playerid);
  941.  
  942.         VehicleInfo[vehicleid][vFuel] = 20;
  943.  
  944.         return 1;
  945.     }
  946.     if (!strcmp (cmdtext, "/on", true))
  947.     {
  948.         new vehicleid = GetPlayerVehicleID(playerid);
  949.  
  950.         vehicleParamsSet(vehicleid, 1, -1, -1, -1, -1, -1, -1);
  951.  
  952.         return 1;
  953.     }
  954.     if (!strcmp (cmdtext, "/off", true))
  955.     {
  956.         new vehicleid = GetPlayerVehicleID(playerid);
  957.  
  958.         vehicleParamsSet(vehicleid, 0, -1, -1, -1, -1, -1, -1);
  959.  
  960.         return 1;
  961.     }
  962.    
  963.     // refuel command
  964.     if (!strcmp (cmd, "/refuel", true))
  965.     {
  966.         new params1[256];
  967.         params1 = strtok(cmdtext, idx);
  968.        
  969.         new params2[256];
  970.         params2 = strtok(cmdtext, idx);
  971.  
  972.         new string[256];
  973.         format(string, sizeof(string), "%s %s", params1, params2);
  974.        
  975.         cmd_refuel(playerid, string);
  976.         return 1;
  977.     }
  978.    
  979.     // vehicle repair command
  980.     if (!strcmp (cmd, "/fixcar", true))
  981.     {
  982.         new params[64];
  983.         params = strtok(cmdtext, idx);
  984.  
  985.         cmd_repair(playerid, params);
  986.         return 1;
  987.     }
  988.    
  989.     return 0;
  990. }
  991.  
  992.  
  993.  
  994. //------------------------------------------------------------------------------
  995. //                             stock fuctions
  996. //------------------------------------------------------------------------------
  997.  
  998. // returns the price per litre of fuel
  999. stock Float: getFuelPrice(fuelType)
  1000. {
  1001.     if(fuelType == FUELTYPE_NONE) return FUELPRICE_NONE;
  1002.     if(fuelType == FUELTYPE_BATTERY) return FUELPRICE_BATTERY;
  1003.     if(fuelType == FUELTYPE_REGULAR) return FUELPRICE_REGULAR;
  1004.     if(fuelType == FUELTYPE_PREMIUM) return FUELPRICE_PREMIUM;
  1005.     if(fuelType == FUELTYPE_DIESEL) return FUELPRICE_DIESEL;
  1006.     if(fuelType == FUELTYPE_AVIATION) return FUELPRICE_AVIATION;
  1007.     return FUELPRICE_NONE;
  1008. }
  1009.  
  1010. // are we at a gas station?
  1011. stock IsPlayerAtFuelStation(playerid)
  1012. {
  1013.     for (new i=0; i<sizeof(fuelStations); i++)
  1014.     {
  1015.         if (IsPlayerInRangeOfPoint (playerid, 10.0, fuelStations[i][x], fuelStations[i][y], fuelStations[i][z])) return 1;
  1016.     }
  1017.     return 0;
  1018. }
  1019.  
  1020. // return the type of vehicle for a modelid
  1021. stock vehicleType(modelid)
  1022. {
  1023.     switch(modelid){
  1024.         case 402, 411, 415, 602, 429, 541, 587, 565, 494, 502, 503,
  1025.         559, 603, 506, 451, 558, 477, 560, 562: return VEHTYPE_SPORT;
  1026.  
  1027.         case 400, 424, 489, 495, 505, 568, 579, 599: return VEHTYPE_OFFROAD;
  1028.  
  1029.         case 403, 406, 407, 408, 413, 414, 416, 418, 423, 427, 428,
  1030.         431, 432, 433, 437, 440, 443, 444, 455, 456, 459, 470,
  1031.         482, 483, /*485,*/ 486, 498, 499, 508, 514, 515, 524,
  1032.         /*531, 532,*/543, 556, 557, /*572,*/573, 578, 582, 588,
  1033.         601, 609: return VEHTYPE_TRUCK;
  1034.  
  1035.         case 401, 404, 405, 409, 410, 412, 419, 420, 421, 422, 426,
  1036.         434, 436, 438, 439, 442, 445, 458, 466, 467, 474, 475,
  1037.         478, 479, 490, 491, 492, 496, 500, 504, 507, 516, 517,
  1038.         518, 525, 526, 527, 528, 529, 533, 534, 535, 536, 540,
  1039.         542, 545, 546, 547, 549, 551, 552, 554, 555,
  1040.         561, 566, 567, 575, 576, 580, 585, 589, 596, 597, 598,
  1041.         600, 604, 605: return VEHTYPE_COMMON;
  1042.  
  1043.         case 448, 457, 461, 462, 468, 471, 521, 522, 523, 530, 571,
  1044.         574, 581, 583, 586: return VEHTYPE_BIKE;
  1045.  
  1046.         case 592, 577, 511, 512, 593, 520, 553, 476, 519, 460, 513,
  1047.         548, 425, 417, 487, 488, 497, 563, 447, 469: return VEHTYPE_AIR;
  1048.     }
  1049.  
  1050.     return VEHTYPE_NONE;
  1051. }
  1052.  
  1053. // return the fuel tank capacity for a modelid
  1054. // return -1 for an unknown modelid
  1055. stock vehicleFuelTankCapacity(modelid)
  1056. {
  1057.     switch (vehicleType(modelid))
  1058.     {
  1059.         case VEHTYPE_NONE:    return 0;
  1060.         case VEHTYPE_SPORT:   return 70;
  1061.         case VEHTYPE_COMMON:  return 60;
  1062.         case VEHTYPE_OFFROAD: return 80;
  1063.         case VEHTYPE_TRUCK:   return 130;
  1064.         case VEHTYPE_BIKE:    return 25;
  1065.         case VEHTYPE_AIR:     return 200;
  1066.     }
  1067.     return -1;
  1068. }
  1069.  
  1070. // init vehicle info
  1071. stock vehicleInfoInit(vehicleid, playerid)
  1072. {
  1073.     VehicleInfo[vehicleid][vModelid] = GetVehicleModel(vehicleid);
  1074.     VehicleInfo[vehicleid][vNumberPlate] = 0;
  1075.     VehicleInfo[vehicleid][vLastPlayerid] = playerid;
  1076.     VehicleInfo[vehicleid][vDamage] = 0;
  1077.  
  1078.     // fill the tank with a random ammount of fuel, from a min of 5L to max of full tank
  1079.     VehicleInfo[vehicleid][vFuel] = randnumb(5, vehicleFuelTankCapacity(VehicleInfo[vehicleid][vModelid]) );
  1080.  
  1081.     // put a suitable fuel in the tank
  1082.     switch(vehiclePropulsionType(VehicleInfo[vehicleid][vModelid])){
  1083.         case VEHPROP_NONE:       VehicleInfo[vehicleid][vFuelType] = FUELTYPE_NONE;
  1084.         case VEHPROP_PUSH:       VehicleInfo[vehicleid][vFuelType] = FUELTYPE_NONE;
  1085.         case VEHPROP_ELECTRIC:   VehicleInfo[vehicleid][vFuelType] = FUELTYPE_BATTERY;
  1086.         case VEHPROP_PETROL:     VehicleInfo[vehicleid][vFuelType] = FUELTYPE_REGULAR;
  1087.         case VEHPROP_DIESEL:     VehicleInfo[vehicleid][vFuelType] = FUELTYPE_DIESEL;
  1088.         case VEHPROP_GASTURBINE: VehicleInfo[vehicleid][vFuelType] = FUELTYPE_DIESEL;
  1089.         case VEHPROP_AVIATION:   VehicleInfo[vehicleid][vFuelType] = FUELTYPE_AVIATION;
  1090.     }
  1091.  
  1092.     VehicleInfo[vehicleid][vTotalDistance] = 0;
  1093.     VehicleInfo[vehicleid][vDistanceThisPlayer] = 0;
  1094.     VehicleInfo[vehicleid][vDistanceRemaining] = 0;
  1095. }
  1096.  
  1097. // return the type of propulsion for a modelid
  1098. stock vehiclePropulsionType(modelid)
  1099. {
  1100.     switch(modelid){
  1101.         case 435,450,584,591,606,607,608,610,611,590,594: return VEHPROP_NONE;
  1102.  
  1103.         case 481,509,510: return VEHPROP_PUSH;
  1104.  
  1105.         case 457,441,464,465,501,564: return VEHPROP_ELECTRIC;
  1106.  
  1107.         case 462,471,568,571,572,401,404,405,410,412,419,421,424,426,436,439,445,458,463,466,
  1108.         467,468,474,475,480,483,491,492,550,516,517,518,521,526,527,529,533,534,536,540,
  1109.         542,545,547,549,551,566,567,575,576,580,585,586,589,446,452,472,473,493,539,402,
  1110.         411,415,429,434,451,461,477,494,496,500,502,503,504,506,507,522,541,546,555,558,
  1111.         559,560,561,562,565,581,587,602,603,409,420,438,442,448,485,530,531,574,583,523,
  1112.         596,597,598,416,604: return VEHPROP_PETROL;
  1113.  
  1114.         case 418,422,478,479,543,600,453,454,484,400,489,495,505,508,535,573,579,403,406,408,
  1115.         413,414,423,431,437,440,443,444,455,456,459,482,486,498,499,514,515,524,525,532,
  1116.         552,554,556,557,578,582,588,609,407,427,428,430,490,528,544,599,601,432,433,470,
  1117.         595,605: return VEHPROP_DIESEL;
  1118.  
  1119.         case 417,460,469,487,488,511,512,513,519,553,577,593,497,563,425,447,476,520,548,592: return VEHPROP_AVIATION;
  1120.     }
  1121.  
  1122.     return VEHPROP_NONE;
  1123. }
  1124.  
  1125. // check if a fuel type is compatible with a vehicle
  1126. // returns 1 for compatible and 0 for not compatible
  1127. stock checkFuelVehicle(modelid, fuelType)
  1128. {
  1129.     new propType = vehiclePropulsionType(modelid);
  1130.  
  1131.     // if the fueltype is safe for the engine type, return 1
  1132.     switch(propType){
  1133.         case VEHPROP_NONE: if(fuelType==FUELTYPE_NONE) return 1;
  1134.  
  1135.         case VEHPROP_PUSH: if(fuelType==FUELTYPE_NONE) return 1;
  1136.  
  1137.         case VEHPROP_ELECTRIC: if(fuelType==FUELTYPE_BATTERY) return 1;
  1138.  
  1139.         case VEHPROP_PETROL: if(fuelType==FUELTYPE_REGULAR || fuelType==FUELTYPE_PREMIUM) return 1;
  1140.  
  1141.         case VEHPROP_DIESEL: if(fuelType==FUELTYPE_DIESEL) return 1;
  1142.  
  1143.         case VEHPROP_GASTURBINE: if(fuelType==FUELTYPE_REGULAR || fuelType==FUELTYPE_PREMIUM || fuelType==FUELTYPE_DIESEL || fuelType==FUELTYPE_AVIATION) return 1;
  1144.  
  1145.         case VEHPROP_AVIATION: if(fuelType==FUELTYPE_AVIATION) return 1;
  1146.     }
  1147.  
  1148.     return 0; // return "not safe"
  1149. }
  1150.  
  1151. // return a string of the name of a fueltype_id
  1152. stock fuelTypeString(fuelType)
  1153. {
  1154.     new string[15];
  1155.  
  1156.     switch(fuelType){
  1157.         case FUELTYPE_NONE:     string = "No Fuel Tank";
  1158.         case FUELTYPE_BATTERY:  string = "Battery";
  1159.         case FUELTYPE_REGULAR:  string = "Regular Petrol"; // 14 chars
  1160.         case FUELTYPE_PREMIUM:  string = "Premium Petrol";
  1161.         case FUELTYPE_DIESEL:   string = "Diesel Fuel";
  1162.         case FUELTYPE_AVIATION: string = "Aviation Fuel";
  1163.     }
  1164.  
  1165.     return string;
  1166. }
  1167.  
  1168. stock randnumb (min, max)
  1169. {
  1170.     return random (max - min) + min;
  1171. }
  1172.  
  1173. // pass a value of 1 to turn a param on, 0 to turn it off, and -1 to leave it as it was
  1174. stock vehicleParamsSet(vehicleid, engine, lights, alarm, doors, bonnet, boot, objective)
  1175. {
  1176.     new engine_state;
  1177.     new lights_state;
  1178.     new alarm_state;
  1179.     new doors_state;
  1180.     new bonnet_state;
  1181.     new boot_state;
  1182.     new objective_state;
  1183.  
  1184.     // get the old params state
  1185.     GetVehicleParamsEx(vehicleid, engine_state, lights_state, alarm_state, doors_state, bonnet_state, boot_state, objective_state);
  1186.  
  1187.     // set the vars to what the new state will be
  1188.     if(engine == 1) engine_state = 1; // if true turn on
  1189.     else if(engine == 0) engine_state = 0; // otherwise turn off
  1190.  
  1191.     if(lights == 1) lights_state = 1;
  1192.     else if(lights == 0)lights_state = 0;
  1193.  
  1194.     if(alarm == 1) alarm_state = 1;
  1195.     else if(alarm == 0) alarm_state = 0;
  1196.  
  1197.     if(doors == 1) doors_state = 1;
  1198.     else if(doors == 0) doors_state = 0;
  1199.  
  1200.     if(bonnet == 1) bonnet_state = 1;
  1201.     else if(bonnet == 0) bonnet_state = 0;
  1202.  
  1203.     if(boot == 1) boot_state = 1;
  1204.     else if(boot == 0) boot_state = 0;
  1205.  
  1206.     if(objective == 1) objective_state = 1;
  1207.     else if(objective == 0) objective_state = 0;
  1208.  
  1209.     // set the new params
  1210.     SetVehicleParamsEx(vehicleid, engine_state, lights_state, alarm_state, doors_state, bonnet_state, boot_state, objective_state);
  1211. }
  1212.  
  1213. // toggles a bool variable
  1214. stock toggle(&boolInput)
  1215. {
  1216.     if(boolInput) boolInput = false;
  1217.     else boolInput = true;
  1218.     return;
  1219. }
  1220.  
  1221. // pass a value of 1 to toggle a param, 0 to leave as was
  1222. stock vehicleParamsToggle(vehicleid, engine, lights, alarm, doors, bonnet, boot, objective)
  1223. {
  1224.     new engine_state;
  1225.     new lights_state;
  1226.     new alarm_state;
  1227.     new doors_state;
  1228.     new bonnet_state;
  1229.     new boot_state;
  1230.     new objective_state;
  1231.  
  1232.     // get the old params state
  1233.     GetVehicleParamsEx(vehicleid, engine_state, lights_state, alarm_state, doors_state, bonnet_state, boot_state, objective_state);
  1234.  
  1235.     // set the vars to what the new state will be
  1236.     if (engine) toggle(engine_state);
  1237.  
  1238.     if (lights) toggle(lights_state);
  1239.  
  1240.     if (alarm) toggle(alarm_state);
  1241.  
  1242.     if (doors) toggle(doors_state);
  1243.  
  1244.     if (bonnet) toggle(bonnet_state);
  1245.  
  1246.     if (boot) toggle(boot_state);
  1247.  
  1248.     if (objective) toggle(objective_state);
  1249.  
  1250.     // set the new params
  1251.     SetVehicleParamsEx(vehicleid, engine_state, lights_state, alarm_state, doors_state, bonnet_state, boot_state, objective_state);
  1252. }
  1253.  
  1254. // return 1 if engine is on, 0 if it is off
  1255. stock vehicleStateEngine(vehicleid)
  1256. {
  1257.     new engine_state;
  1258.     new lights_state;
  1259.     new alarm_state;
  1260.     new doors_state;
  1261.     new bonnet_state;
  1262.     new boot_state;
  1263.     new objective_state;
  1264.  
  1265.     // get the old params state
  1266.     GetVehicleParamsEx(vehicleid, engine_state, lights_state, alarm_state, doors_state, bonnet_state, boot_state, objective_state);
  1267.  
  1268.     if(engine_state) return 1;
  1269.     return 0;
  1270. }
  1271.  
  1272.  
  1273.  
  1274. //------------------------------------------------------------------------------
  1275. //                             other fuctions
  1276. //------------------------------------------------------------------------------
  1277.  
  1278. cmd_repair(playerid, params[])
  1279. {
  1280.     new idx,ammount,tmp[256];
  1281.  
  1282.     tmp = strtok(params, idx);
  1283.  
  1284.     // if not in a vehicle
  1285.     if(!IsPlayerInAnyVehicle(playerid)){
  1286.         SendClientMessage(playerid, COLOR_ERROR, "You must be in a vehicle to repair it!");
  1287.         return 1;
  1288.     }
  1289.  
  1290.     // if not at a petrol station
  1291.     if(!IsPlayerAtFuelStation(playerid)){
  1292.         SendClientMessage(playerid, COLOR_ERROR, "You must at a fuel station to repair!");
  1293.         return 1;
  1294.     }
  1295.  
  1296.     new vehicleid = GetPlayerVehicleID(playerid);
  1297.  
  1298.     // if no params have been passed
  1299.     if(!strlen(tmp)){
  1300.         // make them for it
  1301.         new playerCash = GetPlayerMoney(playerid);
  1302.         new invoice = floatround((VehicleInfo[vehicleid][vDamage] * REPAIR_COST), floatround_round);
  1303.         if(playerCash-invoice < 0){ // if they can't afford
  1304.             SendClientMessage(playerid, COLOR_ERROR, "You can't afford to do this!");
  1305.             return 1;
  1306.         }
  1307.         GivePlayerMoney( playerid, (invoice * -1) );
  1308.  
  1309.         SendClientMessage(playerid, COLOR_SERVER_HELP_MSG, "Now Repairing"); // tell the player they are being repaired
  1310.         repairVehicle(vehicleid, -1, 0);  // call the repair function
  1311.         return 1;
  1312.     }
  1313.  
  1314.     // if invalid params have been passed
  1315.     if(!isNumeric(tmp)){
  1316.         SendClientMessage(playerid, COLOR_ERROR, "Usage: /repair {percentage to repair}");
  1317.         return 1;
  1318.     }
  1319.  
  1320.     // if valid params have been passed
  1321.     ammount = strval(tmp);
  1322.    
  1323.     // if ammount is not a valid percentage
  1324.     if(ammount<0 || ammount>100){
  1325.         SendClientMessage(playerid, COLOR_ERROR, "{percentage to repair} must be an integer from 0 to 100!");
  1326.         return 1;
  1327.     }
  1328.  
  1329.     // make them for it
  1330.     new playerCash = GetPlayerMoney(playerid);
  1331.     new invoice = floatround( (ammount * REPAIR_COST), floatround_round );
  1332.     if(playerCash-invoice < 0){ // if they can't afford
  1333.         SendClientMessage(playerid, COLOR_ERROR, "You can't afford to do this!");
  1334.         return 1;
  1335.     }
  1336.     GivePlayerMoney( playerid, (invoice * -1) );
  1337.  
  1338.     // tell the player they are being repaired
  1339.     new string[256];
  1340.     format (string, sizeof (string), "Now repairing %d%%", ammount);
  1341.     SendClientMessage(playerid, COLOR_SERVER_HELP_MSG, string);
  1342.  
  1343.     repairVehicle(vehicleid, ammount, 0); // call the repair function
  1344.  
  1345.     return 1;
  1346. }
  1347.  
  1348. new repairTimer[MAX_VEHICLES];
  1349.  
  1350. forward modifyVehicleDamage(vehicleid, Float: target, Float: rate);
  1351. public modifyVehicleDamage(vehicleid, Float: target, Float: rate)
  1352. {
  1353.     // if we have reached the target
  1354.     if(VehicleInfo[vehicleid][vDamage]-rate <= target){
  1355.         VehicleInfo[vehicleid][vDamage] = target; // correct for small errors
  1356.        
  1357.         // turn the engine back on
  1358.         vehicleParamsSet(vehicleid, 1, -1, -1, -1, -1, -1, -1);
  1359.  
  1360.         KillTimer(repairTimer[vehicleid]); // kill the repair timer
  1361.     }
  1362.    
  1363.     // but if we haven't...
  1364.     else{
  1365.         VehicleInfo[vehicleid][vDamage] -= rate;
  1366.        
  1367.         // make sure engine stays off
  1368.         vehicleParamsSet(vehicleid, 0, -1, -1, -1, -1, -1, -1);
  1369.     }
  1370.    
  1371.     // if we repaired enough, fix the vehicles paneling
  1372.     if(VehicleInfo[vehicleid][vDamage] < 10) RepairVehicle(vehicleid);
  1373.     // set the vehicle health from the vehicle damage
  1374.     new Float: vehicleHealth = (VehicleInfo[vehicleid][vDamage] * -1 +100) * 750/100 + 250;
  1375.     SetVehicleHealth(vehicleid, vehicleHealth);
  1376.    
  1377.     return;
  1378. }
  1379.  
  1380. // repair a vehicleid - pass a negative ammount to repair completely,
  1381. // pass instant a value of false to repair using a timer (so it takes time to repair)
  1382. stock repairVehicle(vehicleid, Float: ammount, instant)
  1383. {
  1384.     // turn the engine off
  1385.     vehicleParamsSet(vehicleid, 0, -1, -1, -1, -1, -1, -1);
  1386.  
  1387.     // if the repair is to happen instantly
  1388.     if(instant){
  1389.         // if ammount is less than 0, repair fully
  1390.         if(ammount < 0) VehicleInfo[vehicleid][vDamage] = 0;
  1391.  
  1392.         // if an ammount is specified
  1393.         else{
  1394.             if(VehicleInfo[vehicleid][vDamage]-ammount < 0) VehicleInfo[vehicleid][vDamage] = 0; // if ammount would over-repair, repair to 0 damage
  1395.  
  1396.             else VehicleInfo[vehicleid][vDamage] -= ammount; // otherwise repair by ammount
  1397.         }
  1398.  
  1399.         // if we repaired enough, fix the vehicles paneling
  1400.         if(VehicleInfo[vehicleid][vDamage] < 10) RepairVehicle(vehicleid);
  1401.         // set the vehicle health from the vehicle damage
  1402.         new Float: vehicleHealth = (VehicleInfo[vehicleid][vDamage] * -1 +100) * 750/100 + 250;
  1403.         SetVehicleHealth(vehicleid, vehicleHealth);
  1404.        
  1405.         // turn the engine back on
  1406.         vehicleParamsSet(vehicleid, 1, -1, -1, -1, -1, -1, -1);
  1407.     }
  1408.  
  1409.     // if not using instant
  1410.     else{
  1411.         // if ammount is less than 0, repair fully
  1412.         if(ammount < 0){
  1413.             repairTimer[vehicleid] = SetTimerEx("modifyVehicleDamage", 100, 1, "dff", vehicleid, 0, REPAIR_RATE);
  1414.         }
  1415.  
  1416.         // if an ammount is specified
  1417.         else{
  1418.             // if ammount would over-repair, repair to 0 damage
  1419.             if(VehicleInfo[vehicleid][vDamage]-ammount <= 0){
  1420.                 repairTimer[vehicleid] = SetTimerEx("modifyVehicleDamage", 100, 1, "dff", vehicleid, 0, REPAIR_RATE);
  1421.             }
  1422.  
  1423.             else{ // otherwise repair by ammount
  1424.                 new Float: target = VehicleInfo[vehicleid][vDamage] - ammount; // target = current damage - ammount
  1425.                 repairTimer[vehicleid] = SetTimerEx("modifyVehicleDamage", 100, 1, "dff", vehicleid, target, REPAIR_RATE); // repair to the target, instead of to 0 damage
  1426.             }
  1427.         }
  1428.     }
  1429.  
  1430.     return;
  1431. }
  1432.  
  1433.  
  1434.  
  1435. new refuelTimer[MAX_VEHICLES];
  1436.  
  1437. // empty the tank before initiating the refuel function loop
  1438. forward drainRefuelVehicle(vehicleid, Float: ammountToRefuel, Float: rate);
  1439. public drainRefuelVehicle(vehicleid, Float: ammountToRefuel, Float: rate)
  1440. {
  1441.     if(rate<0) rate *= -1; // rate must be positive;
  1442.  
  1443.     // check to see if we have reached the target (of 0)
  1444.     if(VehicleInfo[vehicleid][vFuel]-rate <= 0){
  1445.  
  1446.         // stop the timer that is calling this function
  1447.         KillTimer(refuelTimer[vehicleid]);
  1448.  
  1449.         // call the refuel function to refuel the "ammountToRefuel"
  1450.         refuelVehicle(vehicleid, ammountToRefuel, 0, 0);
  1451.  
  1452.         return 1;
  1453.     }
  1454.  
  1455.     // alter the vehicle fuel by the ammount of rate
  1456.     VehicleInfo[vehicleid][vFuel] -= rate;
  1457.  
  1458.     // make sure engine stays off
  1459.     vehicleParamsSet(vehicleid, 0, -1, -1, -1, -1, -1, -1);
  1460.  
  1461.     return 0;
  1462. }
  1463.  
  1464. // returns 1 when it reaches its target
  1465. forward addFuelToVehicle(vehicleid, Float: target, Float: rate, &Float: fuelAdded);
  1466. public addFuelToVehicle(vehicleid, Float: target, Float: rate, &Float: fuelAdded)
  1467. {
  1468.     // if we get a negative rate, drain the tank instead of filling it
  1469.     if(rate<0){
  1470.         // check to see if we have reached the target
  1471.         if(VehicleInfo[vehicleid][vFuel]+rate <= target){
  1472.             // turn the engine back on
  1473.             vehicleParamsSet(vehicleid, 1, -1, -1, -1, -1, -1, -1);
  1474.             KillTimer(refuelTimer[vehicleid]); // stop the timer that is calling this function
  1475.             return 1;
  1476.         }
  1477.     }
  1478.  
  1479.     // if we get a positive rate
  1480.     else{
  1481.         // check to see if we have reached the target
  1482.         if(VehicleInfo[vehicleid][vFuel]+rate >= target){
  1483.             // turn the engine back on
  1484.             vehicleParamsSet(vehicleid, 1, -1, -1, -1, -1, -1, -1);
  1485.             KillTimer(refuelTimer[vehicleid]); // stop the timer that is calling this function
  1486.             return 1;
  1487.         }
  1488.     }
  1489.  
  1490.     // alter the vehicle fuel by the ammount of rate
  1491.     VehicleInfo[vehicleid][vFuel] += rate;
  1492.     fuelAdded += rate;
  1493.  
  1494.     // make sure engine stays off
  1495.     vehicleParamsSet(vehicleid, 0, -1, -1, -1, -1, -1, -1);
  1496.  
  1497.     return 0;
  1498. }
  1499.  
  1500. cmd_refuel(playerid, params[])
  1501. {
  1502.     new idx;
  1503.     new tmp[256];
  1504.  
  1505.     new Float: ammount = -1.0;
  1506.     new fuelType = FUELTYPE_NONE;
  1507.     new reverse = false; // when set to true, removes fuel instead of adding it.
  1508.    
  1509.     new vehicleid = GetPlayerVehicleID(playerid);
  1510.  
  1511.     // if not in a vehicle
  1512.     if(!IsPlayerInAnyVehicle(playerid)){
  1513.         SendClientMessage(playerid, COLOR_ERROR, "You must be in a vehicle to refuel it!");
  1514.         return 1;
  1515.     }
  1516.    
  1517.     // if not at a petrol station
  1518.     if(!IsPlayerAtFuelStation(playerid)){
  1519.         SendClientMessage(playerid, COLOR_ERROR, "You must at a fuel station to refuel!");
  1520.         return 1;
  1521.     }
  1522.    
  1523.    
  1524.     // deal with the first param
  1525.     tmp = strtok(params, idx);
  1526.    
  1527.     // if no params has been passed
  1528.     if(!strlen(tmp)){
  1529.         ammount = -1; // -1 will fill the tank to the top
  1530.     }
  1531.     // if params have been passed
  1532.     else{
  1533.         if(!isNumeric(tmp)){ // if the passed params are invalid, (not a number)
  1534.             SendClientMessage(playerid, COLOR_ERROR, "Usage: /refuel {numerical ammount}");
  1535.             return 1;
  1536.         }
  1537.        
  1538.         ammount = strval(tmp); // convert the passed params to a value
  1539.        
  1540.         if(ammount<0){
  1541.             reverse = true; // if they entered a negative ammount, set reverse to true (to remove fuel from tank)
  1542.             ammount *= -1; // and invert ammount, because ammount must not be negative
  1543.         }
  1544.     }
  1545.    
  1546.    
  1547.     // deal with the second param
  1548.     tmp = strtok(params, idx);
  1549.    
  1550.     // if no params has been passed
  1551.     if(!strlen(tmp)){
  1552.         fuelType = VehicleInfo[vehicleid][vFuelType]; // set the new fuel type to what is already in the tank
  1553.     }
  1554.     // if params have been passed for fuel type
  1555.     else{
  1556.         if(!strcmp (tmp, "battery", true)) fuelType = FUELTYPE_BATTERY; // if the passed param matches a fuel type
  1557.         else if(!strcmp (tmp, "regular", true)) fuelType = FUELTYPE_REGULAR;
  1558.         else if(!strcmp (tmp, "premium", true)) fuelType = FUELTYPE_PREMIUM;
  1559.         else if(!strcmp (tmp, "diesel", true)) fuelType = FUELTYPE_DIESEL;
  1560.         else if(!strcmp (tmp, "aviation", true)) fuelType = FUELTYPE_AVIATION;
  1561.         // if we don't recognize the param they passed
  1562.         else{
  1563.             SendClientMessage(playerid, COLOR_ERROR, "Usage: /refuel {numerical ammount} {\"battery\" / \"regular\" / \"premium\" / \"diesel\" / \"aviation\"}");
  1564.             return 1;
  1565.         }
  1566.     }
  1567.  
  1568.  
  1569.     // check that the selected fuel type is compatible with their car
  1570.     if(!checkFuelVehicle(GetVehicleModel(vehicleid), fuelType)){
  1571.         new string[256];
  1572.         format (string, sizeof (string), "You cannot fill this vehicle with %s!", tmp);
  1573.         SendClientMessage(playerid, COLOR_ERROR, string);
  1574.         return 1;
  1575.     }
  1576.  
  1577.    
  1578.     // check if the player can pay for it
  1579.     new playerCash = GetPlayerMoney(playerid);
  1580.     new invoice = 0;
  1581.     new Float: fuelPrice = getFuelPrice(fuelType);
  1582.     new Float: tankCapacity = vehicleFuelTankCapacity(GetVehicleModel(vehicleid)); // find the tank capacity
  1583.     new Float: ammountToAdd;
  1584.    
  1585.     // if we are filling to a full tank
  1586.     if(ammount<0){
  1587.         // if we are to drain before filling
  1588.         if(fuelType != VehicleInfo[vehicleid][vFuelType]){
  1589.             ammountToAdd = tankCapacity; // add a full tank
  1590.         }
  1591.         else{
  1592.             ammountToAdd = tankCapacity - VehicleInfo[vehicleid][vFuel]; // don't add whats already in the tank
  1593.         }
  1594.     }
  1595.     // if we are filling a set ammount
  1596.     else{
  1597.         ammountToAdd = ammount;
  1598.  
  1599.         // check for overfill and correct it
  1600.         if(fuelType != VehicleInfo[vehicleid][vFuelType]){ // if we are to drain before filling
  1601.             // if we are going to overfill
  1602.             if(ammount>tankCapacity){
  1603.                 ammountToAdd = tankCapacity; // add a full tank
  1604.             }
  1605.         }
  1606.         else{
  1607.             // if we are going to overfill
  1608.             if(ammount > tankCapacity-VehicleInfo[vehicleid][vFuelType]){
  1609.                 ammountToAdd = tankCapacity-VehicleInfo[vehicleid][vFuelType]; // add a full tank
  1610.             }
  1611.         }
  1612.     }
  1613.  
  1614.     invoice = floatround( (ammountToAdd * fuelPrice * REFUEL_COST), floatround_round );
  1615.    
  1616.     // if removing fuel, skip the payment part
  1617.     if(!reverse){
  1618.         if(playerCash-invoice < 0){ // if they can't afford
  1619.             SendClientMessage(playerid, COLOR_ERROR, "You can't afford to do this!");
  1620.             return 1;
  1621.         }
  1622.  
  1623.         GivePlayerMoney( playerid, (invoice * -1) ); // pay
  1624.     }
  1625.  
  1626.    
  1627.     // if we have selected a different fuel than what is already in the tank
  1628.     if(fuelType != VehicleInfo[vehicleid][vFuelType]){
  1629.         new string[256];
  1630.         format (string, sizeof (string), "The fuel you selected (%s) is different to the fuel in the tank. The tank will be emptied before it is refilled!", tmp);
  1631.         SendClientMessage(playerid, COLOR_ERROR, string);
  1632.        
  1633.         // set a timer to call the drainRefuel function
  1634.         refuelTimer[vehicleid] = SetTimerEx("drainRefuelVehicle", 100, 1, "dff", vehicleid, ammount, REFUEL_RATE );
  1635.     }
  1636.     else{
  1637.         refuelVehicle(vehicleid, ammount, 0, reverse); // call the refuel function
  1638.     }
  1639.    
  1640.     // set the fuel type to what we just put in the tank
  1641.     VehicleInfo[vehicleid][vFuelType] = fuelType;
  1642.  
  1643.  
  1644.     // tell the player they are being refueled
  1645.     new string[128];
  1646.     if(ammount<0){
  1647.         format(string, sizeof (string), "Now Refueling.");
  1648.     }
  1649.     else{
  1650.         if(reverse) ammount *= -1;
  1651.         format(string, sizeof (string), "Now Refueling %.0f Litres.", ammount);
  1652.     }
  1653.     SendClientMessage(playerid, COLOR_SERVER_HELP_MSG, string);
  1654.  
  1655.     return 1;
  1656. }
  1657.  
  1658. //                  variables to pass to this function
  1659. // "vehicleid" - the vehicles game id
  1660. // "ammount" - the ammount of fuel that we wish to add/remove from the tank.
  1661. //   use a value of -1 to completely fill/empty the fuel tank.
  1662. // "instant" - when true, the tank will be filled instantly, when false, the tank will be filled in real time
  1663. // "reverse" - when true, ammount will be subtracted from the tank, rather than added
  1664. stock refuelVehicle(vehicleid, Float: ammount, instant, reverse)
  1665. {
  1666.     // turn the engine off
  1667.     vehicleParamsSet(vehicleid, 0, -1, -1, -1, -1, -1, -1);
  1668.  
  1669.     new Float: tankCapacity = vehicleFuelTankCapacity(GetVehicleModel(vehicleid)); // find the tank capacity
  1670.     new Float: target; // the target fuel level to have in the tank at the end of the refill
  1671.  
  1672.  
  1673.     // if we want to empty the tank
  1674.     if(reverse){
  1675.         // if ammount is < 0, just empty the tank completely
  1676.         if(ammount<0){
  1677.             target = 0.0;
  1678.         }
  1679.         else{
  1680.             // if subtracting ammount would exceed the tank limits
  1681.             if(VehicleInfo[vehicleid][vFuel]-ammount < 0.0) target = 0.0; // set the tank to empty
  1682.  
  1683.             // if it doesn't
  1684.             else target = VehicleInfo[vehicleid][vFuel] - ammount; // remove ammount from the tank
  1685.         }
  1686.     }
  1687.  
  1688.     // otherwise fill the tank
  1689.     else{
  1690.         // if ammount is < 0, just fill the tank completely
  1691.         if(ammount<0){
  1692.             target = tankCapacity; // fill the tank to near capacity
  1693.         }
  1694.         else{
  1695.             // if adding ammount would exceed the tank limits
  1696.             if(VehicleInfo[vehicleid][vFuel]+ammount >= tankCapacity) target = tankCapacity; // set the tank to near capacity
  1697.  
  1698.             // if it wouldn't
  1699.             else target = VehicleInfo[vehicleid][vFuel] + ammount; // add ammount to the tank
  1700.         }
  1701.     }
  1702.  
  1703.  
  1704.     // if the refill is to happen instantly
  1705.     if(instant){
  1706.  
  1707.         // set the fuel level to the target we calculated
  1708.         VehicleInfo[vehicleid][vFuel] = target;
  1709.  
  1710.         // turn the engine back on
  1711.         vehicleParamsSet(vehicleid, 1, -1, -1, -1, -1, -1, -1);
  1712.     }
  1713.  
  1714.     // if using realtime
  1715.     else{
  1716.         // if we want to empty the tank
  1717.         if(reverse){
  1718.             // set a timer to empty the tank to the "target" level
  1719.             refuelTimer[vehicleid] = SetTimerEx("addFuelToVehicle", 100, 1, "dff", vehicleid, target, (REFUEL_RATE * -1) );
  1720.         }
  1721.  
  1722.         // otherwise fill the tank
  1723.         else{
  1724.             // set a timer to fill the tank to the "target" level
  1725.             refuelTimer[vehicleid] = SetTimerEx("addFuelToVehicle", 100, 1, "dff", vehicleid, target, REFUEL_RATE );
  1726.         }
  1727.     }
  1728.  
  1729.  
  1730.     return;
  1731. }
  1732.  
  1733.  
  1734.  
  1735. //------------------------------------------------------------------------------
  1736. //                             timed fuctions
  1737. //------------------------------------------------------------------------------
  1738.  
  1739. // calculate the fuel consumption for a vehicleid, return a value in Litres per 100km
  1740. Float: vehicleConsumption (vehid)
  1741. {
  1742.     if(vehicleType(GetVehicleModel(vehid) == 0 )) return -1.0; // if not a vehicle
  1743.     if(!vehicleStateEngine(vehid)) return 0.0; // if the engine is off
  1744.    
  1745.     new Float: speed [3], multiplier, final_speed, Float: health;
  1746.     GetVehicleVelocity (vehid, speed [0], speed [1], speed [2]);
  1747.     final_speed = floatround (floatsqroot (floatpower (speed [0], 2) + floatpower (speed [1], 2) + floatpower (speed [2], 2)) * 160.666667, floatround_round);
  1748.     GetVehicleHealth (vehid, health);
  1749.  
  1750.     switch (vehicleType(GetVehicleModel(vehid)))
  1751.     {
  1752.         case VEHTYPE_SPORT:
  1753.         {
  1754.             if (final_speed <= 80.0)
  1755.             {
  1756.                 multiplier = floatround (final_speed / 10, floatround_round);
  1757.             }
  1758.             else
  1759.             {
  1760.                 multiplier = - floatround (final_speed / 10, floatround_round);
  1761.             }
  1762.  
  1763.             return 9.5 + multiplier * 0.02 + (10.0 - health / 100) / 2;
  1764.         }
  1765.         case VEHTYPE_COMMON:
  1766.         {
  1767.             if (final_speed <= 65.0)
  1768.             {
  1769.                 multiplier = floatround (final_speed / 10, floatround_round);
  1770.             }
  1771.             else
  1772.             {
  1773.                 multiplier = - floatround (final_speed / 10, floatround_round);
  1774.             }
  1775.             return 7.5 + multiplier * 0.02 + (10.0 - health / 100) / 2;
  1776.         }
  1777.         case VEHTYPE_OFFROAD:
  1778.         {
  1779.             if (final_speed <= 85.0)
  1780.             {
  1781.                 multiplier = floatround (final_speed / 10, floatround_round);
  1782.             }
  1783.             else
  1784.             {
  1785.                 multiplier = - floatround (final_speed / 10, floatround_round);
  1786.             }
  1787.             return 10.5 + multiplier * 0.02 + (10.0 - health / 100) / 2;
  1788.         }
  1789.         case VEHTYPE_TRUCK:
  1790.         {
  1791.             if (final_speed <= 75.0)
  1792.             {
  1793.                 multiplier = floatround (final_speed / 10, floatround_round);
  1794.             }
  1795.             else
  1796.             {
  1797.                 multiplier = - floatround (final_speed / 10, floatround_round);
  1798.             }
  1799.             return 15.5 + multiplier * 0.02 + (10.0 - health / 100) / 2;
  1800.         }
  1801.         case VEHTYPE_BIKE:
  1802.         {
  1803.             if (final_speed <= 60.0)
  1804.             {
  1805.                 multiplier = floatround (final_speed / 10, floatround_round);
  1806.             }
  1807.             else
  1808.             {
  1809.                 multiplier = - floatround (final_speed / 10, floatround_round);
  1810.             }
  1811.             return 4.5 + multiplier * 0.02 + (10.0 - health / 100) / 2;
  1812.         }
  1813.         case VEHTYPE_AIR:
  1814.         {
  1815.             multiplier = floatround (final_speed / 10, floatround_round);
  1816.             return 20.0 + multiplier * 0.02 + (10.0 - health / 100) / 2;
  1817.         }
  1818.     }
  1819.     return 0.0; // if vehicletype is 0
  1820. }
  1821.  
  1822. new Float: vehpos [3];
  1823. new Float: vehpos_old [MAX_VEHICLES][3];
  1824.  
  1825. forward updateTextDraws();
  1826. public updateTextDraws()
  1827. {
  1828.     for(new playerid=0; playerid<MAX_PLAYERS; playerid++){
  1829.         if(IsPlayerConnected(playerid) && IsPlayerInAnyVehicle(playerid) && GetPlayerState(playerid) == PLAYER_STATE_DRIVER)
  1830.         {
  1831.             // calculate the textdraws
  1832.             new vehicleid = GetPlayerVehicleID(playerid);
  1833.  
  1834.             // vehid/modelid update
  1835.             PlayerInfo[playerid][pVehicleid] = GetPlayerVehicleID(playerid);
  1836.             VehicleInfo[PlayerInfo[playerid][pVehicleid]][vModelid] = GetVehicleModel(PlayerInfo[playerid][pVehicleid])-400;
  1837.  
  1838.             // velocity
  1839.             getVehicleVelocity(PlayerInfo[playerid][pVehicleid], PlayerInfo[playerid][pSpeedActual], PlayerInfo[playerid][pSpeedGround], PlayerInfo[playerid][pHeading],
  1840.                                 PlayerInfo[playerid][pAttitude], PlayerInfo[playerid][pAltitude], 0, 0, 1);
  1841.  
  1842.             // damage
  1843.             new Float:vehicleHealth;
  1844.             GetVehicleHealth(PlayerInfo[playerid][pVehicleid], vehicleHealth); // max health is 1000, vehicle will catch fire at 250 health
  1845.             if(vehicleHealth>250){
  1846.                 VehicleInfo[PlayerInfo[playerid][pVehicleid]][vDamage] = ( (vehicleHealth-250) * 100/750 ) * -1 + 100; // calculate so damage may be measured from 0 to 100
  1847.             }
  1848.             else VehicleInfo[PlayerInfo[playerid][pVehicleid]][vDamage] = 100;
  1849.  
  1850.             // set the vehicle health from the vehicle damage
  1851.             //vehicleHealth = (VehicleInfo[PlayerInfo[playerid][pVehicleid]][vDamage] * -1 +100) * 750/100 + 250;
  1852.             //SetVehicleHealth(vehicleid, vehicleHealth);
  1853.  
  1854.             // fuel and distance
  1855.             GetVehiclePos(vehicleid, vehpos[0], vehpos[1], vehpos[2]); // get current position
  1856.             vehpos [0] = vehpos [0] - vehpos_old [vehicleid][0]; // calculate the displacement for each axis
  1857.             vehpos [1] = vehpos [1] - vehpos_old [vehicleid][1];
  1858.             vehpos [2] = vehpos [2] - vehpos_old [vehicleid][2];
  1859.             GetVehiclePos (vehicleid, vehpos_old[vehicleid][0], vehpos_old[vehicleid][1], vehpos_old[vehicleid][2]); // record the last position for next time
  1860.            
  1861.             new Float: displacement = floatsqroot(vehpos[0]*vehpos[0] + vehpos[1]*vehpos[1] + vehpos[2]*vehpos[2]); // calculate the displacement in 3d
  1862.            
  1863.             VehicleInfo[PlayerInfo[playerid][pVehicleid]][vTotalDistance] += (displacement * 4/5) / 1000; // add the displacement to the vehicles total distance travelled (convert from meters to km)
  1864.             VehicleInfo[PlayerInfo[playerid][pVehicleid]][vDistanceThisPlayer] += (displacement * 4/5) / 1000; // add the displacement to the vehicles distance travelled for this player
  1865.  
  1866.             // if the vehicle has moved
  1867.             if(displacement != 0){
  1868.                 VehicleInfo[PlayerInfo[playerid][pVehicleid]][vFuel] -= vehicleConsumption(vehicleid) / 25000 * displacement;
  1869.             }
  1870.             else{ // if it has not
  1871.                 VehicleInfo[PlayerInfo[playerid][pVehicleid]][vFuel] -= vehicleConsumption(vehicleid) / 25000 * 20; // engine idling
  1872.             }
  1873.  
  1874.  
  1875.             // update the textdraws
  1876.  
  1877.             //                              vehicle model                   actual      ground          heading    pitch      altitude         damage          fuel            consumption  type        total distance (for vehid)
  1878.             //format(string,sizeof(string),"Police Cruiser LVPD  Velocity gnd 500km/h act 600km/h head 6400mils ptc 6400mils Alt 50000ft   Damage 000%%   Fuel 500.0L 000.0%% 50.0L/100km Aviation Fuel   Distance 5000000km",PlayerInfo[playerid][pSpeed]); // we measure heading in mils
  1879.  
  1880.             new string[32]; // [256] something small will sufice, but for testing use 256
  1881.  
  1882.             // model name
  1883.             format(string,sizeof(string),"%s",vehicleNames[GetVehicleModel(vehicleid) - 400]);
  1884.             TextDrawSetString(VehicleOperationDisplay[0][playerid], string);
  1885.  
  1886.             // ground
  1887.             format(string,sizeof(string),"%.0fkm/h",PlayerInfo[playerid][pSpeedGround]);
  1888.             TextDrawSetString(VehicleOperationDisplay[2][playerid], string);
  1889.  
  1890.             // actual speed
  1891.             format(string,sizeof(string),"%.0fkm/h",PlayerInfo[playerid][pSpeedActual]);
  1892.             TextDrawSetString(VehicleOperationDisplay[4][playerid], string);
  1893.  
  1894.             // heading
  1895.             format(string,sizeof(string),"%.0fmils",PlayerInfo[playerid][pHeading]);
  1896.             TextDrawSetString(VehicleOperationDisplay[6][playerid], string);
  1897.  
  1898.             // elevation
  1899.             format(string,sizeof(string),"%.0fmils",PlayerInfo[playerid][pAttitude]);
  1900.             TextDrawSetString(VehicleOperationDisplay[8][playerid], string);
  1901.  
  1902.             // altitude
  1903.             format(string,sizeof(string),"%.0fft",PlayerInfo[playerid][pAltitude]);
  1904.             TextDrawSetString(VehicleOperationDisplay[10][playerid], string);
  1905.  
  1906.             // damage
  1907.             format(string,sizeof(string),"%.0f%%",VehicleInfo[PlayerInfo[playerid][pVehicleid]][vDamage]);
  1908.             TextDrawSetString(VehicleOperationDisplay[12][playerid], string);
  1909.  
  1910.             // fuel litres
  1911.             format(string,sizeof(string),"%.1fL",VehicleInfo[PlayerInfo[playerid][pVehicleid]][vFuel]);
  1912.             TextDrawSetString(VehicleOperationDisplay[14][playerid], string);
  1913.  
  1914.             // fuel percent
  1915.             new Float: fuelPercent = VehicleInfo[PlayerInfo[playerid][pVehicleid]][vFuel] / vehicleFuelTankCapacity(GetVehicleModel(vehicleid)) * 100;
  1916.             format(string,sizeof(string),"%.1f%%",fuelPercent);
  1917.             TextDrawSetString(VehicleOperationDisplay[15][playerid], string);
  1918.  
  1919.             // fuel consumption
  1920.             format(string,sizeof(string),"%.1fL/100km",vehicleConsumption(PlayerInfo[playerid][pVehicleid]));
  1921.             TextDrawSetString(VehicleOperationDisplay[16][playerid], string);
  1922.  
  1923.             // fuel type
  1924.             format(string,sizeof(string),"%s",fuelTypeString(VehicleInfo[PlayerInfo[playerid][pVehicleid]][vFuelType]));
  1925.             TextDrawSetString(VehicleOperationDisplay[17][playerid], string);
  1926.  
  1927.             // distance
  1928.             format(string,sizeof(string),"%.0fkm",VehicleInfo[PlayerInfo[playerid][pVehicleid]][vTotalDistance]);
  1929.             TextDrawSetString(VehicleOperationDisplay[19][playerid], string);
  1930.         }
  1931.     }
  1932. }
  1933.  
  1934.  
  1935.  
  1936. //------------------------------------------------------------------------------
  1937. //                            Don Walt "Enforcer"
  1938. //------------------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement