Author Topic: Sentry guns 0.90  (Read 9548 times)

0 Members and 1 Guest are viewing this topic.

Offline tk

  • Soldier
  • **
  • Posts: 235
Re: Sentry guns 0.90
« Reply #20 on: October 19, 2009, 08:54:19 am »
Also get 2.6.5 version of the server, it crashes on 2.6.4 because of forceweapon bug.

Offline Xariki

  • Major(1)
  • Posts: 5
Re: Sentry guns 0.90
« Reply #21 on: October 19, 2009, 01:15:36 pm »
Tk, it seems to also crash on 2.6.5, when I use /sgun ingame, it says "Bot file Dummy not found" even if it exists and after 10-20 seconds it says " Script Sgun has crashed, the server is now shutting down."
Any ideas?

Offline Gizd

  • Flagrunner
  • ****
  • Posts: 586
  • (Re)tired
    • Eat-this! community site
Re: Sentry guns 0.90
« Reply #22 on: October 19, 2009, 01:34:58 pm »
Are you sure that bot file exists?

Offline Xariki

  • Major(1)
  • Posts: 5
Re: Sentry guns 0.90
« Reply #23 on: October 19, 2009, 02:50:40 pm »
100% sure.
I made a .txt file and named it Dummy.bot and put it in bots.

Offline tk

  • Soldier
  • **
  • Posts: 235
Re: Sentry guns 0.90
« Reply #24 on: October 19, 2009, 02:59:10 pm »
Try this, the new version of the script which works correctly with the new core. It's also faster and should be more stable. I've been too lazy to relase it.
Code: [Select]
{Sentry Gun script by tk}
{version 0.92}

const
{settings}
MAX_NUM_OF_PLAYERS = 16; //max number of players on the server. Do not set value greater than 26.
SENTRY_TEAM = 0;
SENTRY_DURATION = 120;
cRed = $EE5C42;
cGreen = $BCEE68;

{gatling gun settings}
gAmmo = 800000;
gPower = 0.35;
gSpeed = 30; //bullet speed;
gInt = 2; //NOTE Modifing can cause issues. '1' gives 40 rounds per secound, but may be unstable.
gAccuracy = 8;

{heavy mg settings}
hgAmmo = 300;
hgPower = 1;
hgSpeed = 35;
hgInt = 3; //NOTE Modifing can cause issues.
hgAccuracy = 6;

{flak cannon}
fcAmmo = 200;
fcPower = 10;
fcSpeed = 22;
fcInt = 2; //NOTE Modifing can cause issues.
fcDivergence = 10;

{shotgun settings}
sgAmmo = 80;
sgPower = 1.8;
sgSpeed = 20;
sgPellets = 7; //number of shotgun pellets
sgInt = 17; //NOTE Modifing can cause issues.
sgSpread = 12;

{auto aiming missile settings}
mlAmmo = 8;
rocketFuel = 45; // recommended not to use value greater than 50.
accuracy = 40; //0 - the best accuracy. Recommended not to use value greater than 40.
acceleration = 3; // 3
flametraceMovement = 2; // 2

MAX_PLAYERS = MAX_NUM_OF_PLAYERS + 5; //do not modify it

type
tPlayer = record
is_sentry: boolean;
sentry_ID: byte;
end;

type
tSentry = record
owner,botID,style,target: byte;
duration,ammo: word;
last_fire: integer;
end;

var
player: array[1..MAX_PLAYERS] of tPlayer;
sentry: array[1..5] of tSentry;
missile_reload: integer;
sgBullID: byte;
disabled: boolean;

procedure nova(X,Y,dir_x,dir_y,r,speed,power: single; n: word; style, id: byte);
var
angle,sine,cosine: single;
begin
angle:=6.28318/n;
for n:=n downto 1 do
begin
sine:=sin(angle*n);
cosine:=cos(angle*n);
CreateBullet(cosine*r + X, sine*r + Y,cosine*speed + dir_x,sine*speed + dir_y,power, style, ID);
end;
end;

