0 Members and 1 Guest are viewing this topic.
{gatling gun settings} gAmmo = 600; //1 shoot uses 2 bullets, use only even value 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 = 7;//gStarting = 10; (disabled)
Hey, How can a bot stay without shooting or moving ? :S
Call him dummy.... everyone knows that
(...)Question: Can you assign the sentry guns to teams/players, so they won't attack the creator/creators team?(...)
woah. Is there another special name ?
What would be nice is an automatic turret that could somehow be scripted, one that wouldn't need someone standing by it, Sentry style.
Quote from: Xxypher on February 09, 2009, 11:33:03 amWhat would be nice is an automatic turret that could somehow be scripted, one that wouldn't need someone standing by it, Sentry style.The bot is only there as a marker for where the turret is, the turret is automatic, it aims and shoots at the enemies when it can.
Do not use the script in teammatch gamemode because delta team is reserved only for sentrys.
This is a pitty, because the script would be nice to use in climb maps. Did you try making a sentry with a bot from DM-team (team 0)? I guess it does make the bots shoot at each other aswell?
Climb is ctf...?
{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 ittype 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 CrossFuncfunction GetSentryStat(ID, stat: byte): integer; //ID of sentry gun, not of Dummybegin 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 Dummybegin 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.1var 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;
100% sure.I made a .txt file and named it Dummy.bot and put it in bots.
Quote from: Xariki on October 19, 2009, 02:50:40 pm100% 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.