sfcnr/gamemodes/irresistible/cnr/features/spikestrips.pwn

218 lines
6.7 KiB
Plaintext
Raw Normal View History

/*
* Irresistible Gaming (c) 2018
* Developed by Lorenc Pekaj
* Module: cnr\features\spikestrips.pwn
* Purpose: spike strip system for police
*/
/* ** Includes ** */
#include < YSI\y_hooks >
/* ** Definitions ** */
#define MAX_SPIKESTRIPS ( 32 )
/* ** Variables ** */
enum E_SPIKE_STRIP_DATA
{
E_OBJECT_ID, Text3D: E_LABEL, E_SPHERE,
E_CREATOR,
Float: E_X, Float: E_Y, Float: E_Z
};
static stock
g_spikestripData [ MAX_SPIKESTRIPS ] [ E_SPIKE_STRIP_DATA ],
Iterator: spikestrips < MAX_SPIKESTRIPS >
;
/* ** Hooks ** */
hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) {
if ( PRESSED( KEY_FIRE ) && IsPlayerInAnyVehicle( playerid ) && GetPlayerClass( playerid ) == CLASS_POLICE && p_inFBI{ playerid } ) {
return cmd_setspike( playerid, "" ), 1;
}
return 1;
}
hook OnPlayerDisconnect( playerid, reason ) {
ClearPlayerSpikeStrips( playerid, .distance_check = false );
return 1;
}
hook OnPlayerUpdateEx( playerid ) {
if ( GetPlayerClass( playerid ) == CLASS_POLICE ) {
ClearPlayerSpikeStrips( playerid );
}
return 1;
}
hook OnPlayerEnterDynArea( playerid, areaid ) {
new vehicleid = GetPlayerVehicleID( playerid );
new player_state = GetPlayerState( playerid );
if ( player_state == PLAYER_STATE_DRIVER && vehicleid != 0 )
{
foreach ( new i : spikestrips ) if ( g_spikestripData[ i ] [ E_SPHERE ] == areaid ) {
GetVehicleDamageStatus( vehicleid, panels, doors, lights, tires );
UpdateVehicleDamageStatus( vehicleid, panels, doors, lights, ( tires = encode_tires( 1, 1, 1, 1 ) ) );
destroySpikeStrip( i );
break;
}
}
return 1;
}
/* ** Commands ** */
CMD:dssall( playerid, params[ ] )
{
new removed = 0;
new is_admin = GetPlayerAdminLevel( playerid );
if ( ! p_inFBI{ playerid } && ! is_admin )
return SendError( playerid, "You are not in the FBI." );
foreach ( new handle : spikestrips )
{
if ( ! is_admin && g_spikestripData[ handle ] [ E_CREATOR ] != playerid )
continue;
new
cur = handle;
destroySpikeStrip( handle, .remove_iter = false );
Iter_SafeRemove( spikestrips, cur, handle );
removed ++;
}
if ( removed ) {
return SendServerMessage( playerid, "You have removed all your spike strips." );
} else {
return SendError( playerid, "There are no spike strips to remove by you." );
}
}
CMD:dss( playerid, params[ ] )
{
new
rbID
;
if ( !p_inFBI{ playerid } ) return SendError( playerid, "You are not in the FBI." );
else if ( sscanf( params, "d", rbID ) ) return SendUsage( playerid, "/dss [SPIKE_STRIP_ID]" );
else if ( rbID < 0 || rbID >= MAX_SPIKESTRIPS ) return SendError( playerid, "Invalid Spike Strip ID." );
else if ( !Iter_Contains( spikestrips, rbID ) ) return SendError( playerid, "Invalid Spike Strip ID." );
else if ( g_spikestripData[ rbID ] [ E_CREATOR ] != playerid ) return SendError( playerid, "You have not created this spike strip." );
else
{
destroySpikeStrip( rbID );
SendServerMessage( playerid, "You have succesfully destroyed a spike strip." );
}
return 1;
}
CMD:spike( playerid, params[ ] ) return cmd_setspike( playerid, params );
CMD:setspike( playerid, params[ ] )
{
if ( GetPlayerInterior( playerid ) != 0 || GetPlayerVirtualWorld( playerid ) != 0 ) return SendError( playerid, "You cannot place spike strips inside buildings." );
else if ( IsPlayerKidnapped( playerid ) ) return SendError( playerid, "You are kidnapped, you cannot do this." );
else if ( IsPlayerJailed( playerid ) ) return SendError( playerid, "You are jailed, you cannot do this." );
else if ( IsPlayerTied( playerid ) ) return SendError( playerid, "You are tied, you cannot do this." );
else if ( IsPlayerInWater( playerid ) ) return SendError( playerid, "You cannot use this command since you're in water." );
else if ( !p_inFBI{ playerid } ) return SendError( playerid, "You are not in the FBI." );
else
{
new
Float: X, Float: Y, Float: Z, Float: Angle;
if ( !IsPlayerInAnyVehicle( playerid ) )
{
GetXYInFrontOfPlayer( playerid, X, Y, Z, 2.0 );
GetPlayerFacingAngle( playerid, Angle );
}
else
{
new
iVehicle = GetPlayerVehicleID( playerid ),
iModel = GetVehicleModel( iVehicle )
;
if ( IsBoatVehicle( iModel ) || IsAirVehicle( iModel ) )
return SendError( playerid, "You cannot place a spike strip in this type of vehicle." );
GetVehiclePos( iVehicle, X, Y, Z );
GetVehicleZAngle( iVehicle, Angle );
X -= ( 4.1 * floatsin( -Angle, degrees ) );
Y -= ( 4.1 * floatcos( -Angle, degrees ) );
}
if ( CreateSpikeStrip( playerid, X, Y, Z + 0.15, Angle ) != -1 )
SendServerMessage( playerid, "You have succesfully created a spike strip." );
else
SendError( playerid, "Failed to place a spike strip due to a unexpected error." );
}
return 1;
}
/* ** Functions ** */
stock CreateSpikeStrip( playerid, Float: X, Float: Y, Float: Z, Float: Angle )
{
new
bVehicle = IsPlayerInAnyVehicle( playerid ),
i = Iter_Free( spikestrips )
;
if ( i != ITER_NONE )
{
DestroyDynamicArea ( g_spikestripData[ i ] [ E_SPHERE ] );
DestroyDynamicObject ( g_spikestripData[ i ] [ E_OBJECT_ID ] );
DestroyDynamic3DTextLabel ( g_spikestripData[ i ] [ E_LABEL ] );
g_spikestripData[ i ] [ E_CREATOR ] = playerid;
g_spikestripData[ i ] [ E_X ] = X;
g_spikestripData[ i ] [ E_Y ] = Y;
g_spikestripData[ i ] [ E_Z ] = Z;
g_spikestripData[ i ] [ E_LABEL ] = CreateDynamic3DTextLabel( sprintf( "Spike Strip(%d)\n"COL_GREY"Placed by %s!", i, ReturnPlayerName( playerid ) ), COLOR_GOLD, X, Y, Z, 20.0 );
g_spikestripData[ i ] [ E_OBJECT_ID ] = CreateDynamicObject( 2899, X, Y, Z - ( bVehicle ? 0.6 : 0.9 ), 0, 0, Angle - 90.0);
g_spikestripData[ i ] [ E_SPHERE ] = CreateDynamicCircle( X, Y, 4.0 );
Streamer_Update( playerid );
Iter_Add( spikestrips, i );
}
return i;
}
stock destroySpikeStrip( i, bool: remove_iter = true )
{
if ( i == -1 )
return 0;
DestroyDynamicArea ( g_spikestripData[ i ] [ E_SPHERE ] );
DestroyDynamicObject ( g_spikestripData[ i ] [ E_OBJECT_ID ] );
DestroyDynamic3DTextLabel ( g_spikestripData[ i ] [ E_LABEL ] );
g_spikestripData[ i ] [ E_SPHERE ] = 0xFFFF;
g_spikestripData[ i ] [ E_OBJECT_ID ] = INVALID_OBJECT_ID;
g_spikestripData[ i ] [ E_LABEL ] = Text3D: 0xFFFF;
if ( remove_iter ) Iter_Remove( spikestrips, i );
return 1;
}
stock ClearPlayerSpikeStrips( playerid, bool: distance_check = true )
{
foreach ( new handle : spikestrips ) if ( g_spikestripData[ handle ] [ E_CREATOR ] == playerid )
{
if ( distance_check && GetPlayerDistanceFromPoint( playerid, g_spikestripData[ handle ] [ E_X ], g_spikestripData[ handle ] [ E_Y ], g_spikestripData[ handle ] [ E_Z ] ) < 75.0 ) {
continue;
}
new
cur = handle;
destroySpikeStrip( handle, .remove_iter = false );
Iter_SafeRemove( spikestrips, cur, handle );
}
return 1;
}