procedure Missile(owner_ID, target_ID: Byte; X, Y: Single);
{v. 1.6}
var
poly_coll, target_coll: Boolean;
n, interval: Word;
X2, Y2, dist, next_dist_x, next_dist_y, prev_dist_x, prev_dist_y, rd: Single;
begin
GetPlayerXY(target_ID,X2,Y2);
dist:=Distance(X,Y,X2,Y2);
next_dist_x:=(X2-X)/(dist/10);
next_dist_y:=(Y2-Y)/(dist/10);
X:=X + next_dist_x;
Y:=Y + next_dist_y;
prev_dist_x:=next_dist_x;
prev_dist_y:=next_dist_y;
interval:=40;
while n < rocketFuel do
begin
Sleep(interval);
next_dist_x:=((X2-X)/(dist/(20+accuracy*2))+prev_dist_x*accuracy) / (accuracy+1);
next_dist_y:=((Y2-Y)/(dist/(24+accuracy*2))+prev_dist_y*accuracy) / (accuracy+1);
prev_dist_x:=next_dist_x;
prev_dist_y:=next_dist_y;
X:=X + next_dist_x;
Y:=Y + next_dist_y;
GetPlayerXY(target_ID,X2,Y2);
dist:=Distance(X,Y,X2,Y2);
if dist > 80 then //poly dodging
begin
if not rayCast(X,Y,X+15,Y,rd,16) then X:=X - 15 else
if not rayCast(X,Y,X-15,Y,rd,16) then X:=X + 15;
if not rayCast(X,Y,X,Y+18,rd,19) then Y:=Y - 18 else
if not rayCast(X,Y,X,Y-18,rd,19) then Y:=Y + 18;
end;
if dist < 25 then //check for collision
begin
target_coll:=true;
break;
end else
if not RayCast(X,Y,X,Y,rd,1) then
begin
poly_coll:=true;
break;
end;
if dist > 10*flametraceMovement then //create one flame
CreateBullet(X, Y, next_dist_x/10*flametraceMovement, next_dist_y/10*flametraceMovement, 0, 5, owner_ID);
if interval > 9 then
interval:=interval-acceleration; //acceleration
n:=n+1;
end;
if target_coll then //collision with target
begin
DoDamageBy(target_ID, owner_ID, GetPlayerStat(target_ID, 'health')-1);
nova(X,Y,next_dist_x/2,next_dist_y/2,20,5,2,7,14,owner_ID);
nova(X2,Y2,0,0,30,8,2,9,14,owner_ID);
nova(X2,Y2,0,0,12,-3,10,5,4,owner_ID);
end else
if poly_coll then //collision with poly
begin
nova(X,Y,next_dist_x/2,next_dist_y/2,20,5,2,7,14,owner_ID);
nova(X,Y,0,0,20,-3,10,4,4,owner_ID);
end else
begin //no fuel
nova(X,Y,next_dist_x/3,next_dist_y/2,20,5,2,7,14,owner_ID);
CreateBullet(X, Y, next_dist_x/2, next_dist_x/3, 10, 4, owner_ID);
end;
end;

function Name(_type: byte): string;
begin
case _type of
1: Result:='Gatling gun';
2: Result:='Heavy machine gun';
3: Result:='Flak cannon';
4: Result:='Shotgun';
5: Result:='Missile launcher';
end;
end;

