04.11.2013, 15:07
So this is bombing script of Mauzen. I just modded it according to my needs. But how the hell do i give kill to the player -_- The Pvar which came with it is buggy! It give kill to the last guy who did damage to the person died in explosion!
pawn Код:
#include <a_samp>
#include <mapandreas>
#define COLOR_RED 0xAA3333AA
#define COLOR_YELLOW 0xFFFF00AA
#define MAX_BOMBS 1 //Max bombs at once per player
#define UPDATE_TIME 100 //Collisioncheck updatetime in ms, increase it if your server is slow
#define KEY_DROP_BOMB KEY_HANDBRAKE
#define KEY_NEXT_BOMBTYPE KEY_ANALOG_DOWN
#define KEY_PREV_BOMBTYPE KEY_ANALOG_UP
#define USE_TEXTDRAWS 1 //See the SA-MP.com forum topic and the screenshots for info about this, or try 0, 1 and 2
#define FILTERSCRIPT
forward DropBomb(playerid);
forward BombTimer(playerid, num, Float:targetz);
forward DetonateBomb(playerid, num);
forward CreateSpecialExplosion(explosionid, num, playerid);
forward ReactivateBomb(playerid, bombnum);
forward CreateRadialExplosion(Float:x, Float:y, Float:z, round, max);
forward ReleaseBomb(playerid, bid);
forward OnBombExplode(playerid, num, Float:x, Float:y, Float:z);
forward ResetNearExp(playerid);
forward RemoveTextDraw(playerid);
forward ShowTextDraw(playerid, vehicleid, count);
// Free changeable stuff -------------
enum bombEnum {
bombName[32], //Name of the bomb (plural for correct grammar ;)
expID, //ExplosionID of the bomb (the same as in CreateExplosion)
Float:expRadius, //Explosion radius (the same as in CreateExplosion)
Float:accuracy, //Drop accuracy, higher is better (Height / this value = max x,y tolerance)
bombModel, //Object model of the bomb
bombModelRot, //Object model rotation of the bomb
expDelay, //Explosion delay after reaching the ground (ms)
reloadTime, //Reload time (ms)
dropAtOnce, //Number of bombs beeing dropped with one click
dropAtOnceDelay //Delay between the bombs beeing dropped at once (ms)
}
new gBombTypes[][bombEnum] = {
{"Normal bombs", 1, 2.8, 6.0, 1636, 270, 500, 150, 1, 0},
{"Fire bombs", 1, 4.0, 8.0, 1636, 270, 0, 200, 1, 0},
{"Big bombs", 7, 4.5, 10.0, 1636, 270, 0, 750, 1, 0},
{"Laser-guided Bombs", 6, 5.0, 25.0, 1636, 270, 0, 1500, 1, 0},
{"Heavy bombs", -1, 5.0, 15.0, 345, 270, 0, 10000, 1, 0}, //Negative Explosion IDs can be used for self-created explosions, for more info check CreateSpecialExplosion
{"Anti-Missile Flares", -2, 150.0, 35.0, 354, 0, 5000, 10000, 1, 0}, //Only has an effect together with my (act. unreleased) missile FS
{"Nuclear Bombs", -3, 4.0, 10.0, 3790, 270, 0, 10000, 1, 0},
{"Clusterbombs", 6, 2.5, 3.0, 1636, 270, 0, 15000, 12, 0},
{"Carpetbombs", 1, 2.5, 5.5, 1636, 270, 0, 15000, 12, 100}
};
//{Vehicle model ID, bombtype 1 allowed, bombtype 2 allowed, ..., bombtype n allowed}
//needs to be expanded, when more bombtypes are added
new gVehicleBombs[][] = {
{476, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0} //Rustler
};
new Float:gBombSpeed = 20.0; //Bomb-falling speed (constant, non-accelerated)
// Global variables ---------------
new bombid[MAX_PLAYERS][MAX_BOMBS];
new bombtime[MAX_PLAYERS][MAX_BOMBS];
new bombcount[MAX_PLAYERS];
new boti[MAX_PLAYERS][MAX_BOMBS];
new bfree[MAX_PLAYERS];
new btype[MAX_PLAYERS][MAX_BOMBS];
new bptype[MAX_PLAYERS] = 0;
new vmid[MAX_PLAYERS] = -1;
#if(USE_TEXTDRAWS)
new Text:bombtext[MAX_PLAYERS];
new removetimer[MAX_PLAYERS];
#endif
// ----------------------------------
#if defined FILTERSCRIPT
public OnFilterScriptInit()
{
print("\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
print("X Bombing filterscript V0.97 X");
print("XxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxX");
new size = sizeof gBombTypes;
if(size != (sizeof gVehicleBombs[] - 1)) print("WARNING: NUMBER OF BOMBS DOES NOT MATCH THE VEHICLECONFIGERATIONS");
MapAndreas_Init(MAP_ANDREAS_MODE_FULL); //This FS requires the MapAndres-plugin
return 1;
}
public OnFilterScriptExit()
{
return 1;
}
#endif
public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger)
{
vmid[playerid] = GetVehicleStatID(GetVehicleModel(vehicleid));
if(vmid[playerid] > -1) {
bptype[playerid] = 3;
#if(USE_TEXTDRAWS)
TextDrawHideForPlayer(playerid, bombtext[playerid]);
TextDrawDestroy(bombtext[playerid]);
KillTimer(removetimer[playerid]);
SetTimerEx("ShowTextDraw", 500, 0, "iii", playerid, vehicleid, 0);
#endif
}
return 1;
}
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
if(IsPlayerInAnyVehicle(playerid) && (vmid[playerid] > -1)) {
new old[MAX_PLAYERS];
if((newkeys & KEY_NEXT_BOMBTYPE) && !(oldkeys & KEY_NEXT_BOMBTYPE)) {
old[playerid] = bptype[playerid];
bptype[playerid] ++;
if(bptype[playerid] >= sizeof gBombTypes) bptype[playerid] = old[playerid];
while(gVehicleBombs[vmid[playerid]][bptype[playerid] + 1] <= 0) {
bptype[playerid] ++;
if(bptype[playerid] >= sizeof gBombTypes) {
bptype[playerid] = old[playerid];
return 1;
}
}
#if(USE_TEXTDRAWS)
UpdateTextDraw(playerid);
#else
new str[40];
format(str, 40, "You have armed %s", gBombTypes[bptype[playerid]][bombName]);
SendClientMessage(playerid, COLOR_YELLOW, str);
#endif
}
if((newkeys & KEY_PREV_BOMBTYPE) && !(oldkeys & KEY_PREV_BOMBTYPE)) {
old[playerid] = bptype[playerid];
bptype[playerid] --;
if(bptype[playerid] < 0) bptype[playerid] = old[playerid];
while(gVehicleBombs[vmid[playerid]][bptype[playerid] + 1] <= 0) {
bptype[playerid] --;
if(bptype[playerid] < 0) {
bptype[playerid] = old[playerid];
return 1;
}
}
#if(USE_TEXTDRAWS)
UpdateTextDraw(playerid);
#else
new str[40];
format(str, 40, "You have armed %s", gBombTypes[bptype[playerid]][bombName]);
SendClientMessage(playerid, COLOR_YELLOW, str);
#endif
}
if((newkeys & KEY_DROP_BOMB) && !(oldkeys & KEY_DROP_BOMB)) {
if(IsPlayerAllowedToDropBomb(playerid)) DropBomb(playerid);
else SendClientMessage(playerid, COLOR_RED, "You can't use that bomb now!");
#if(USE_TEXTDRAWS)
UpdateTextDraw(playerid);
#endif
}
}
return 1;
}
// -----------------------------------------------------------------------------
stock Float:floatrandom(Float:max)
{
new Float:rand;
max = max * 100000;
rand = floatdiv(float(random(floatround(max))), 100000.0);
return rand;
}
stock Float:GetPlayerDistanceToPoint(playerid, Float:x, Float:y, Float:z)
{
new Float:px;
new Float:py;
new Float:pz;
if(!IsPlayerInAnyVehicle(playerid)) GetPlayerPos(playerid, px, py, pz);
else GetVehiclePos(GetPlayerVehicleID(playerid), px, py, pz);
return floatsqroot( floatadd( floatadd( floatpower(floatsub(x, px), 2), floatpower(floatsub(y, py), 2) ), floatpower(floatsub(z, pz), 2) ) );
}
stock Float:GetGroundZ(Float:x, Float:y)
{
new Float:gz;
MapAndreas_FindZ_For2DCoord(x, y, gz);
return gz;
}
stock GetVehicleStatID(modelid)
{
for(new i = 0; i < sizeof gVehicleBombs; i ++)
if(gVehicleBombs[i][0] == modelid)
return i;
return -1;
}
// -----------------------------------------------------------------------------
public DropBomb(playerid)
{
if(bptype[playerid] != 0) {
if(bfree[playerid] == 0) {
if(bombcount[playerid] < MAX_BOMBS) {
bfree[playerid] = 1;
new bid = bptype[playerid];
for(new drops = 0; drops < gBombTypes[bptype[playerid]][dropAtOnce] && bombcount[playerid] < MAX_BOMBS; drops ++) {
if(gBombTypes[bid][dropAtOnceDelay] > 0) SetTimerEx("ReleaseBomb", gBombTypes[bid][dropAtOnceDelay] * drops, 0, "ii", playerid, bid);
else ReleaseBomb(playerid, bid);
}
SetTimerEx("ReactivateBomb", gBombTypes[bptype[playerid]][reloadTime], 0, "ii", playerid, bptype[playerid]);
} else SendClientMessage(playerid, COLOR_RED, "Please wait while we are reloading the bomb!");
} else {
#if(!USE_TEXTDRAWS)
SendClientMessage(playerid, COLOR_RED, "The bomb needs to be loaded! Wait a moment...");
#endif
}
}
}
public ReleaseBomb(playerid, bid)
{
bombcount[playerid] ++;
new Float:x, Float:y, Float:z, Float:tz;
new sel = -1;
new Float:tolerancex, Float:tolerancey;
for(new i = 0; i < MAX_BOMBS; i++) {
if(bombid[playerid][i] <= 0) {
sel = i;
bombid[playerid][i] = 1;
break;
}
}
if(sel == -1) return;
btype[playerid][sel] = bid;
GetVehiclePos(GetPlayerVehicleID(playerid), x, y, z);
tz = floatdiv(z - GetGroundZ(x, y), gBombTypes[bid][accuracy]);
tolerancex = floatsub( floatrandom( tz ), floatdiv(tz, 2.0));
tolerancey = floatsub( floatrandom( tz ), floatdiv(tz, 2.0));
tz = GetGroundZ(x + tolerancex, y + tolerancey);
bombid[playerid][sel] = CreateObject(gBombTypes[bid][bombModel], x, y, z - 1, gBombTypes[bid][bombModelRot], 0, 0);
MoveObject(bombid[playerid][sel], x + tolerancex, y + tolerancey, tz - 1, gBombSpeed);
boti[playerid][sel] = 0;
bombtime[playerid][sel] = SetTimerEx("BombTimer", UPDATE_TIME, 1, "iif", playerid, sel, tz);
if(bptype[playerid] == 6) {
CallRemoteFunction("LaunchAntiRocketFlare", "iff", bombid[playerid][sel], gBombTypes[6][expRadius], gBombTypes[6][accuracy]);
}
}
public BombTimer(playerid, num, Float:targetz)
{
new Float:x;
new Float:y;
new Float:z;
GetObjectPos(bombid[playerid][num], x, y, z);
boti[playerid][num] += UPDATE_TIME;
for(new i = 0; i < MAX_PLAYERS; i ++) { //Check, if the bombs hits a player
if(IsPlayerConnected(i))
if(GetPlayerDistanceToPoint(i, x, y, z) < 7.5 && boti[playerid][num] >= 400) DetonateBomb(playerid, num);
}
if((floatsub(z, targetz) < 1)) { //bomb reached ground
if(gBombTypes[btype[playerid][num]][expDelay] > 0) {
SetTimerEx("DetonateBomb", gBombTypes[btype[playerid][num]][expDelay], 0, "ii", playerid, num);
KillTimer(bombtime[playerid][num]);
} else {
DetonateBomb(playerid, num);
}
}
}
public DetonateBomb(playerid, num)
{
new Float:x;
new Float:y;
new Float:z;
GetObjectPos(bombid[playerid][num], x, y, z);
OnBombExplode(playerid, num, x, y, z);
KillTimer(bombtime[playerid][num]);
if(gBombTypes[btype[playerid][num]][expID] > -1) {
CreateExplosion(x, y, z, gBombTypes[btype[playerid][num]][expID], gBombTypes[btype[playerid][num]][expRadius]);
} else {
CreateSpecialExplosion(gBombTypes[btype[playerid][num]][expID], num, playerid);
}
DestroyObject(bombid[playerid][num]);
bombid[playerid][num] = -1;
bombcount[playerid] --;
}
public CreateSpecialExplosion(explosionid, num, playerid)
{ //Every explosion with a negative explosion ID is created here
new Float:x; //You may add a check for your own bombs like the one already existing
new Float:y;
new Float:z;
GetObjectPos(bombid[playerid][num], x, y, z);
if(explosionid == -1) { //btype[playerid][num] is the index of the exploding bomb
CreateExplosion(x, y, z, 7, 4.0); //x, y and z are the coordinates of the bomb
CreateExplosion(x, y, z + 5.0, 1, 4.0);
CreateExplosion(x, y, z + 9.0, 1, 3.0);
CreateExplosion(x, y, z + 12.5, 1, 3.0);
CreateExplosion(x + 4.0, y, z, 0, 2.0);
CreateExplosion(x - 4.0, y, z, 0, 2.0);
CreateExplosion(x, y + 4.0, z, 0, 2.0);
CreateExplosion(x, y - 4.0, z, 0, 2.0);
CreateExplosion(x, y - 7.0, z, 1, 3.0);
CreateExplosion(x, y + 7.0, z, 1, 3.0);
CreateExplosion(x + 7.0, y, z, 1, 3.0);
CreateExplosion(x - 7.0, y, z, 1, 3.0);
CreateExplosion(x + 4.0, y + 4.0, z, 1, 4.0);
CreateExplosion(x - 4.0, y - 4.0, z, 1, 4.0);
CreateExplosion(x - 4.0, y + 4.0, z, 1, 4.0);
CreateExplosion(x + 4.0, y - 4.0, z, 1, 4.0);
} else if(explosionid == -2) {
CallRemoteFunction("StopAntiRocketFlare", "i", bombid[playerid][num]);
} else if(explosionid == -3) {
CreateExplosion(x, y, z, 7, 4.0);
SetTimerEx("CreateRadialExplosion", 200, 0, "fffii", x, y, z, 0, 4);
}
//To add an own explosion create a new check like this:
/*if(btype[playerid][num] == YOUR_BOMB_INDEX) {
...your explosion...
}*/
}
public CreateRadialExplosion(Float:x, Float:y, Float:z, round, max)
{
for(new i = 0; i < 1 + 6 * round; i ++) {
CreateExplosion(x + round * 10 * floatcos(6.28318 * (float(i) / (1.0 + 6.0*float(round)))), y + round * 10 * floatsin(6.28318 * (float(i) / (1.0 + 6.0*float(round)))), z, 2, 3.0);
}
round ++;
if(round <= max) SetTimerEx("CreateRadialExplosion", 200, 0, "fffii", x, y, z, round, max);
return 1;
}
public ReactivateBomb(playerid)
{
bfree[playerid] = 0;
#if(USE_TEXTDRAWS)
UpdateTextDraw(playerid);
#endif
}
forward killedbyc42(playerid,killerid);
public OnBombExplode(playerid, num, Float:x, Float:y, Float:z)
{
return 1;
}
public RemoveTextDraw(playerid)
{
if(!IsPlayerInAnyVehicle(playerid)) {
TextDrawHideForPlayer(playerid, bombtext[playerid]);
TextDrawDestroy(bombtext[playerid]);
KillTimer(removetimer[playerid]);
}
}
stock UpdateTextDraw(playerid)
{
new text[160] = " ";
#if(USE_TEXTDRAWS == 1)
if(bptype[playerid] == 0) text = "~r~Nothing~w~";
else text = "Nothing";
for(new i = 1; i < sizeof gBombTypes; i ++)
if(gVehicleBombs[vmid[playerid]][i + 1] == 1) {
if(bptype[playerid] == i) {
if(bfree[playerid] || !IsPlayerAllowedToDropBomb(playerid)) format(text, 160, "%s~n~~r~%s~w~", text, gBombTypes[i][bombName]);
else format(text, 160, "%s~n~~g~%s~w~", text, gBombTypes[i][bombName]);
} else format(text, 160, "%s~n~%s", text, gBombTypes[i][bombName]);
}
#elseif(USE_TEXTDRAWS == 2)
if(bfree[playerid] || bptype[playerid] == 0 || !IsPlayerAllowedToDropBomb(playerid)) format(text, 160, "~r~%s", gBombTypes[bptype[playerid]][bombName]);
else format(text, 160, "~g~%s", gBombTypes[bptype[playerid]][bombName]);
#endif
TextDrawSetString(bombtext[playerid], text);
}
public ResetNearExp(playerid)
{
SetPVarInt(playerid, "nearExp", -1);
}
IsPlayerAllowedToDropBomb(playerid)
{
#pragma unused playerid
// This is used to restrict the use of bombs for single players
// For example to make them available for special teams only, ...
// bptype[playerid] is the index of the selected bomb
return 1;
}