Author Topic: How to activate bot on see within a certain area.  (Read 2801 times)

0 Members and 1 Guest are viewing this topic.

Offline D4NG3R NL

  • Soldier
  • **
  • Posts: 130
  • You got Rickroll'd
How to activate bot on see within a certain area.
« on: May 15, 2009, 02:27:34 am »
I need to activate the "Witch" bot when you come to near.

Part of code I have now:

Code: [Select]
//Made by D4NG3R for the zombie survival server, based on the codec of the origional author:
//Shantec


function OnPlayerDamage(Victim, Shooter: byte; Damage: integer): integer;
var Vx,Vy,Sx,Sy: single;
begin
  if (IdToName(victim) = 'Witch') and (IdToName(shooter) <> 'Witch') then begin
  Vx := GetPlayerStat(Victim,'X');
  Vy := GetPlayerStat(Victim,'Y');
  Sx := GetPlayerStat(Shooter,'X');
  Sy := GetPlayerStat(Shooter,'Y');
If (Distance(Vx,Vy,Sx,Sy) < 180) and (GetPlayerStat(victim,'Alive') = true) then begin
  //Here needs to bee the bot start part
  WriteConsole(ID,'You startled a Witch!',RGB(200,200,200))
end;
  end;
end;

procedure OnPlayerKill(Killer, Victim: byte; Weapon: string);
begin
  if (IdToName(victim) = 'Witch') and (IdToName(killer) <> 'Witch') then begin
  WriteConsole(ID,'You killed the Witch.',RGB(200,200,200))
  end;
end;
« Last Edit: May 15, 2009, 02:30:40 am by D4NG3R NL »
                  Forum Rules   -   Search

Offline DorkeyDear

  • Veteran
  • *****
  • Posts: 1507
  • I also go by Curt or menturi
Re: How to activate bot on see within a certain area.
« Reply #1 on: May 15, 2009, 05:17:13 am »
You could use Avarax's SpawnBot function which adds a bot to the game at a given location. It's under Script Releases somewhere.