//PlaceSentry (ID of owner, type of sentry, X, Y, show WriteConsole info?)
//Returns ID of created sentry (0 if failed)
function PlaceSentry(ID,gun_type: byte; X,Y: single; show_info: boolean): byte;
var
i,j,k: byte;
place: boolean;
spawn_active: array[1..254] of boolean;
begin
if (GetPlayerStat(ID, 'Active') = true) and (GetPlayerStat(ID, 'Alive') = true) then
begin
if GetPlayerStat(ID, 'Ground') = true then
begin
if gun_type = 5 then //check if there is missile launcher in game
for i:=1 to 5 do
if sentry[i].style = 5 then
begin
if show_info then WriteConsole(ID, 'One "Missile launcher" is already placed. Choose another type of the gun.',cRed);
exit;
end;
for i:=1 to 5 do
if sentry[i].duration = 0 then
begin
place:=true;
break;
end;
if place then //force bot to spawn at given coords \/
begin
for j:=1 to 254 do
if GetSpawnStat(j, 'style') = SENTRY_TEAM then
begin
if GetSpawnStat(j, 'active') = true then spawn_active[j]:=true;
SetSpawnStat(j, 'active',false);
k:=j;
end;
SetSpawnStat(254, 'active',true);
SetSpawnStat(254, 'style',SENTRY_TEAM);
SetSpawnStat(254, 'X',X);
SetSpawnStat(254, 'Y',Y-10);
Result:=Command('/addbot'+inttostr(SENTRY_TEAM)+' Dummy');
SetSpawnStat(254, 'active',false);
for j:=1 to k do
if GetSpawnStat(j, 'style') = SENTRY_TEAM then
if spawn_active[j] then SetSpawnStat(j, 'active',true);
case gun_type of
1: begin sentry[i].ammo:=gAmmo;  ForceWeapon(sentry[i].botID,10,255,0); end;
2: begin sentry[i].ammo:=hgAmmo; ForceWeapon(sentry[i].botID,3,255,0); end;
3: begin sentry[i].ammo:=fcAmmo; end;
4: begin sentry[i].ammo:=sgAmmo; ForceWeapon(sentry[i].botID,5,255,0); end;
5: begin sentry[i].ammo:=mlAmmo; end;
end;
GiveBonus(sentry[i].botID,3);
sentry[i].duration:=SENTRY_DURATION;
sentry[i].owner:=ID;
sentry[i].style:=gun_type;
sentry[i].botID:=Result;
player[sentry[i].botID].sentry_ID:=i;
player[sentry[i].botID].is_sentry:=true;
DrawText(ID,Name(gun_type)+' placed.',240,cGreen,0.112,20,360);
if show_info then WriteConsole(ID, 'Sentry gun placed. (Type: '+Name(gun_type)+'; Ammo: '+IntToStr(sentry[i].ammo)+'; Duration: '+IntToStr(SENTRY_DURATION)+' seconds)',cGreen);
end else if show_info then WriteConsole(ID, 'Sentry gun count limit exceeded. Gun can not be placed.',cRed);
end else if show_info then WriteConsole(ID, 'You have to be on the ground to place a sentry gun.',cRed);
end else if show_info then WriteConsole(ID, 'You have to be alive to place a sentry gun.',cRed);
end;

