31.01.2012, 14:55
Hello,
I downloaded a speedometer filterscript, and tried to add the cruisecontrol fs into it,
but i want the player to only press CTRL Once, and that works. But i wan't the cruisecontrol to stop
when the player presses W Or D (so up or down) and i can't get this to work..
i have to brake hard to stop the cruisecontrol
I downloaded a speedometer filterscript, and tried to add the cruisecontrol fs into it,
but i want the player to only press CTRL Once, and that works. But i wan't the cruisecontrol to stop
when the player presses W Or D (so up or down) and i can't get this to work..
i have to brake hard to stop the cruisecontrol
Код:
#include <a_samp> #include <sscanf2> #include <streamer> #include <zcmd> #pragma tabsize 0 // ****************************************************************************************************************************** // Settings that can be changed // ****************************************************************************************************************************** // Define where the Camera-file is located (all camera's are stored in one file) and the max amount of speedcamera's #define CameraFile "speedo/Cameras.ini" #define MAX_CAMERAS 100 // Define maximum fuel amount (default: 2400) // Changing MaxFuel changes how fast a vehicle will run without fuel // 1 fuel is consumed every half a second, that's 2 fuel per second // A value of 2400 allows you to drive 2400/2 = 1200 seconds (or 1200/60 = 20 minutes) without refuelling new MaxFuel = 2400; // RefuelMaxPrice is the price you pay for a total refuel (when the vehicle has no more fuel), the price to pay is calculated // by the amount of fuel to refuel (pay 50% of RefuelMaxPrice when vehicle has half a fuel-tank left) new RefuelMaxPrice = 1000; // An extra setting to disable the shadows for the speedometer and fueldraws (shadows enabled by default) new bool:DisableShadows = false; // ****************************************************************************************************************************** // Enums and the array-setups that use them // ****************************************************************************************************************************** // Setup a custom type that holds all data about a speedcamera enum TSpeedCamera { Float:CamX, // Holds the X-coordinate of the camera Float:CamY, // Holds the Y-coordinate of the camera Float:CamZ, // Holds the Z-coordinate of the camera Float:CamAngle, // Holds the Angle of the camera CamSpeed, // Holds the maximum speed allowed to pass this camera without being caught CamObj1, // Holds the reference to the first camera object CamObj2 // Holds the reference to the second camera object } new ACameras[MAX_CAMERAS][TSpeedCamera]; // Setup a custom type that holds the data of pickups enum TPickupData { Float:pux, // Holds the x-position of the refuel-pickup Float:puy, // Holds the y-position of the refuel-pickup Float:puz, // Holds the z-position of the refuel-pickup PickupID // Holds the PickupID of the refuel-pickup } // Holds the data for pickups for refuelling (maximum 50 refuel-pickups) new ARefuelPickups[50][TPickupData]; // Setup a custom type to hold all data about a vehicle enum TVehicleData { Fuel // Holds the amount of fuel for this vehicle } // Setup an array which holds all data for every vehicleid, max 2000 vehicles (server limit) new AVehicleData[2000][TVehicleData]; // Setup all the fields required for the player data (Speedometer TextDraw, current job, ...) enum TPlayerData { Text:SpeedometerText, // The TextDraw of the speedometer for this player Text:FuelGauge, // The textdraw of the fuel-gauge for this player Text:CruiseControlText, CruiseControlState, SpeedometerTimer, // Holds the reference to the speedometer timer for this player PlayerSpeed, // Holds the speed of the player PlayerCaughtSpeeding // This holds a value to prevent being caught multiple times by the same speedcamera } // Create an array to hold the playerdata for every player new APlayerData[MAX_PLAYERS][TPlayerData]; // These variables are used when starting the script and debugging purposes new TotalRefuelStations, TotalCameras; //cruisecontrol new Float:PlayerCruiseSpeed[MAX_PLAYERS]; new Float:PlayerHeadingAngle[MAX_PLAYERS]; new CCKey = KEY_ACTION; forward CruiseControl(playerid); // ****************************************************************************************************************************** // Callbacks // ****************************************************************************************************************************** // The main function (used only once when the server loads) main() { } // This callback gets called when the server initializes the filterscript public OnFilterScriptInit() { // Loop through all vehicles for (new vid; vid < 2000; vid++) { // If this vehicle belongs to the PPC_Housing script, don't refuel it, as the housing script manages the fuel for this vehicle // by using remote calls to this script if (CallRemoteFunction("Housing_IsVehicleOwned", "i", vid) == 1) { // The vehicle is owned by a player in the housing script, so do nothing, the housing script manages this vehicle's fuel } else // The vehicle doesn't belong to the housing script (it's created and managed by another script), set the fuel to maximum AVehicleData[vid][Fuel] = MaxFuel; } // Add all refuel-pickups to the world (including their icon) AddRefuelPickup(-1471.5, 1863.75, 32.7); AddRefuelPickup(-1326.5, 2677.5, 50.1); AddRefuelPickup(611.5, 1694.5, 7.0); AddRefuelPickup(-2249.25, -2559.0, 32.0); AddRefuelPickup(-1606.5, -2714.0, 48.6); AddRefuelPickup(-93.5, -1175.0, 2.3); AddRefuelPickup(1377.5, 457.0, 19.9); AddRefuelPickup(651.5, -565.5, 16.4); AddRefuelPickup(-1675.75, 412.75, 7.2); AddRefuelPickup(-2405.50, 976.25, 45.3); AddRefuelPickup(-2023.25, 156.75, 28.9); AddRefuelPickup(-1131.75, -204.25, 14.2); AddRefuelPickup(66.50, 1220.50, 18.9); AddRefuelPickup(350.50, 2537.50, 16.8); AddRefuelPickup(2147.00, 2747.75, 10.9); AddRefuelPickup(2639.75, 1106.00, 10.9); AddRefuelPickup(2115.00, 920.00, 10.9); AddRefuelPickup(2202.00, 2475.00, 10.9); AddRefuelPickup(1596.50, 2199.75, 10.9); AddRefuelPickup(1584.25, 1448.25, 10.9); AddRefuelPickup(1004.25, -940.50, 42.2); AddRefuelPickup(1935.00, -1772.75, 13.4); // Load all speedcamera's CameraFile_Load(); printf("\n----------------------------------------"); printf("PPC Speedometer filterscript initialized"); printf("Gas-stations created: %i", TotalRefuelStations); printf("Speedcamera's loaded: %i", TotalCameras); printf("----------------------------------------\n"); return 1; } // This callback gets called when a player connects to the server public OnPlayerConnect(playerid) { // Setup the speedometer for this player Speedometer_Setup(playerid); return 1; } // This callback gets called when a player disconnects from the server public OnPlayerDisconnect(playerid, reason) { // Cleanup the speedometer for this player Speedometer_Cleanup(playerid); APlayerData[playerid][CruiseControlState] = 0; return 1; } // This callback gets called when a vehicle respawns at it's spawn-location (where it was created) public OnVehicleSpawn(vehicleid) { // If this vehicle belongs to the PPC_Housing script, don't refuel it, as the housing script manages the fuel for this vehicle // by using remote calls to this script if (CallRemoteFunction("Housing_IsVehicleOwned", "i", vehicleid) == 1) { // The vehicle is owned by a player in the housing script, so do nothing, the housing script manages this vehicle's fuel } else // The vehicle doesn't belong to the housing script (it's created and managed by another script), set the fuel to maximum AVehicleData[vehicleid][Fuel] = MaxFuel; return 1; } // This callback gets called whenever a player changes state public OnPlayerStateChange(playerid,newstate,oldstate) { // Setup local variables new vehicleid, engine, lights, alarm, doors, bonnet, boot, objective; // Check if the player entered a vehicle as driver if (newstate == PLAYER_STATE_DRIVER) { // Get the player's vehicle vehicleid = GetPlayerVehicleID(playerid); // Check if the vehicle has fuel if (AVehicleData[vehicleid][Fuel] > 0) { // Start the engine and turn on the lights GetVehicleParamsEx(vehicleid, engine, lights, alarm, doors, bonnet, boot, objective); SetVehicleParamsEx(vehicleid, 1, 1, alarm, doors, bonnet, boot, objective); } } } // This callback gets called when a player exits his vehicle public OnPlayerExitVehicle(playerid, vehicleid) { // Setup local variables new engine, lights, alarm, doors, bonnet, boot, objective; // Check if the player is the driver of the vehicle if (GetPlayerVehicleSeat(playerid) == 0) { // Turn off the lights and engine GetVehicleParamsEx(vehicleid, engine, lights, alarm, doors, bonnet, boot, objective); SetVehicleParamsEx(vehicleid, 0, 0, alarm, doors, bonnet, boot, objective); } APlayerData[playerid][CruiseControlState] = 0; return 1; } // This callback gets called whenever a player presses a key public OnPlayerKeyStateChange(playerid, newkeys, oldkeys) { // Refuel a vehicle when driving a vehicle and pressing the HORN key near a refuelpickup // Check if the player presses the HORN key if ((newkeys & KEY_CROUCH) && !(oldkeys & KEY_CROUCH)) { // Check if the player is driving a vehicle if (GetPlayerVehicleSeat(playerid) == 0) { // Loop through all ARefuelPickups for (new i; i < sizeof(ARefuelPickups); i++) { // Check if this refuel-pickup exists (check for a valid pickup) if (IsValidDynamicPickup(ARefuelPickups[i][PickupID])) { // Check if the player is in range of a refuelpickup if(IsPlayerInRangeOfPoint(playerid, 5.0, ARefuelPickups[i][pux], ARefuelPickups[i][puy], ARefuelPickups[i][puz])) { // Show a message that the player's vehicle is refuelling GameTextForPlayer(playerid, "~g~Refuelling...", 3000, 4); // Don't allow the player to move again (the timer will allow it after refuelling) TogglePlayerControllable(playerid, 0); // Start a timer (let the player wait until the vehicle is refuelled) SetTimerEx("RefuelVehicle", 5000, false, "i", playerid); // Stop the search break; } } else // No more refuel-pickups, so stop searching through the array break; } } } //cruise if ((newkeys & CCKey) && !(oldkeys & CCKey) && IsPlayerInAnyVehicle(playerid) && GetPlayerState(playerid) == PLAYER_STATE_DRIVER) { new vid = GetPlayerVehicleID(playerid); if (GetVehicleSpeed(vid) == 0) return false; new Float:x, Float:y, Float:z; GetVehicleVelocity(vid, x, y, z); GetVehicleZAngle(vid, PlayerHeadingAngle[playerid]); DistanceFlat(0, 0, x, y, PlayerCruiseSpeed[playerid]); SetTimerEx("CruiseControl", 500, false, "d", playerid); APlayerData[playerid][CruiseControlState] = 1; } else if (PlayerCruiseSpeed[playerid] != 0.00 && (newkeys & KEY_HANDBRAKE)) { PlayerCruiseSpeed[playerid] = 0.00; APlayerData[playerid][CruiseControlState] = 0; } if((newkeys & KEY_UP)) { if (GetPlayerState(playerid) == PLAYER_STATE_DRIVER) { if(APlayerData[playerid][CruiseControlState] == 1) { APlayerData[playerid][CruiseControlState] = 0; } } } return 1; } // ****************************************************************************************************************************** // Commands // ****************************************************************************************************************************** // This command allows you to create a speedcamera COMMAND:createcamera(playerid, params[]) { // Setup local variables new Float:x, Float:y, Float:z, Float:rot, MaxSpeed, Msg[128]; // If a player hasn't logged in properly, he cannot use this command if (INT_IsPlayerLoggedIn(playerid) == 0) return 0; // If the player has an insufficient admin-level (he needs level 5 or RCON admin), exit the command // returning "SERVER: Unknown command" to the player if (INT_CheckPlayerAdminLevel(playerid, 5) == 0) return 0; // Split the parameters to useable variables if (sscanf(params, "i", MaxSpeed)) SendClientMessage(playerid, 0xFFFFFFFF, "{FF0000}Usage: \"/createcamera <max_speed>\""); else { // Check if the player is on foot if (GetPlayerVehicleSeat(playerid) == -1) { // Get player's position and facing angle GetPlayerPos(playerid, x, y, z); GetPlayerFacingAngle(playerid, rot); z = z - 1.0; // Adjust camera Z-coordinate 1m lower than normal (otherwise the camera floats in the air) // Move the player a bit, otherwise he could get stuck inside the camera-object SetPlayerPos(playerid, x, y + 1.0, z + 1.0); // Save the camera to a file for (new CamID; CamID < MAX_CAMERAS; CamID++) { // Check if this index is free if (ACameras[CamID][CamSpeed] == 0) { // Setup this camera (create the objects and store the data) SetupSpeedCamera(CamID, x, y, z, rot, MaxSpeed); // Also save the entire camerafile again to add this new camera to the file CameraFile_Save(); // Let the player know he created a new camera format(Msg, 128, "{00FF00}You've created a speed-camera with ID: {FFFF00}%i", CamID); SendClientMessage(playerid, 0xFFFFFFFF, Msg); // Exit the function return 1; } } // In case all camera-slots are occupied (100 camera's have been created already), let the player know about it format(Msg, 128, "{FF0000}You cannot create more than %i speedcamera's", MAX_CAMERAS); SendClientMessage(playerid, 0xFFFFFFFF, Msg); } else SendClientMessage(playerid, 0xFFFFFFFF, "{FF0000}You must be on foot to use this command"); } // Let the server know that this was a valid command return 1; } // This command allows you to delete a speedcamera COMMAND:delcamera(playerid, params[]) { // Setup local variables new Msg[128]; // If a player hasn't logged in properly, he cannot use this command if (INT_IsPlayerLoggedIn(playerid) == 0) return 0; // If the player has an insufficient admin-level (he needs level 5 or RCON admin), exit the command // returning "SERVER: Unknown command" to the player if (INT_CheckPlayerAdminLevel(playerid, 5) == 0) return 0; // Check if the player is on foot if (GetPlayerVehicleSeat(playerid) == -1) { // Loop through all camera's for (new CamID; CamID < MAX_CAMERAS; CamID++) { // Check if this index is used if (ACameras[CamID][CamSpeed] != 0) { // Check if the player is in range of the camera if (IsPlayerInRangeOfPoint(playerid, 5.0, ACameras[CamID][CamX], ACameras[CamID][CamY], ACameras[CamID][CamZ])) { // Delete both camera objects DestroyDynamicObject(ACameras[CamID][CamObj1]); DestroyDynamicObject(ACameras[CamID][CamObj2]); // Also clear the data from memory ACameras[CamID][CamX] = 0.0; ACameras[CamID][CamY] = 0.0; ACameras[CamID][CamZ] = 0.0; ACameras[CamID][CamAngle] = 0.0; ACameras[CamID][CamSpeed] = 0; ACameras[CamID][CamObj1] = 0; ACameras[CamID][CamObj2] = 0; // Also save the entire camerafile again to remove this camera from the file CameraFile_Save(); // Let the player know he deleted a camera format(Msg, 128, "{00FF00}You've deleted speed-camera {FFFF00}%i", CamID); SendClientMessage(playerid, 0xFFFFFFFF, Msg); // Exit the function return 1; } } } // In case the player wasn't near a speedcamera, inform him about it SendClientMessage(playerid, 0xFFFFFFFF, "{FF0000}You must be near a speedcamera to delete it"); } else SendClientMessage(playerid, 0xFFFFFFFF, "{FF0000}You must be on foot to use this command"); // Let the server know that this was a valid command return 1; } // This command allows you to refuel your vehicle for free (admins only) COMMAND:fuel(playerid, params[]) { // Setup local variables new vid, engine, lights, alarm, doors, bonnet, boot, objective; // If a player hasn't logged in properly, he cannot use this command if (INT_IsPlayerLoggedIn(playerid) == 0) return 0; // If the player has an insufficient admin-level (he needs level 1 or RCON admin), exit the command // returning "SERVER: Unknown command" to the player if (INT_CheckPlayerAdminLevel(playerid, 1) == 0) return 0; // Check if the player is the driver of a vehicle if (GetPlayerVehicleSeat(playerid) == 0) { // Get the vehicleid vid = GetPlayerVehicleID(playerid); // Refuel the vehicle AVehicleData[vid][Fuel] = MaxFuel; // Also (re-)start the engine and turn on the lights in case the vehicle is completely out of fuel GetVehicleParamsEx(vid, engine, lights, alarm, doors, bonnet, boot, objective); SetVehicleParamsEx(vid, 1, 1, alarm, doors, bonnet, boot, objective); // Let the player know about it SendClientMessage(playerid, 0xFFFFFFFF, "{00FF00}Your vehicle is refuelled"); } else SendClientMessage(playerid, 0xFFFFFFFF, "{FF0000}You're not driving a vehicle"); // Let the server know that this was a valid command return 1; } // ****************************************************************************************************************************** // Speedometer functions // ****************************************************************************************************************************** // This function sets up the speedometer for the given player Speedometer_Setup(playerid) { // Setup the speedometer for the player APlayerData[playerid][SpeedometerText] = TextDrawCreate(500.0, 395.0, " "); APlayerData[playerid][FuelGauge] = TextDrawCreate(500.0, 410.0, " "); APlayerData[playerid][CruiseControlText] = TextDrawCreate(500.0, 380.0, " "); // Disable shadows if required if (DisableShadows == true) { TextDrawSetShadow(APlayerData[playerid][SpeedometerText], 0); TextDrawSetShadow(APlayerData[playerid][FuelGauge], 0); TextDrawSetShadow(APlayerData[playerid][CruiseControlText], 0); } // Enable the TextDraw for this player TextDrawShowForPlayer(playerid, APlayerData[playerid][SpeedometerText]); TextDrawShowForPlayer(playerid, APlayerData[playerid][FuelGauge]); TextDrawShowForPlayer(playerid, APlayerData[playerid][CruiseControlText]); // Start the speedometer timer for this player APlayerData[playerid][SpeedometerTimer] = SetTimerEx("Speedometer_Update", 500, true, "i", playerid); return 1; } // This function cleans up the speedometer for the given player Speedometer_Cleanup(playerid) { // Destroy the speedometer textdraw TextDrawDestroy(APlayerData[playerid][SpeedometerText]); TextDrawDestroy(APlayerData[playerid][FuelGauge]); TextDrawDestroy(APlayerData[playerid][CruiseControlText]); // Kill the speedometer timer KillTimer(APlayerData[playerid][SpeedometerTimer]); // Set player speed to 0 APlayerData[playerid][PlayerSpeed] = 0; return 1; } // Forward the function needed to update the speedometer forward Speedometer_Update(playerid); // This function gets called by a timer which runs every 500ms to display and update the speedometer public Speedometer_Update(playerid) { // Setup local variables new vid, Float:speed_x, Float:speed_y, Float:speed_z, Float:final_speed, speed_string[50], final_speed_int, Float:vehiclehealth; new FuelString[50], FuelStatus[20]; // Get the ID of the player's vehicle vid = GetPlayerVehicleID(playerid); // If the player is inside a vehicle if(vid != 0) { // Get the vehicles velocity GetVehicleVelocity(vid, speed_x, speed_y, speed_z); // Calculate the speed (in kph) final_speed = floatsqroot(((speed_x * speed_x) + (speed_y * speed_y)) + (speed_z * speed_z)) * 158.179; // Convert the float value to an int value final_speed_int = floatround(final_speed, floatround_round); // Also save the speed for the player APlayerData[playerid][PlayerSpeed] = final_speed_int; // Setup the string to display for the player and display it format(speed_string, 50, "~w~Speed: ~b~%i~w~ kph", final_speed_int); TextDrawSetString(APlayerData[playerid][SpeedometerText], speed_string); if(APlayerData[playerid][CruiseControlState] == 0) { TextDrawSetString(APlayerData[playerid][CruiseControlText], "CruiseControl:Off"); } else { TextDrawSetString(APlayerData[playerid][CruiseControlText], "CruiseControl:On"); } // Also display the vehicle's health through the player-health bar GetVehicleHealth(vid, vehiclehealth); SetPlayerHealth(vid, vehiclehealth / 10.0); // Check if the player is the driver of the vehicle (otherwise every passenger would consume fuel for just being in the car) if (GetPlayerVehicleSeat(playerid) == 0) if ((final_speed_int > 10) && (AVehicleData[vid][Fuel] > 0)) // Check if the speed is above 10kph and if the vehicle didn't run out of fuel AVehicleData[vid][Fuel] = AVehicleData[vid][Fuel] - 1; // Decrease the fuel for this vehicle every time the timer is run // Construct the fuelgauge if ((AVehicleData[vid][Fuel] > 0) && (AVehicleData[vid][Fuel] < 100000)) format(FuelStatus, 20, "~g~%s~r~%s", "I", "IIIIIIIII"); // Fuel is between 0% and 10% full if ((AVehicleData[vid][Fuel] >= ((MaxFuel / 10) * 1)) && (AVehicleData[vid][Fuel] < ((MaxFuel / 10) * 2))) format(FuelStatus, 20, "~g~%s~r~%s", "II", "IIIIIIII"); // Fuel is between 10% and 20% full if ((AVehicleData[vid][Fuel] >= ((MaxFuel / 10) * 2)) && (AVehicleData[vid][Fuel] < ((MaxFuel / 10) * 3))) format(FuelStatus, 20, "~g~%s~r~%s", "III", "IIIIIII"); // Fuel is between 20% and 30% full if ((AVehicleData[vid][Fuel] >= ((MaxFuel / 10) * 3)) && (AVehicleData[vid][Fuel] < ((MaxFuel / 10) * 4))) format(FuelStatus, 20, "~g~%s~r~%s", "IIII", "IIIIII"); // Fuel is between 30% and 40% full if ((AVehicleData[vid][Fuel] >= ((MaxFuel / 10) * 4)) && (AVehicleData[vid][Fuel] < ((MaxFuel / 10) * 5))) format(FuelStatus, 20, "~g~%s~r~%s", "IIIII", "IIIII"); // Fuel is between 40% and 50% full if ((AVehicleData[vid][Fuel] >= ((MaxFuel / 10) * 5)) && (AVehicleData[vid][Fuel] < ((MaxFuel / 10) * 6))) format(FuelStatus, 20, "~g~%s~r~%s", "IIIIII", "IIII"); // Fuel is between 50% and 60% full if ((AVehicleData[vid][Fuel] >= ((MaxFuel / 10) * 6)) && (AVehicleData[vid][Fuel] < ((MaxFuel / 10) * 7))) format(FuelStatus, 20, "~g~%s~r~%s", "IIIIIII", "III"); // Fuel is between 60% and 70% full if ((AVehicleData[vid][Fuel] >= ((MaxFuel / 10) * 7)) && (AVehicleData[vid][Fuel] < ((MaxFuel / 10) * 8))) format(FuelStatus, 20, "~g~%s~r~%s", "IIIIIIII", "II"); // Fuel is between 70% and 80% full if ((AVehicleData[vid][Fuel] >= ((MaxFuel / 10) * 8)) && (AVehicleData[vid][Fuel] < ((MaxFuel / 10) * 9))) format(FuelStatus, 20, "~g~%s~r~%s", "IIIIIIIII", "I"); // Fuel is between 80% and 90% full if ((AVehicleData[vid][Fuel] >= ((MaxFuel / 10) * 9)) && (AVehicleData[vid][Fuel] <= MaxFuel)) format(FuelStatus, 20, "~g~%s", "IIIIIIIIII"); // Fuel is between 90% and 100% full (all bars are green) if (AVehicleData[vid][Fuel] == 0) format(FuelStatus, 20, "~r~%s", "IIIIIIIIII"); // Fuel is empty (all bars are red) // Format the final fuel-gauge readout format(FuelString, 50, "~w~Fuel: %s", FuelStatus); // Display the fuel-gauge TextDrawSetString(APlayerData[playerid][FuelGauge], FuelString); // Check if the vehicle is out of fuel if (AVehicleData[vid][Fuel] == 0) { // Stop the engine and turn off the lights so the player cannot drive anymore with this vehicle new engine,lights,alarm,doors,bonnet,boot,objective; GetVehicleParamsEx(vid, engine, lights, alarm, doors, bonnet, boot, objective); SetVehicleParamsEx(vid, 0, 0, alarm, doors, bonnet, boot, objective); } // Check if the player is not in any plane or helicopter (those cannot be caught by speedcamera's) if (IsVehicleAirVehicle(vid) == 0) CheckPlayerSpeeding(playerid); } else { // If the player is not inside a vehicle, display an empty string (looks like the speedometer is gone) TextDrawSetString(APlayerData[playerid][SpeedometerText], " "); TextDrawSetString(APlayerData[playerid][FuelGauge], " "); TextDrawSetString(APlayerData[playerid][CruiseControlText], " "); // Set the speed of the player to 0 APlayerData[playerid][PlayerSpeed] = 0; } } // This function checks if the player is speeding near a speedcamera CheckPlayerSpeeding(playerid) { // Check if the player hasn't been caught speeding recently if (APlayerData[playerid][PlayerCaughtSpeeding] == 0) { // Loop through all speedcameras for (new CamID; CamID < MAX_CAMERAS; CamID++) { // Check if this camera has been created if (ACameras[CamID][CamSpeed] != 0) { // Check if the player is the driver of the vehicle if (GetPlayerVehicleSeat(playerid) == 0) { // Check if the player's speed is greater than the speed allowed by this camera (no need to process a distance-check if not speeding) if (APlayerData[playerid][PlayerSpeed] > ACameras[CamID][CamSpeed]) { // Check if the player is near the camera if (IsPlayerInRangeOfPoint(playerid, 50.0, ACameras[CamID][CamX], ACameras[CamID][CamY], ACameras[CamID][CamZ])) { // Prevent the player being caught multiple times by the same speed-camera APlayerData[playerid][PlayerCaughtSpeeding] = 20; // Increase the wanted-level of this player by 1 star SetPlayerWantedLevel(playerid, GetPlayerWantedLevel(playerid) + 1); // Let the player know he's been caught speeding SendClientMessage(playerid, 0xFFFFFFFF, "{FF0000}You've been caught by a speedtrap, slow down!"); } } } } } } else // If the player has been caught before, reduce the value until it's 0 again, then he can be caught again APlayerData[playerid][PlayerCaughtSpeeding]--; } // This function returns "1" if the given vehicle-id is a plane or helicopter IsVehicleAirVehicle(vid) { switch (GetVehicleModel(vid)) { case 592, 577, 511, 512, 593, 520, 553, 476, 519, 460, 513, 548, 425, 417, 487, 488, 497, 563, 447, 469: return 1; default: return 0; } return 0; } // Forward the refueltimer forward RefuelVehicle(playerid); // This timer-function is called when a player refuels near a refuelpickup public RefuelVehicle(playerid) { new RefuelMsg[128]; // Get the vehicle-id of the player's vehicle new vid = GetPlayerVehicleID(playerid); // Calculate the amount of fuel that needs to be refuelled new Amount = MaxFuel - AVehicleData[vid][Fuel]; // Calculate the price to refuel new RefuelPrice = (Amount * RefuelMaxPrice) / MaxFuel; // Check if the player has enough cash if (INT_GetPlayerMoney(playerid) >= RefuelPrice) { // Refuel the vehicle AVehicleData[vid][Fuel] = MaxFuel; // Withdraw the money from the player INT_GivePlayerMoney(playerid, -RefuelPrice); // Let the player know he refuelled his vehicle format(RefuelMsg, 128, "{00FF00}You refuelled your vehicle for $%i", RefuelPrice); SendClientMessage(playerid, 0xFFFFFFFF, RefuelMsg); } else SendClientMessage(playerid, 0xFFFFFFFF, "{FF0000}You don't have enough cash to refuel your vehicle"); // Allow the player to move again TogglePlayerControllable(playerid, 1); return 1; } // This function is used to add refuelling pickups to the map AddRefuelPickup(Float:x, Float:y, Float:z) { // Add the pickup-id to the ARefuelPickups array for (new i; i < sizeof(ARefuelPickups); i++) { // If an empty array-index is found (no valid pickup) if (!IsValidDynamicPickup(ARefuelPickups[i][PickupID])) { // Store the pickup-id in this empty slot ARefuelPickups[i][PickupID] = CreateDynamicPickup(1244, 1, x, y, z, 0); // Type 1, cannot be pickup up, exists all the time ARefuelPickups[i][pux] = x; ARefuelPickups[i][puy] = y; ARefuelPickups[i][puz] = z; // Count the total amount of refuelstations that have been created TotalRefuelStations++; // Add a 3DText message above the refuel-pickup CreateDynamic3DTextLabel("Honk the horn\nto refuel your vehicle", 0x008080FF, x, y, z + 0.8, 30.0); // Add an icon to the map for this refuel-spot CreateDynamicMapIcon(x, y, z, 56, 0, 0, 0, -1, 300.0); // Stop browsing through the array break; } } } // This function will load the speedcamera's datafile (used when the server is started to load all cameras) CameraFile_Load() { // Setup local variables new file[128], File:CFile, LineFromFile[100], ParameterName[50], ParameterValue[50]; new CamID, Float:x, Float:y, Float:z, Float:rot, MaxSpeed; // Construct the complete filename for this camera-file format(file, sizeof(file), CameraFile); // Check if the camerafile exists if (fexist(file)) { // Open the camerafile for reading CFile = fopen(file, io_read); // Read the first line of the file fread(CFile, LineFromFile); // Keep reading until the end of the file is found (no more data) // An empty line between data-segments still has the NewLine characters (\r\n) so it's not completely empty // Reading past the last line will read a completely empty line, therefore indicating the end of the file while (strlen(LineFromFile) > 0) { StripNewLine(LineFromFile); // Strip any newline characters from the LineFromFile sscanf(LineFromFile, "s[50]s[50]", ParameterName, ParameterValue); // Extract parametername and parametervalue // Check if there is anything in the LineFromFile (skipping empty lines) if (strlen(LineFromFile) > 0) { // Check if a header for a camera has been found if (strcmp(ParameterName, "[Camera]", false) == 0) { // Clear all variables x = 0.0; y = 0.0; z = 0.0; rot = 0.0; MaxSpeed = 0; } // Store the proper value in the proper place if (strcmp(ParameterName, "CamX", false) == 0) // If the parametername is correct ("CamX") x = floatstr(ParameterValue); // Store the CamX if (strcmp(ParameterName, "CamY", false) == 0) // If the parametername is correct ("CamY") y = floatstr(ParameterValue); // Store the CamY if (strcmp(ParameterName, "CamZ", false) == 0) // If the parametername is correct ("CamZ") z = floatstr(ParameterValue); // Store the CamZ if (strcmp(ParameterName, "CamAngle", false) == 0) // If the parametername is correct ("CamAngle") rot = floatstr(ParameterValue); // Store the CamAngle if (strcmp(ParameterName, "CamSpeed", false) == 0) // If the parametername is correct ("CamSpeed") MaxSpeed = strval(ParameterValue); // Store the CamSpeed // Check if a end of a camera has been found if (strcmp(ParameterName, "[/Camera]", false) == 0) { SetupSpeedCamera(CamID, x, y, z, rot, MaxSpeed); // Setup the camera TotalCameras++; // Count the total camera's loaded from the file CamID++; // Increase the CamID to select the next camera before data is loaded (in case more camera's are found in the file) } } // Read the next line of the file fread(CFile, LineFromFile); } // Close the file fclose(CFile); } } // This function will save the speedcamera's datafile CameraFile_Save() { // Setup local variables new file[100], File:PFile, LineForFile[100]; // Save the file format(file, sizeof(file), CameraFile); // Construct the complete filename for the camera-file PFile = fopen(file, io_write); // Open the camera-file for writing // Loop through all camera's for (new CamID; CamID < MAX_CAMERAS; CamID++) { // Check if this index holds a camera if (ACameras[CamID][CamSpeed] != 0) { fwrite(PFile, "[Camera]\r\n"); // Save the header of the camera format(LineForFile, 100, "CamX %f\r\n", ACameras[CamID][CamX]); fwrite(PFile, LineForFile); // And save it to the file format(LineForFile, 100, "CamY %f\r\n", ACameras[CamID][CamY]); fwrite(PFile, LineForFile); // And save it to the file format(LineForFile, 100, "CamZ %f\r\n", ACameras[CamID][CamZ]); fwrite(PFile, LineForFile); // And save it to the file format(LineForFile, 100, "CamAngle %f\r\n", ACameras[CamID][CamAngle]); fwrite(PFile, LineForFile); // And save it to the file format(LineForFile, 100, "CamSpeed %i\r\n", ACameras[CamID][CamSpeed]); fwrite(PFile, LineForFile); // And save it to the file fwrite(PFile, "[/Camera]\r\n"); // Save the end of this camera fwrite(PFile, "\r\n"); // Save an empty line to split the camera's up a bit (for readability) } } fclose(PFile); // Close the file } // This function creates a speedcamera (store data and create the objects) SetupSpeedCamera(CamID, Float:x, Float:y, Float:z, Float:rot, MaxSpeed) { // Store all the given values ACameras[CamID][CamX] = x; ACameras[CamID][CamY] = y; ACameras[CamID][CamZ] = z; ACameras[CamID][CamAngle] = rot; ACameras[CamID][CamSpeed] = MaxSpeed; // Create both camera objects and store their reference ACameras[CamID][CamObj1] = CreateDynamicObject(18880, x, y, z, 0.0, 0.0, rot); ACameras[CamID][CamObj2] = CreateDynamicObject(18880, x, y, z, 0.0, 0.0, rot + 180.0); // Update the draw distance of each camera to 300m, otherwise they could be invisible until you're standing right next to them // By default, dynamic objects have a draw distance of 0m, meaning they're only visible when you're very close to them Streamer_SetFloatData(STREAMER_TYPE_OBJECT, ACameras[CamID][CamObj1], E_STREAMER_DRAW_DISTANCE, 300.0); Streamer_SetFloatData(STREAMER_TYPE_OBJECT, ACameras[CamID][CamObj2], E_STREAMER_DRAW_DISTANCE, 300.0); } // ****************************************************************************************************************************** // Support functions // ****************************************************************************************************************************** // This function is copied from the include-file "dutils.inc" stock StripNewLine(string[]) { new len = strlen(string); // Get the length of the given string if (string[0] == 0) return ; // If the given string is empty, exit the function if ((string[len - 1] == '\n') || (string[len - 1] == '\r')) // If the string ends with \n or \r { string[len - 1] = 0; // Replace the \n or \r with a 0 character if (string[0]==0) return ; // If the string became empty, exit the function if ((string[len - 2] == '\n') || (string[len - 2] == '\r')) // Check again if the string ends with \n or \r string[len - 2] = 0; // Replace the \n or \r again with a 0 character } } // ****************************************************************************************************************************** // Special functions that try to access external public functions to retreive data from another script // ****************************************************************************************************************************** // This function is used to get the player's money INT_GetPlayerMoney(playerid) { // Setup local variables new Money; // Try to call the external function to get the player's money (used to get the serversided money for this player) Money = CallRemoteFunction("Admin_GetPlayerMoney", "i", playerid); // The external function returned "0" (as the player doesn't have any money yet), or the function is not used in another script if (Money == 0) return GetPlayerMoney(playerid); // Return the normal money of the player else return Money; // Return the money that was returned by the external function } // This function is used to set the player's money INT_GivePlayerMoney(playerid, Money) { // Setup local variables new Success; // Try to call the external function to get the player's money (used to get the serversided money for this player) Success = CallRemoteFunction("Admin_GivePlayerMoney", "ii", playerid, Money); // The external function returned "0" as the function is not used in another script if (Success == 0) GivePlayerMoney(playerid, Money); // Use the normal money (client-sided money) } // This function checks if the admin-level of a player is sufficient INT_CheckPlayerAdminLevel(playerid, AdminLevel) { // Setup local variables new Level; // Check if the player is an RCON admin if (IsPlayerAdmin(playerid)) return 1; // Return 1 to indicate this player has a sufficient admin-level to use a command // If the player is not an RCON admin, try to get his admin-level from an external script using a remote function Level = CallRemoteFunction("Admin_GetPlayerAdminLevel", "i", playerid); // Check if the player has a sufficient admin-level if (Level >= AdminLevel) return 1; // Return 1 to indicate this player has a sufficient admin-level else return 0; // Return 0 to indicate this player has an insufficient admin-level } // This function checks if the player has logged in properly by entering his password INT_IsPlayerLoggedIn(playerid) { // Setup local variables new LoggedIn; // Try to determine if the player logged in properly by entering his password in another script LoggedIn = CallRemoteFunction("Admin_IsPlayerLoggedIn", "i", playerid); // Check if the player has logged in properly switch (LoggedIn) { case 0: return 1; // No admin script present that holds the LoggedIn status of a player, so allow a command to be used case 1: return 1; // The player logged in properly by entering his password, allow commands to be used case -1: return 0; // There is an admin script present, but the player hasn't entered his password yet, so block all commands // This prevents executing the commands using F6 during login with an admin-account before entering a password } // In any other case, block all commands return 0; } // ****************************************************************************************************************************** // External functions to be used from within other filterscripts or gamemode (these aren't called anywhere inside this script) // These functions can be called from other filterscripts or the gamemode to get data from the speedometer filterscript // ****************************************************************************************************************************** // This function can be used to get the fuel-status from the given vehicle forward Speedo_GetVehicleFuel(vehicleid); public Speedo_GetVehicleFuel(vehicleid) { return AVehicleData[vehicleid][Fuel]; } // This function can be used to set the fuel-status for the given vehicle forward Speedo_SetVehicleFuel(vehicleid, fuel); public Speedo_SetVehicleFuel(vehicleid, fuel) { // If a fuel-value of -1 is used, this will refuel the vehicle to maximum fuel if (fuel == -1) { AVehicleData[vehicleid][Fuel] = MaxFuel; // Set fuel to maximum return 1; // Return 1 (this can be used in the other script to check if the function was called successfully) } // Fuel cannot be negative (other negative values are ignored) if (fuel >= 0) { // Check if the fuel is within normal limits if (fuel > MaxFuel) AVehicleData[vehicleid][Fuel] = MaxFuel; // If a higher value was given than allowed (higher than MaxFuel), set fuel to maximum else AVehicleData[vehicleid][Fuel] = fuel; // Set the fuel to the given value } else return -1; // Return -1 (this can be used in the other script to check if the function was called successfully, // but the fuel-value was not acceptable) // Return 1 (this can be used in the other script to check if the function was called successfully) return 1; } // This function can be used to get the player's speed (returns 0 if the player is not inside a vehicle) forward Speedo_GetPlayerSpeed(playerid); public Speedo_GetPlayerSpeed(playerid) { return APlayerData[playerid][PlayerSpeed]; } // ****************************************************************************************************************************** // Functions that need to be placed in the gamemode or filterscript which holds the playerdata // Only needed when the server uses server-sided money, otherwise the normal money is used // ****************************************************************************************************************************** /* // This function is used to get the player's money forward Admin_GetPlayerMoney(playerid); public Admin_GetPlayerMoney(playerid) { return APlayerData[playerid][PlayerMoney]; } // This function is used to get the player's money forward Admin_GivePlayerMoney(playerid, Money); public Admin_GivePlayerMoney(playerid, Money) { // Add the given money to the player's account APlayerData[playerid][PlayerMoney] = APlayerData[playerid][PlayerMoney] + Money; // Return that the function had success (another script holds the player's money on the server-side) return 1; } // This function is used to get the player's admin-level forward Admin_GetPlayerAdminLevel(playerid); public Admin_GetPlayerAdminLevel(playerid) { return APlayerData[playerid][AdminLevel]; } // This function is used to determine if the player has logged in (he succesfully entered his password) forward Admin_IsPlayerLoggedIn(playerid); public Admin_IsPlayerLoggedIn(playerid) { if (APlayerData[playerid][LoggedIn] == true) return 1; // The player has logged in succesfully else return -1; // The player hasn't logged in (yet) } */ GetVehicleSpeed(vehicleid) { new Float:Vx, Float:Vy, Float:Vz; GetVehicleVelocity(vehicleid, Vx, Vy, Vz); new Float:rtn; rtn = floatsqroot(floatpower(Vx*100,2) + floatpower(Vy*100,2)); rtn = floatsqroot(floatpower(rtn,2) + floatpower(Vz*100,2)); return floatround(rtn); } DistanceFlat(Float:ax, Float:ay, Float:bx,Float:by, &Float:distance) { distance = floatsqroot(floatpower(bx-ax,2)+floatpower(by-ay,2)); return floatround(distance); } public CruiseControl(playerid) { new vid = GetPlayerVehicleID(playerid); new Float:x, Float:y, Float:z; GetVehicleVelocity(vid, x, y, z); new keys, ud, lr; GetPlayerKeys(playerid, keys, ud, lr); new Float:angle, Float:heading, Float:speed; GetVehicleZAngle(vid, angle); GetVehicleHeadingAngle(vid, heading); DistanceFlat(0, 0, x, y, speed); if (APlayerData[playerid][CruiseControlState] == 0 || PlayerCruiseSpeed[playerid] == 0.00 || //If player released LCTRL or CruiseSpeed got cancelled by other means (spacebar press) GetPlayerState(playerid) != PLAYER_STATE_DRIVER || (speed < 0.7 * PlayerCruiseSpeed[playerid]) || //if player slowed down too much z > 1 || //if car is going upwards too fast (floatabs(angle - heading) > 50 && floatabs(angle - heading) < 310))//if vehicle goes sideways { //Cruise control will turn off: PlayerCruiseSpeed[playerid] = 0.00; APlayerData[playerid][CruiseControlState] = 0; return false; } GetVehicleZAngle(vid, PlayerHeadingAngle[playerid]); GetXYVelocity(vid, x, y, PlayerCruiseSpeed[playerid]); SetVehicleVelocity(vid, x, y, z); return SetTimerEx("CruiseControl", 500, false, "d", playerid); } GetXYVelocity(vehicleid, &Float:x, &Float:y, Float:speed) { new Float:a; x = 0.0; y = 0.0; GetVehicleZAngle(vehicleid, a); x += (speed * floatsin(-a, degrees)); y += (speed * floatcos(-a, degrees)); } GetAngleToXY(Float:X, Float:Y, Float:CurrentX, Float:CurrentY, &Float:Angle) { Angle = atan2(Y-CurrentY, X-CurrentX); Angle = floatsub(Angle, 90.0); if(Angle < 0.0) Angle = floatadd(Angle, 360.0); } GetVehicleHeadingAngle(vehicleid, &Float:a) { new Float:x, Float:y, Float:z; GetVehicleVelocity(vehicleid, x, y, z); GetAngleToXY(x, y, 0, 0, a); }