I also suggest doing if (GetPlayerStat(#, 'Human') = false) then.
« Last Edit: May 15, 2009, 05:19:03 am by DorkeyDear »

Offline shantec

  • Soldier
  • **
  • Posts: 140
  • Get ANGREH!!
Re: How to activate bot on see within a certain area.
« Reply #2 on: May 15, 2009, 03:03:01 pm »
First you must to do is dummy bot, named witch (is it possible? or does the name need to be "dummy"?), i think you want to make LeftForDead alike witch, amirite?
Then, if the distance is small enough, kick the dummy named witch, and spawn "living" witch bot
Quote
using Avarax's SpawnBot
Also Known As REIMA


Lol Happles (happy apples)

Offline D4NG3R NL

  • Soldier
  • **
  • Posts: 130
  • You got Rickroll'd
Re: How to activate bot on see within a certain area.
« Reply #3 on: May 15, 2009, 05:57:54 pm »
First you must to do is dummy bot, named witch (is it possible? or does the name need to be "dummy"?), i think you want to make LeftForDead alike witch, amirite?
Then, if the distance is small enough, kick the dummy named witch, and spawn "living" witch bot
Quote
using Avarax's SpawnBot

Hmmm, that actually is a great idea...

Code: [Select]
//Witch Testing script based on some codec of: Shantec's "Taliban" script

function PlaceBot(botname: string; team: byte; X,Y: single): byte;
function OnPlayerDamage(Witch, Player: byte; Damage: integer): integer;
var Wx,Wy,Px,Py: single;
begin
if (IdToName(Witch) = 'Dummy') and (IdToName(Player) <> 'Witch') then begin
Wx := GetPlayerStat(Witch,'X');
Wy := GetPlayerStat(Witch,'Y');
Px := GetPlayerStat(Player,'X');
Py := GetPlayerStat(Player,'Y');
If (Distance(Wx,Wy,Px,Py) < 180) and (GetPlayerStat(Witch,'Alive') = true) then begin
Command('/kick Dummy')
PlaceBot('Witch',GetPlayerStat(Dummy,'Team'),GetPlayerStat(Dummy,'X'),GetPlayerStat(Dummy,'Y'));
WriteConsole(ID, 'You startled the witch!', $FFFFFF);
end;
end;

procedure OnPlayerKill(Witch: byte; Weapon: string);
begin
if (IdToName(Witch) = 'Witch') then begin
Command('/kick Witch')
Command('/Addbot2 Dummy)
end;
end;

[Error] (4:1) 'BEGIN' expected
Line 4 word 1 already IS begin....
Whats wrong xD
« Last Edit: May 15, 2009, 06:36:25 pm by D4NG3R NL »
                  Forum Rules   -   Search

Offline Hacktank

  • Camper
  • ***
  • Posts: 462
  • Soldat Scripter
    • HTZRPG
Re: How to activate bot on see within a certain area.
« Reply #4 on: May 15, 2009, 07:03:32 pm »
You have one function right after another.

Code: [Select]
function PlaceBot(botname: string; team: byte; X,Y: single): byte;
function OnPlayerDamage(Witch, Player: byte; Damage: integer): integer;
var Wx,Wy,Px,Py: single;
begin;

Code: [Select]
function PlaceBot(botname: string; team: byte; X,Y: single): byte;
begin
//actual placebot stuff here
end;

function OnPlayerDamage(Witch, Player: byte; Damage: integer): integer;
var Wx,Wy,Px,Py: single;
begin;

PS: lines are counted weather blank or not. Also the compiler adds one for some reason. So if it gave an error on line 5 spot 3 it would actuall be line 4 spot 3, whitch on yours is
Code: [Select]
fu >n< ction OnPlayerDamage(Witch, Player: byte; Damage: integer): integer;.
« Last Edit: May 15, 2009, 07:09:42 pm by Hacktank »


Offline Gizd

  • Flagrunner
  • ****
  • Posts: 586
  • (Re)tired
    • Eat-this! community site
Re: How to activate bot on see within a certain area.
« Reply #5 on: May 16, 2009, 01:48:33 am »
Quote
function OnPlayerDamage(Witch, Player: byte; Damage: integer): integer;
...
WriteConsole(ID, 'You startled the witch!', $FFFFFF);
There is no 'ID' there...
And change Command('/kick Dummy') into KickPlayer(Witch)

Offline y0uRd34th

  • Camper
  • ***
  • Posts: 325
  • [i]Look Signature![/i]
Re: How to activate bot on see within a certain area.
« Reply #6 on: May 16, 2009, 03:10:15 am »
Code: [Select]
function PlaceBot(botname: string; team: byte; X,Y: single): byte;
var i,n,tempType: byte;
    spawn: array of byte;
    tempX,tempY: single;
begin
  SetArrayLength(spawn,0);
  n:=0;
  for i:=1 to 254 do
    If GetSpawnStat(i,'Active') = true then
      If GetSpawnStat(i,'Style') = team then begin
        n:=n + 1;
        SetArrayLength(spawn,n);
        spawn[n-1]:=i;
        SetSpawnStat(i,'Active',false);
      end;
  for i:=1 to 254 do
    If GetSpawnStat(i,'Active') = false then begin
      SetSpawnStat(i,'Active',true);
      tempType:=GetSpawnStat(i,'Style');
      tempX:=GetSpawnStat(i,'X');
      tempY:=GetSpawnStat(i,'Y');
      SetSpawnStat(i,'Style',team);
      SetSpawnStat(i,'X',X);
      SetSpawnStat(i,'Y',Y);
      break;
    end;
  result:=Command('/addbot' + inttostr(team) + ' ' + botname);
  SetSpawnStat(i,'Active',false);
  SetSpawnStat(i,'Style',tempType);
  SetSpawnStat(i,'X',tempX);
  SetSpawnStat(i,'Y',tempY);
  If n > 0 then
    for i:=0 to n-1 do
      SetSpawnStat(spawn[i],'Active',true);
end;

copied & pasted from Avarax MMod.

Offline D4NG3R NL

  • Soldier
  • **
  • Posts: 130
  • You got Rickroll'd
Re: How to activate bot on see within a certain area.
« Reply #7 on: May 16, 2009, 01:57:04 pm »
Ok now its making me kinda dizzy xD

What I need to get:

X & Y of the "Dummy"
Then at those X & Y coordinates a "Witch" bot spawns

What happens:
Dummy gets kicked
Witch gets added, when killed she gets kicked & after 60 seconds a Dummy re-spawns.

The script should run when the player gets in a certain area OR when the dummy gets damaged!

I know the dummy gets hit it needs to run a OnDamage script, but HOW do I have to get the distance to work to?
« Last Edit: May 16, 2009, 01:59:06 pm by D4NG3R NL »
                  Forum Rules   -   Search

Offline iDante

  • Veteran
  • *****
  • Posts: 1967
Re: How to activate bot on see within a certain area.
« Reply #8 on: May 16, 2009, 02:17:11 pm »
In AppOnIdle check everyone's distance to the bot using the Distance function in the scriptcore.

Offline tk

  • Soldier
  • **
  • Posts: 235
Re: How to activate bot on see within a certain area.
« Reply #9 on: May 16, 2009, 02:17:26 pm »
Distance(x,y,x2,y2: single): single;

if Distance(x,y,x2,y2) < 150 then //...

or for short distances like 0-50 units

if Abs(x - x2) <= 50 then
  if Abs(y - y2) <= 50 then // ...


Offline D4NG3R NL

  • Soldier
  • **
  • Posts: 130
  • You got Rickroll'd
Re: How to activate bot on see within a certain area.
« Reply #10 on: May 16, 2009, 02:31:55 pm »
In AppOnIdle check everyone's distance to the bot using the Distance function in the scriptcore.

If the script constantly checks the player positions wouldn't it make lag?
                  Forum Rules   -   Search

Offline EnEsCe

  • Retired Soldat Developer
  • Flamebow Warrior
  • ******
  • Posts: 3101
  • http://enesce.com/
    • [eC] Official Website
Re: How to activate bot on see within a certain area.
« Reply #11 on: May 16, 2009, 02:45:23 pm »
In AppOnIdle check everyone's distance to the bot using the Distance function in the scriptcore.

If the script constantly checks the player positions wouldn't it make lag?
Yep, the Distance function's code is quite heavy so it is unwise to be calling it frequently.

Offline danmer

  • Camper
  • ***
  • Posts: 466
  • crabhead
Re: How to activate bot on see within a certain area.
« Reply #12 on: May 16, 2009, 04:56:23 pm »
well... isn't it just some powers and sqrt? Or do you mean that even that is heavy already? Oo

Offline DorkeyDear

  • Veteran
  • *****
  • Posts: 1507
  • I also go by Curt or menturi
Re: How to activate bot on see within a certain area.
« Reply #13 on: May 16, 2009, 04:58:53 pm »
You could also have:
Code: [Select]
const
  Distance = 150.0;

var
  Distance2: double;

procedure ActivateServer();
begin
  Distance2 := Distance * Distance;
end;

procedure AppOnIdle(Ticks: cardinal);
begin
  if (GetPlayerStat(__, 'X') * GetPlayerStat(__, 'X') + GetPlayerStat(__, 'Y') * GetPlayerStat(__, 'Y') < Distance2) then begin
    // ...
  end;
end;
That way it never does any sort of Sqrt, which is a source (afaik) of some slowness. If not, it now only squares 2 numbers (by multiplying, not some complex power algorithm) instead of three (except on activateserver, which it squares the 3rd number, but sense it doesn't vary, only need to do this once)
« Last Edit: May 16, 2009, 05:00:59 pm by DorkeyDear »

Offline iDante

  • Veteran
  • *****
  • Posts: 1967
Re: How to activate bot on see within a certain area.
« Reply #14 on: May 16, 2009, 07:51:13 pm »
It's a good idea Curt, here's how I'd implement that.
Code: [Select]
const
   Distance = 150.0;
   BOTID = 1;

var
   Distance2: single;

procedure ActivateServer;
begin
   Distance2 := Distance * Distance;
end;

procedure AppOnIdle(Ticks: cardinal);
var
   i: integer;
   wx,wy,x,y: single;
begin
   GetPlayerXY(BOTID, wx, wy);
   for i := 1 to 32 do begin
      GetPlayerXY(i, x, y);
      if ( ( (x-wx)*(x-wx) + (y-wy)*(y-wy) ) < Distance2 ) AND ( i <> BOTID ) then begin
         { It is close enough, do stuff }
      end;
   end;
end;
Has not been tested, probably wrong

Offline tk

  • Soldier
  • **
  • Posts: 235
Re: How to activate bot on see within a certain area.
« Reply #15 on: May 17, 2009, 03:16:44 am »
Faster and working version:

Code: [Select]
const
  Dist = 150;
  Max_Players = 20;
  Distance2 = Dist*Dist;

procedure AppOnIdle(Ticks: cardinal);
var
   i: byte;
   x,y,x2,y2: single;
begin
  GetPlayerXY(BOTID, x, y);
  for i := 1 to Max_Players do
    if GetPlayerStat(i,'Active') then
      if i <> BOTID then
      begin
        GetPlayerXY(i, x2, y2);
        x2:=x2-x;
        y2:=y2-y;
        if x2*x2 + y2*y2 < Distance2 then
        begin
          { It is close enough, do stuff }
        end;
   end;
end;
« Last Edit: May 17, 2009, 03:33:18 am by tk »

Offline D4NG3R NL

  • Soldier
  • **
  • Posts: 130
  • You got Rickroll'd
Re: How to activate bot on see within a certain area.
« Reply #16 on: May 17, 2009, 11:18:58 am »
Faster and working version:

Code: [Select]
const
  Dist = 150;
  Max_Players = 20;
  Distance2 = Dist*Dist;

procedure AppOnIdle(Ticks: cardinal);
var
   i: byte;
   x,y,x2,y2: single;
begin
  GetPlayerXY(BOTID, x, y);
  for i := 1 to Max_Players do
    if GetPlayerStat(i,'Active') then
      if i <> BOTID then
      begin
        GetPlayerXY(i, x2, y2);
        x2:=x2-x;
        y2:=y2-y;
        if x2*x2 + y2*y2 < Distance2 then
        begin
          { It is close enough, do stuff }
        end;
   end;
end;

Unknown Identifier BOTID. When I change BOTID to Witch It gives the same thing...

Or do I have to add something to this!? (Sorry I'm quite new to the whole scripting part of soldat.... :(
                  Forum Rules   -   Search

Offline croat1gamer

  • Veteran
  • *****
  • Posts: 1327
  • OMG CHANGING AVATAR!!! ^ω^
Re: How to activate bot on see within a certain area.
« Reply #17 on: May 17, 2009, 11:31:37 am »
BOTID is the id number of the bot in the game.
Last year, I dreamt I was pissing at a restroom, but I missed the urinal and my penis exploded.

Offline tk

  • Soldier
  • **
  • Posts: 235
Re: How to activate bot on see within a certain area.
« Reply #18 on: May 17, 2009, 11:32:49 am »
BOTID is for you to know where to put ID of the witch.
There is BOTID in two places, maybe you missed one
Quote
  GetPlayerXY(BOTID, x, y);
  for i := 1 to Max_Players do
    if GetPlayerStat(i,'Active') then
      if i <> BOTID then

Offline DorkeyDear

  • Veteran
  • *****
  • Posts: 1507
  • I also go by Curt or menturi
Re: How to activate bot on see within a certain area.
« Reply #19 on: May 17, 2009, 11:47:09 am »
Code: [Select]
const
  Dist = 150.0;
  Dist2 = Dist * Dist;

function PlaceBot(botname: string; team: byte; X,Y: single): byte;
var i,n,tempType: byte;
    spawn: array of byte;
    tempX,tempY: single;
begin
  SetArrayLength(spawn,0);
  n:=0;
  for i:=1 to 254 do
    If GetSpawnStat(i,'Active') = true then
      If GetSpawnStat(i,'Style') = team then begin
        n:=n + 1;
        SetArrayLength(spawn,n);
        spawn[n-1]:=i;
        SetSpawnStat(i,'Active',false);
      end;
  for i:=1 to 254 do
    If GetSpawnStat(i,'Active') = false then begin
      SetSpawnStat(i,'Active',true);
      tempType:=GetSpawnStat(i,'Style');
      tempX:=GetSpawnStat(i,'X');
      tempY:=GetSpawnStat(i,'Y');
      SetSpawnStat(i,'Style',team);
      SetSpawnStat(i,'X',X);
      SetSpawnStat(i,'Y',Y);
      break;
    end;
  result:=Command('/addbot' + inttostr(team) + ' ' + botname);
  SetSpawnStat(i,'Active',false);
  SetSpawnStat(i,'Style',tempType);
  SetSpawnStat(i,'X',tempX);
  SetSpawnStat(i,'Y',tempY);
  If n > 0 then
    for i:=0 to n-1 do
      SetSpawnStat(spawn[i],'Active',true);
end;

procedure AppOnIdle(Ticks: cardinal);
var
  i, j: byte;
  X1, Y1, X2, Y2, DX, DY: single;
begin
  for i := 1 to 32 do
    if (GetPlayerStat(i, 'Active') = true) then
      if (GetPlayerStat(i, 'Human') = true) then begin
        GetPlayerXY(i, X1, Y1);
        for j := 1 to 32 do
          if ((i <> j) and (GetPlayerStat(j, 'Active') = true)) then
            if ((GetPlayerStat(j, 'Human') = false) and (GetPlayerStat(j, 'Name') = 'Dummy') and (GetPlayerStat(i, 'Team') <> GetPlayerStat(j, 'Team'))) then begin
              GetPlayerXY(j, X2, Y2);
              DX := X2 - X1;
              DY := Y2 - Y1;
              if (DX * DX + DY * DY < Dist2) then begin
                PlaceBot('Witch', GetPlayerStat(j, 'Team'), X2, Y2);
                KickPlayer(j);
              end;
            end;
      end;
end;
compiles, not tested;
should, if a human goes in range of a bot named Dummy; replace Dummy with Witch