//RemoveSentry (ID of sentry(1..5), explode?, show WriteConsole info?)
procedure RemoveSentry(sID: byte; explosion, show_info: boolean);
var X,Y: single;
begin
if show_info then
if sentry[sID].ammo <= 0 then
WriteConsole(sentry[sID].owner, 'One of your sentry guns: '''+Name(sentry[sID].style)+''' has been destroyed (no ammo).',cRed) else
if sentry[sID].duration <= 0 then WriteConsole(sentry[sID].owner, 'One of your sentry guns: '''+Name(sentry[sID].style)+''' has been destroyed (duration exceeted).',cRed) else
WriteConsole(sentry[sID].owner, 'One of your sentry guns: '''+Name(sentry[sID].style)+''' has been destroyed.',cRed);
if explosion then begin
GetPlayerXY(sentry[sID].botID,X,Y);
nova(X,Y,0,0,12,4,0,5,4,sentry[sID].botID);
CreateBullet(X, Y, 0, 0, 0, 4, sentry[sID].botID);
end;
sentry[sID].duration:=0;
sentry[sID].style:=0;
sentry[SID].owner:=0;
sentry[sID].target:=0;
sentry[sID].ammo:=0;
sentry[SID].last_fire:=0;
KickPlayer(sentry[sID].botID);
end;

// for CrossFunc

function GetSentryStat(ID, stat: byte): integer; //ID of sentry gun, not of Dummy
begin
case stat of
1: Result:=sentry[ID].owner; //owner's ID
2: Result:=sentry[ID].duration; //time left
3: Result:=sentry[ID].style; //Type of sentry
4: Result:=sentry[ID].ammo; //Ammo left
end;
end;

procedure SetSentryStat(ID, stat: byte; value: integer); //ID of sentry gun, not of Dummy
begin
case stat of
1: sentry[ID].owner:=value; //owner's ID
2: sentry[ID].duration:=value; //time left
3: sentry[ID].style:=value; //Type of sentry
4: sentry[ID].ammo:=value; //Ammo left
end;
end;

//ID of bot(1..32) to ID of sentry(1..5);
function IdToSid(Bot_ID: byte): byte; begin
Result:=player[Bot_ID].sentry_ID; end;

//ID of sentry(1..5) to ID of bot(1..32);
function SidToId(Snt_ID: byte): byte; begin
Result:=sentry[Snt_ID].botID; end;

procedure Shoot(X,Y,X2,Y2,accuracy,divergence,speed,power: single; bullets,style,shooter: byte);
//v. 1.1
var i: shortint;
dist_x,angle: single;
a: boolean;
begin
dist_x:=X2 - X;
if dist_x < 0 then
begin
dist_x:=-dist_x;
a:=false;
end else
a:=true;
if dist_x <> 0 then
begin
angle:=arctan((Y2-Y)/(X2-X));
if not a then angle:=angle+Pi;
end else
if Y > Y2 then angle:=4.71239
else
angle:=2.35619;
if accuracy > 0 then
accuracy:=Random(1, Round(accuracy) + 1) / 500 * iif(Random(1, 3) = 1, 1, -1);
if style <> 5 then angle:=angle + divergence * bullets * 0.5 + accuracy - sqrt((dist_x*1.2)/(speed*speed)) / (3+speed*0.4)*iif(a,1,-1)
else angle:=angle + divergence*bullets*0.5 + accuracy;
for i:=1 to bullets do
CreateBullet(X, Y, cos(angle - i*divergence)*speed, sin(angle - i*divergence)*speed, power, style, shooter);
end;

procedure ProcessSentry(ID, SID: byte);
var
X,Y,X2,Y2,rand: single;
begin
if sentry[SID].ammo > 0 then
begin
GetPlayerXY(ID, X, Y);
Y:=Y-10;
if sentry[SID].style < 5 then
begin
GetPlayerXY(sentry[SID].target, X2, Y2);
Y2:=Y2-10;
end;
if GetPlayerStat(sentry[SID].botID, 'direction') = '>' then X:=X+4 else X:=X-4;
case sentry[SID].style of
1: if GetTickCount-sentry[SID].last_fire >= gInt then
begin //MINIGUN
CreateBullet(X, Y-10-gInt, 0, 0, 2, 14, sgBullID);
Shoot(X,Y,X2,Y2,gAccuracy, 0, gSpeed+Random(1,4),gPower,1,1,ID);
Shoot(X,Y,X2,Y2 ,gAccuracy, 0, gSpeed-Random(1,4),gPower,1,1,ID);
end;
2: if GetTickCount-sentry[SID].last_fire >= hgInt then
begin //HMG
CreateBullet(X, Y-10-hgInt, 0, 0, 2, 14, sgBullID);
Shoot(X,Y,X2,Y2,hgAccuracy,0,hgSpeed-Random(1,5),hgPower,1,1,ID);
end;
3: if GetTickCount-sentry[SID].last_fire >= fcInt then
begin //FLAK
CreateBullet(X, Y-10-fcInt, 0, -0.4-Random(0,3)/3, 2, 14, sgBullID);
rand:=Random(fcDivergence div 2,fcDivergence)/100;
Shoot(X,Y,X2,Y2,0,rand, fcSpeed,fcPower*0.5,1,10,ID);
Shoot(X,Y,X2,Y2,0,rand, fcSpeed,fcPower ,1,14,ID);
end;
4: if GetTickCount-sentry[SID].last_fire >= sgInt then
begin //SHOTGUN
CreateBullet(X, Y-10-sgInt, 0, -0.4, 2, 14, sgBullID);
Shoot(X,Y,X2,Y2 ,sgSpread, Random(2,6)/1000*sgSpread, sgSpeed+1, sgPower, sgPellets div 4, 3, ID);
Shoot(X,Y,X2,Y2,sgSpread, Random(2,4)/1000*sgSpread, sgSpeed-2, sgPower, sgPellets div 4, 3, ID);
Shoot(X,Y,X2,Y2 ,sgSpread, Random(2,6)/1000*sgSpread, sgSpeed+2, sgPower, sgPellets div 4, 3, ID);
Shoot(X,Y,X2,Y2,sgSpread, Random(2,7)/1000*sgSpread, sgSpeed-1, sgPower, sgPellets div 4, 3, ID);
Shoot(X,Y,X2,Y2 ,sgSpread, Random(3,6)/1000*sgSpread, sgSpeed, sgPower, sgPellets mod 4, 3, ID);
end;
5: if missile_reload > 0 then missile_reload:=missile_reload-1 else
begin
ThreadFunc([sentry[SID].owner, sentry[SID].target, X, Y], 'Missile');
missile_reload:=5;
end;
end;
sentry[SID].last_fire:=GetTickCount;
sentry[SID].ammo:=sentry[SID].ammo-1;
end;
end;

function OnPlayerDamage(Victim, Shooter: byte; Damage: integer): integer;
begin
if player[Victim].is_sentry then
begin
if shooter = sgBullID then
if sentry[player[Victim].sentry_ID].target > 0 then
ProcessSentry(Victim, player[Victim].sentry_ID);
Result:=-999999;
end else Result:=Damage;
end;

function lookForTarget(SentryID,SentryOwner: byte; X,Y,MaxDistance: integer; UsingRaycast: boolean): byte; {SentryID - ID of sentry (1..5), not of Dummy}
var
i, t: byte;
X2,Y2,sqrdist,maxdist: single;
begin
maxdist:=MaxDistance*MaxDistance;
Result:=0;
t := GetPlayerStat(SentryOwner, 'Team');
for i:=1 to MAX_PLAYERS do
if GetPlayerStat(i, 'Active') then
if (i <> SentryID) and (i <> SentryOwner) then
if GetPlayerStat(i, 'Alive')=true then
if ((not player[i].is_sentry) and (t <> GetPlayerStat(i, 'Team'))) or (t = 0) then
begin
GetPlayerXY(i,X2,Y2);
if UsingRayCast then
if not RayCast(X,Y-7,X2,Y2-7,sqrdist,MaxDistance+1) then continue;
X2:=X2-X;
Y2:=Y2-Y;
sqrdist:=X2*X2+Y2*Y2;
if sqrdist < maxdist then
begin
Result:=i;
maxdist:=sqrdist;
end;
end;
end;

procedure AppOnIdle(Ticks: integer);
var
i: byte;
begin
if (paused) or (disabled) then exit;
for i:=1 to 5 do
begin
if sentry[i].duration = 0 then continue else
begin
sentry[i].duration:=sentry[i].duration - 1;
if sentry[i].ammo > 0 then
begin
sentry[i].target:=lookForTarget(sentry[i].botID, sentry[i].owner, GetPlayerStat(sentry[i].botID, 'X'), GetPlayerStat(sentry[i].botID, 'Y'), 800, true); //find a target
if sentry[i].target > 0 then
if GetTickCount - sentry[i].last_fire >= 45 then
// ProcessSentry(sentry[i].botID, i);
DoDamageBy(sentry[i].botID, sgBullID, 3);
end else
sentry[i].duration:=0;
if sentry[i].duration = 0 then RemoveSentry(i, false, true);
end;
end;
end;

procedure OnPlayerKill(Killer, Victim: byte; Weapon: string);
begin
if player[Killer].is_sentry then
if sentry[player[killer].sentry_ID].target > 0 then
sentry[player[killer].sentry_ID].target:=0//lookForTarget(Killer, sentry[player[killer].sentry_ID].owner, GetPlayerStat(Killer, 'X'), GetPlayerStat(Killer, 'Y'),700,true);
end;

function OnCommand(ID: Byte; Text: string): boolean;
var i: byte; x,y,rd:single; facing: integer;
begin
case lowercase(Text) of
'/delsgun', '/dsg':
for i:=1 to 5 do
if sentry[i].duration > 0 then
if Distance(GetPlayerStat(ID, 'X'), GetPlayerStat(ID, 'Y'), GetPlayerStat(sentry[i].botID, 'X'), GetPlayerStat(sentry[i].botID, 'Y')) < 50 then
RemoveSentry(i, false, true);
'/switch':disabled:=not disabled;
'/swt':sentry[1].owner:=3;
'/mss':missile(2, id, GetPlayerStat(2, 'X'), GetPlayerStat(2, 'Y'));
'/nova':nova(GetPlayerStat(ID, 'X'), GetPlayerStat(ID, 'Y'), 0, 0,35,-15,60,100,14,ID);
else begin
if MaskCheck(Text, '/sgun *') then
if (GetPiece(Text, ' ', 1) <> nil) and (StrToInt(GetPiece(Text, ' ', 1)) <= 5) then PlaceSentry(ID,StrToInt(GetPiece(Text, ' ', 1)),GetPlayerStat(ID, 'X'),GetPlayerStat(ID, 'Y'),true);
if MaskCheck(Text, '/esgun *') then
if (GetPiece(Text, ' ', 1) <> nil) and (StrToInt(GetPiece(Text, ' ', 1)) <= 5) then PlaceSentry(ID+1,StrToInt(GetPiece(Text, ' ', 1)),GetPlayerStat(ID, 'X'),GetPlayerStat(ID, 'Y'),true);
end;
end;
end;

procedure GetBulletID; //finds owner ID for bullets which hurt bots.
var i: byte;
begin
for i:=1 to MAX_PLAYERS do
if GetPlayerStat(i, 'Active') then
if GetPlayerStat(i, 'Team') <> SENTRY_TEAM then
begin
sgBullID:=i;
exit;
end;
end;

procedure OnJoinGame(ID, Team: byte);
begin
GetBulletID;
end;

procedure OnJoinTeam(ID, Team: byte);
begin
GetBulletID;
end;

procedure OnLeaveGame(ID, Team: byte; Kicked: boolean);
var i: byte;
begin
if not player[ID].is_sentry then
begin
for i:=1 to 5 do
if sentry[i].owner = ID then
RemoveSentry(i, false, false);
GetBulletID;
end;
end;

procedure ActivateServer();
var i: byte;
begin
GetBulletID;
for i:=1 to MAX_PLAYERS do
if IDToName(i) = 'Dummy' then kickplayer(i);
end;

procedure OnMapChange(NewMap: String);
var i: byte;
begin
GetBulletID;
for i:=1 to 5 do
if sentry[i].botID <> 0 then
RemoveSentry(i, false, false);
end;
« Last Edit: October 19, 2009, 03:03:03 pm by tk »

Offline iDante

  • Veteran
  • *****
  • Posts: 1967
Re: Sentry guns 0.90
« Reply #25 on: October 19, 2009, 04:38:27 pm »
100% sure.
I made a .txt file and named it Dummy.bot and put it in bots.
Change its name to Dummy in the actual file as well.

Offline Gizd

  • Flagrunner
  • ****
  • Posts: 586
  • (Re)tired
    • Eat-this! community site
Re: Sentry guns 0.90
« Reply #26 on: October 20, 2009, 08:52:02 am »
100% sure.
I made a .txt file and named it Dummy.bot and put it in bots.
Change its name to Dummy in the actual file as well.
Doesn't matter(except that it won't be a dummy...). String in /addbot is file name.

Offline MikisPL

  • Major(1)
  • Posts: 11
Re: Sentry guns 0.90
« Reply #27 on: January 17, 2010, 09:26:11 am »
Help  :(
Where do I put this script?

Offline Hacktank

  • Camper
  • ***
  • Posts: 462
  • Soldat Scripter
    • HTZRPG
Re: Sentry guns 0.90
« Reply #28 on: January 17, 2010, 07:51:28 pm »
In the scripts folder of the dedicated server, not the server you run from soldat.


Offline MikisPL

  • Major(1)
  • Posts: 11
Re: Sentry guns 0.90
« Reply #29 on: January 18, 2010, 10:10:58 am »
Give an example plz.

Offline Hacktank

  • Camper
  • ***
  • Posts: 462
  • Soldat Scripter
    • HTZRPG
Re: Sentry guns 0.90
« Reply #30 on: January 18, 2010, 02:23:15 pm »


Offline MikisPL

  • Major(1)
  • Posts: 11
Re: Sentry guns 0.90
« Reply #31 on: February 02, 2010, 10:24:21 am »
thanks for help  ;)