19.03.2012, 22:04
Creating a "Strike" ability;
I'm aware this may not be the most efficient way to do things, but it works. For the purpose of this tutorial, I allow users to use the Strike ability against tanks only. Soo, let's get started.
Definitions
I know I really haven't explained anything, but this is why it's in the snippets thread, rather than a tutorial.
I'm aware this may not be the most efficient way to do things, but it works. For the purpose of this tutorial, I allow users to use the Strike ability against tanks only. Soo, let's get started.
Definitions
pawn Код:
#define MAX_TANKS 10
#define STRIKE_COOLDOWN 1 //I've defined this as one minute, however, you can change this as needed.
#define HOLDING(%0) \
((newkeys & (%0)) == (%0))
pawn Код:
new
StrikeCooldown[ MAX_PLAYERS ];
new
TanksSpawned = 0,
Tank[ MAX_TANKS ];
pawn Код:
//Tanks
Tank[ 0 ] = AddStaticVehicle( 432, 235.2255,17.2768,2.4297,143.3092, 3, 3 );
Tank[ 1 ] = AddStaticVehicle( 432, 212.7084,-21.6392,1.4297,94.7918, 3, 3 );
pawn Код:
public OnPlayerDisconnect( playerid, reason )
{
if( GetPVarInt( playerid, "ExpTank" ) == 1)
{
KillTimer( StrikeCooldown[ playerid ] );
}
return true;
}
pawn Код:
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
if( HOLDING( KEY_AIM ) )
{
if( GetPlayerWeapon( playerid ) == 43 )
{
new
Float: TankLoc[ 3 ];
for( new tk; tk < MAX_TANKS; tk ++ )
{
GetVehiclePos( Tank[ tk ], TankLoc[ 0 ], TankLoc[ 1 ], TankLoc[ 2 ] );
if( IsPlayerAimingAt( playerid, TankLoc[ 0 ], TankLoc[ 1 ], TankLoc[ 2 ], 3.0 ) )
{
if( GetPVarInt( playerid, "ExpTank" ) == 0 )
{
SetTimerEx( "ExplodeThatBitch", 5000, false, "ii", tk, playerid );
SendClientMessage( playerid, c_ORANGE, "Strike requested! Continue aiming at the Tank!" );
}
else return SendClientMessage( playerid, c_ORANGE, "You've recently called in an airstrike! Please wait 5 minutes." );
}
}
}
}
return true;
}
forward ExplodeThatBitch( TankID, playerid );
public ExplodeThatBitch( TankID, playerid )
{
new
Float: TankLoc[ 3 ],
String[ 128 ],
p_Name[ MAX_PLAYER_NAME ];
GetPlayerName( playerid, p_Name, sizeof( p_Name ) );
for( new tk; tk < MAX_TANKS; tk ++ )
{
GetVehiclePos( Tank[ tk ], TankLoc[ 0 ], TankLoc[ 1 ], TankLoc[ 2 ] );
if( IsPlayerAimingAt( playerid, TankLoc[ 0 ], TankLoc[ 1 ], TankLoc[ 2 ], 3.0 ) )
{
CreateExplosion( TankLoc[ 0 ], TankLoc[ 1 ], TankLoc[ 2 ], 0, 10.0 );
format( String, sizeof( String ), "%s has called in a Strike!", p_Name );
SendClientMessageToAll( c_ORANGE, String );
SetPVarInt( playerid, "ExpTank", 1 );
StrikeCooldown[ playerid ] = SetTimerEx( "ResetCooldown", 60000*STRIKE_COOLDOWN, false, "i", playerid );
return true;
}
else
{
SendClientMessage( playerid, c_ORANGE, "Target not found!" );
SetPVarInt( playerid, "ExpTank", 0 );
return true;
}
}
return true;
}
forward ResetCooldown( playerid );
public ResetCooldown( playerid )
{
SetPVarInt( playerid, "ExpTank", 0 );
SendClientMessage( playerid, c_ORANGE, "You may now use your Strike capabilities!" );
return true;
}
pawn Код:
Float:DistanceCameraTargetToLocation(Float:CamX, Float:CamY, Float:CamZ, Float:ObjX, Float:ObjY, Float:ObjZ, Float:FrX, Float:FrY, Float:FrZ) {
new Float:TGTDistance;
TGTDistance = floatsqroot((CamX - ObjX) * (CamX - ObjX) + (CamY - ObjY) * (CamY - ObjY) + (CamZ - ObjZ) * (CamZ - ObjZ));
new Float:tmpX, Float:tmpY, Float:tmpZ;
tmpX = FrX * TGTDistance + CamX;
tmpY = FrY * TGTDistance + CamY;
tmpZ = FrZ * TGTDistance + CamZ;
return floatsqroot((tmpX - ObjX) * (tmpX - ObjX) + (tmpY - ObjY) * (tmpY - ObjY) + (tmpZ - ObjZ) * (tmpZ - ObjZ));
}
stock IsPlayerAimingAt(playerid, Float:x, Float:y, Float:z, Float:radius)
{
new Float:cx,Float:cy,Float:cz,Float:fx,Float:fy,Float:fz;
GetPlayerCameraPos(playerid, cx, cy, cz);
GetPlayerCameraFrontVector(playerid, fx, fy, fz);
return (radius >= DistanceCameraTargetToLocation(cx, cy, cz, x, y, z, fx, fy, fz));
}
//These are NOT my functions, although I'm not positive where they came from..