/* * Irresistible Gaming (c) 2018 * Developed by Steven Howard * Module: cnr\features\minijobs\pilot.pwn * Purpose: pilot minijob - cargo pickup and transport to another airport. */ /* ** Includes ** */ #include < YSI\y_hooks > /* ** Definitions ** */ #define PILOT_BONUS ( 4000 ) #define INVALID_PILOT_ROUTE ( 0xFF ) /* ** Variables ** */ enum E_PILOT_DATA { E_NAME[ 32 ], Float: E_X, Float: E_Y, Float: E_Z, }; enum E_AIRPORT_DATA { E_NAME[ 32 ], Float: E_X, Float: E_Y, Float: E_Z, }; enum E_CARGO_DATA { E_NAME[ 24 ], E_RISK }; new g_DropOffLocations[ ] [ E_PILOT_DATA ] = { // SF { "SF City Hall", -2706.2783, 376.4467, 4.9684 }, { "Whetstone Farm", -1442.2671, -1492.7599, 101.7578 }, { "Militia Ship", -2396.2244, 1543.2428, 31.8594 }, // LV { "Greenglass College", 1087.6841, 1073.0309, 10.8382 }, { "LV Baseball Ground", 1355.2606, 2156.7888, 11.0156 }, { "The Visage", 1965.2771, 1915.5419, 130.9375}, { "Spinybed", 2400.8699, 2777.5608, 17.3643 }, // LS { "Santa Maria Beach", 369.9119, -2022.7925, 7.6719 }, { "Pershing Square", 1480.7731, -1638.8020, 14.1484 }, { "Glen Park", 1970.1884, -1201.0854, 25.6119 }, // Assorted { "Red County", 1929.0541, 170.9540, 37.2813 }, { "Blueberry Acres", -76.9925, 1.9632, 3.1172 }, { "Bayside", -2465.4614, 2234.1575, 4.8042 } }, g_AirportLocations[ ] [ E_AIRPORT_DATA ] = { { "San Fierro Airport", -1233.8186, -128.0793, 14.1484 }, { "San Fierro Airport", -1340.1185, 152.5395, 14.1484 }, { "Las Venturas Airport", 1477.1909, 1532.9949, 10.8125 }, { "Las Venturas Airport", 1620.1753, 1531.3868, 10.8011 }, { "Los Santos Airport", 1797.7118, -2493.8835, 13.5547 }, { "Los Santos Airport", 1921.8281, -2252.9990, 13.5469 }, { "Abandoned Airstrip", 175.2288, 2504.6611, 16.4844 }, { "Abandoned Airstrip", 266.3593, 2535.8496, 16.8125 } }, g_CargoData[ ][ E_CARGO_DATA ] = { // HARDER CARGO { "Weapons", RISK_FACTOR_HARD }, { "Weed", RISK_FACTOR_HARD }, { "Cocaine", RISK_FACTOR_HARD }, { "Methamphetamine", RISK_FACTOR_HARD }, { "Gold", RISK_FACTOR_HARD }, { "Diamonds", RISK_FACTOR_HARD }, // EASY CARGO { "Wheat", RISK_FACTOR_EASY }, { "Clothes", RISK_FACTOR_EASY }, { "Drinks", RISK_FACTOR_EASY }, { "Soybeans", RISK_FACTOR_EASY }, { "Coffee", RISK_FACTOR_EASY }, { "Medical Supplies", RISK_FACTOR_EASY } }, //g_CargoName[ ][ 8 ] = { "Wheat", "Weed", "Meth", "Coke", "Weapons", "Clothes", "Drinks" }, bool: p_hasPilotJob [ MAX_PLAYERS char ], p_PilotMapIcon [ MAX_PLAYERS ] = { 0xFFFF, ... }, p_PilotCheckPoint [ MAX_PLAYERS ] = { 0xFFFF, ... }, p_PilotPositionTimer [ MAX_PLAYERS ] = { 0xFFFF, ... }, p_PilotCancelTimer [ MAX_PLAYERS ] = { 0xFFFF, ... }, p_PilotLoadTimer [ MAX_PLAYERS ] = { 0xFFFF, ... }, p_PilotCargo [ MAX_PLAYERS ], p_PilotDifficulty [ MAX_PLAYERS ], p_PilotVehicle [ MAX_PLAYERS ], p_PilotTimeElapsed [ MAX_PLAYERS ], Float: p_PilotDistance [ MAX_PLAYERS ], p_PilotRoute [ MAX_PLAYERS ] [ 2 char ] ; /* ** Hooks ** */ hook OnPlayerDisconnect( playerid, reason ) { StopPlayerPilotWork( playerid ); return 1; } #if defined AC_INCLUDED hook OnPlayerDeathEx( playerid, killerid, reason, Float: damage, bodypart ) #else hook OnPlayerDeath( playerid, killerid, reason ) #endif { StopPlayerPilotWork( playerid ); return 1; } hook OnPlayerUpdateEx( playerid ) { new player_vehicle = GetPlayerVehicleID( playerid ); if ( GetPlayerState( playerid ) == PLAYER_STATE_DRIVER && player_vehicle && p_hasPilotJob{ playerid } && p_PilotVehicle[ playerid ] != player_vehicle && p_PilotCancelTimer[ playerid ] == 0xFFFF ) { cancelPlayerPilotWork( playerid, player_vehicle, .ticks = 60 ); } return 1; } hook OnPlayerStateChange( playerid, newstate, oldstate ) { if ( newstate != PLAYER_STATE_DRIVER && oldstate == PLAYER_STATE_DRIVER && p_hasPilotJob{ playerid } ) { cancelPlayerPilotWork( playerid, GetPlayerVehicleID( playerid ), .ticks = 0 ); } else if ( newstate == PLAYER_STATE_DRIVER && oldstate != PLAYER_STATE_DRIVER && p_hasPilotJob{ playerid } ) { KillTimer( p_PilotCancelTimer[ playerid ] ); p_PilotCancelTimer[ playerid ] = 0xFFFF; } else if ( newstate == PLAYER_STATE_DRIVER && IsPlayerInAnyVehicle(playerid) && !p_hasPilotJob{ playerid }) { if ( Pilot_IsPlane( GetPlayerVehicleID( playerid ) ) ) { ShowPlayerHelpDialog( playerid, 3000, "You can begin a pilot job by typing ~g~~h~/pilot" ); } } return 1; } hook OnPlayerEnterDynRaceCP( playerid, checkpointid ) { if ( checkpointid == p_PilotCheckPoint[ playerid ] ) { DestroyDynamicMapIcon( p_PilotMapIcon[ playerid ] ); DestroyDynamicRaceCP ( p_PilotCheckPoint[ playerid ] ); KillTimer ( p_PilotPositionTimer[ playerid ] ); if ( p_PilotRoute[ playerid ] { 0 } != INVALID_PILOT_ROUTE ) { static aPlayer[ 1 ]; aPlayer[ 0 ] = playerid; p_PilotPositionTimer[ playerid ] = SetTimerEx( "OnPilotPositionUpdate", 750, false, "dd", playerid, p_PilotRoute[ playerid ] { 1 } ); PlayerTextDrawShow( playerid, p_TruckingTD[ playerid ] ); KillTimer( p_PilotLoadTimer[ playerid ] ); p_PilotLoadTimer [ playerid ] = 0xFFFF; p_PilotLoadTimer [ playerid ] = SetTimerEx( "OnPilotLoadCargo", 5000, false, "d", playerid ); TogglePlayerControllable(playerid, false); if ( p_PilotDifficulty[ playerid ] == RISK_FACTOR_HARD) GivePlayerWantedLevel( playerid, 6 ); ShowPlayerHelpDialog( playerid, 5000, "Please wait while your cargo is getting loaded into your vehicle!" ); p_PilotMapIcon [ playerid ] = CreateDynamicMapIconEx( g_DropOffLocations[ p_PilotRoute[ playerid ] { 1 } ] [ E_X ], g_DropOffLocations[ p_PilotRoute[ playerid ] { 1 } ] [ E_Y ], g_DropOffLocations[ p_PilotRoute[ playerid ] { 1 } ] [ E_Z ], 51, 0, MAPICON_GLOBAL, 6000.0, { -1 }, { -1 }, aPlayer ); p_PilotCheckPoint [ playerid ] = CreateDynamicRaceCP( 4, g_DropOffLocations[ p_PilotRoute[ playerid ] { 1 } ] [ E_X ], g_DropOffLocations[ p_PilotRoute[ playerid ] { 1 } ] [ E_Y ], g_DropOffLocations[ p_PilotRoute[ playerid ] { 1 } ] [ E_Z ] + 50.0, 15.0, 0.0, 0.0, 10.0, -1, -1, playerid ); return ( p_PilotRoute[ playerid ] { 0 } = INVALID_PILOT_ROUTE ), 1; } else if ( p_PilotRoute[ playerid ] { 1 } != INVALID_PILOT_ROUTE ) { new iCashEarned = floatround( p_PilotDistance[ playerid ] * ( p_PilotDifficulty[ playerid ] == RISK_FACTOR_EASY ? 1.0 : 2.0 ) + PILOT_BONUS ); GivePlayerScore( playerid, 1 + floatround( p_PilotDistance[ playerid ] / 1000.0 ) ); GivePlayerCash( playerid, iCashEarned ); ShowPlayerHelpDialog( playerid, 5000, "You have earned ~y~%s ~w~for exporting %s!", cash_format( iCashEarned ), g_CargoData[ p_PilotCargo[ playerid ] ][ E_NAME ] ); StopPlayerPilotWork( playerid ); return 1; } return 1; } return 1; } /* ** Functions ** */ stock getClosestPilotRoute( playerid, &Float: distance = FLOAT_INFINITY ) { new iCurrent = INVALID_PLAYER_ID, Float:fTmp; for( new i = 0; i < sizeof( g_AirportLocations ); i++ ) if ( 0.0 < ( fTmp = GetDistanceFromPlayerSquared( playerid, g_AirportLocations[ i ] [ E_X ], g_AirportLocations[ i ] [ E_Y ], g_AirportLocations[ i ] [ E_Z ] ) ) < distance ) distance = fTmp, iCurrent = i; return iCurrent; } stock getRandomCargo( iRisk ) { new aRandom[ sizeof( g_CargoData ) ], iRandom = -1 ; for ( new i = 0; i < sizeof ( g_CargoData ); i ++ ) { if ( g_CargoData[ i ][ E_RISK ] == iRisk ) { aRandom[ ++iRandom ] = i; } } return aRandom[ random( iRandom + 1 ) ]; } stock StopPlayerPilotWork( playerid ) { DestroyDynamicRaceCP ( p_PilotCheckPoint[ playerid ] ); DestroyDynamicMapIcon ( p_PilotMapIcon[ playerid ] ); KillTimer ( p_PilotCancelTimer[ playerid ] ); KillTimer ( p_PilotPositionTimer[ playerid ] ); p_PilotDifficulty [ playerid ] = -1; p_PilotDistance [ playerid ] = 0.0; p_hasPilotJob { playerid } = false; p_PilotCheckPoint [ playerid ] = 0xFFFF; p_PilotMapIcon [ playerid ] = 0xFFFF; p_PilotCancelTimer [ playerid ] = 0xFFFF; p_PilotPositionTimer [ playerid ] = 0xFFFF; p_PilotRoute [ playerid ] { 0 } = INVALID_PILOT_ROUTE; p_PilotRoute [ playerid ] { 1 } = INVALID_PILOT_ROUTE; p_PilotCargo [ playerid ] = -1; p_PilotVehicle [ playerid ] = INVALID_VEHICLE_ID; PlayerTextDrawHide( playerid, p_TruckingTD[ playerid ] ); } stock Pilot_IsPlane( vehicleid ) { new modelid = GetVehicleModel( vehicleid ); // skimmer, beagle, cropduster, nevada, andromada, dodo, -shamal- return modelid == 460 || modelid == 511 || modelid == 512 || modelid == 553 || modelid == 592 || modelid == 593; // || modelid == 519; } function OnPilotPositionUpdate( playerid, routeid ) { if ( !IsPlayerInAnyVehicle( playerid ) && !p_hasPilotJob{ playerid } && ( p_PilotRoute[ playerid ] { 0 } == 0 && p_PilotRoute[ playerid ] { 1 } == 0 ) ) { PlayerTextDrawHide( playerid, p_TruckingTD[ playerid ] ); return ( p_PilotPositionTimer[ playerid ] = 0xFFFF ); } new Float: fDistance = 0.0; if ( routeid == p_PilotRoute[ playerid ] { 0 }) { fDistance = GetPlayerDistanceFromPoint( playerid, g_AirportLocations[ routeid ] [ E_X ], g_AirportLocations[ routeid ] [ E_Y ], g_AirportLocations[ routeid ] [ E_Z ] ); PlayerTextDrawSetString( playerid, p_TruckingTD[ playerid ], sprintf( "~b~Location:~w~ %s~n~~b~Distance:~w~ %0.2fm", g_AirportLocations[ routeid ] [ E_NAME ], fDistance ) ); } else if ( routeid == p_PilotRoute[ playerid ] { 1 }) { fDistance = GetPlayerDistanceFromPoint( playerid, g_DropOffLocations[ routeid ] [ E_X ], g_DropOffLocations[ routeid ] [ E_Y ], g_DropOffLocations[ routeid ] [ E_Z ] ); PlayerTextDrawSetString( playerid, p_TruckingTD[ playerid ], sprintf( "~b~Location:~w~ %s~n~~b~Distance:~w~ %0.2fm", g_DropOffLocations[ routeid ] [ E_NAME ], fDistance ) ); } return ( p_PilotPositionTimer[ playerid ] = SetTimerEx( "OnPilotPositionUpdate", 750, false, "dd", playerid, routeid ) ); } function cancelPlayerPilotWork( playerid, vehicleid, ticks ) { if ( p_PilotVehicle[ playerid ] == vehicleid && ticks ) return KillTimer( p_PilotCancelTimer[ playerid ] ), p_PilotCancelTimer[ playerid ] = 0xFFFF; if ( ticks < 1 || !IsPlayerConnected( playerid ) || !IsPlayerSpawned( playerid ) || ! p_hasPilotJob{ playerid } ) { StopPlayerPilotWork( playerid ); return SendServerMessage( playerid, "Your pilot mission has been stopped." ); } else { ShowPlayerHelpDialog( playerid, 1000, "You have %d seconds to get back inside the plane you were using.", ticks - 1 ); p_PilotCancelTimer[ playerid ] = SetTimerEx( "cancelPlayerPilotWork", 980, false, "ddd", playerid, vehicleid, ticks - 1 ); } return 1; } function OnPilotLoadCargo( playerid ) { if (!IsPlayerConnected(playerid)) return 0; if ( !IsPlayerInAnyVehicle( playerid ) ) return 0; TogglePlayerControllable(playerid, true); ShowPlayerHelpDialog( playerid, 7500, "Great! The cargo full of %s has been loaded, deliver it to the drop off location on your radar!", g_CargoData[ p_PilotCargo[ playerid ] ][ E_NAME ]); return KillTimer( p_PilotLoadTimer[ playerid ] ), p_PilotLoadTimer[ playerid ] = 0xFFFF, 1; } /* ** Commands ** */ CMD:pilot( playerid, params[ ] ) { new szDifficulty[ 7 ], iVehicle = GetPlayerVehicleID( playerid ); if ( p_Class[ playerid ] != CLASS_CIVILIAN ) return SendError( playerid, "You must be an ordinary civilian to use this command." ); else if ( GetPlayerState( playerid ) != PLAYER_STATE_DRIVER ) return SendError( playerid, "You must be a driver of a vehicle to work." ); else if ( !iVehicle ) return SendError( playerid, "You are not in any vehicle." ); else if ( sscanf( params, "S(normal)[7]", szDifficulty ) ) return SendUsage( playerid, "/pilot [NORMAL/HARDER/STOP]" ); else if ( strmatch( szDifficulty, "stop" )) { StopPlayerPilotWork( playerid ); return SendServerMessage( playerid, "Your pilot mission has been stopped." ); } else if ( strmatch( szDifficulty, "normal" ) || strmatch( szDifficulty, "harder" )) { if ( Pilot_IsPlane( iVehicle )) { if ( ! p_hasPilotJob{ playerid } ) { if ( p_WorkCooldown[ playerid ] > g_iTime ) return SendError( playerid, "You must wait %d seconds before working again.", p_WorkCooldown[ playerid ] - g_iTime ); static aPlayer[ 1 ]; aPlayer[ 0 ] = playerid; DestroyDynamicMapIcon( p_PilotMapIcon[ playerid ] ); p_hasPilotJob { playerid } = true; p_WorkCooldown [ playerid ] = g_iTime + 60; p_PilotVehicle [ playerid ] = GetPlayerVehicleID( playerid ); p_PilotDifficulty [ playerid ] = ( strmatch( szDifficulty, "harder" ) ? RISK_FACTOR_HARD : RISK_FACTOR_EASY ); p_PilotCargo [ playerid ] = getRandomCargo( strmatch( szDifficulty, "harder" ) ? RISK_FACTOR_HARD : RISK_FACTOR_EASY ); p_PilotRoute [ playerid ] { 0 } = random ( sizeof ( g_AirportLocations ) ); p_PilotRoute [ playerid ] { 1 } = random ( sizeof( g_DropOffLocations ) ); p_PilotTimeElapsed [ playerid ] = g_iTime; p_PilotDistance [ playerid ] = GetDistanceBetweenPoints( g_AirportLocations[ p_PilotRoute[ playerid ] { 0 } ] [ E_X ], g_AirportLocations[ p_PilotRoute[ playerid ] { 0 } ] [ E_Y ], g_AirportLocations[ p_PilotRoute[ playerid ] { 0 } ] [ E_Z ], g_DropOffLocations[ p_PilotRoute[ playerid ] { 1 } ] [ E_X ], g_DropOffLocations[ p_PilotRoute[ playerid ] { 1 } ] [ E_Y ], g_DropOffLocations[ p_PilotRoute[ playerid ] { 1 } ] [ E_Z ] ); p_PilotMapIcon [ playerid ] = CreateDynamicMapIconEx( g_AirportLocations[ p_PilotRoute[ playerid ] { 0 } ] [ E_X ], g_AirportLocations[ p_PilotRoute[ playerid ] { 0 } ] [ E_Y ], g_AirportLocations[ p_PilotRoute[ playerid ] { 0 } ] [ E_Z ], 51, 0, MAPICON_GLOBAL, 6000.0, { -1 }, { -1 }, aPlayer ); p_PilotCheckPoint [ playerid ] = CreateDynamicRaceCP( 0, g_AirportLocations[ p_PilotRoute[ playerid ] { 0 } ] [ E_X ], g_AirportLocations[ p_PilotRoute[ playerid ] { 0 } ] [ E_Y ], g_AirportLocations[ p_PilotRoute[ playerid ] { 0 } ] [ E_Z ], 0.0, 0.0, 0.0, 10.0, -1, -1, playerid ); p_PilotPositionTimer[ playerid ] = SetTimerEx( "OnPilotPositionUpdate", 750, false, "dd", playerid, p_PilotRoute[ playerid ] { 0 } ); PlayerTextDrawShow( playerid, p_TruckingTD[ playerid ] ); ShowPlayerHelpDialog( playerid, 7500, "A ~g~~h~truck blip~w~~h~ has been shown on your radar. Go to where the truck blip is to pickup your cargo full of %s.", g_CargoData[ p_PilotCargo[ playerid ] ][ E_NAME ] ); } else SendError( playerid, "You already have a pilot job started! Cancel it with "COL_GREY"/pilot stop"COL_WHITE"." ); } else SendError( playerid, "There are currently no jobs for this particular vehicle." ); } return 1; }