Author Topic: Question Thread  (Read 32459 times)

0 Members and 2 Guests are viewing this topic.

DarkCrusade

  • Guest
Re: Question Thread
« Reply #80 on: April 10, 2010, 11:44:54 am »
Great! This helped me much :) I am currently trying to find a balanced damage incremention for the random function. Is there a way to detect the nearest enemy foe that is not dead?

Offline squiddy

  • Soldat Beta Team
  • Camper
  • ******
  • Posts: 333
  • Flagger assassin
    • SoldatX
Re: Question Thread
« Reply #81 on: April 10, 2010, 11:54:05 am »
Great! This helped me much :) I am currently trying to find a balanced damage incremention for the random function. Is there a way to detect the nearest enemy foe that is not dead?

Sure there is!

Just need to use RayCast() and GetPlayerStat();

Here it goes..

Code: [Select]
[...] Some Procedure you may use.. //I don't know which one is it, so, fill this yourself.
 Var S: Byte; Dist: Single; //S = Player's ID. I entered S because I have no idea if in that procedure there is already a 'DC' Byte, so I entered 'S' of Squiddy :P. Dist is the distance used in RayCast();
  Begin //Starts..
   For S := 1 To 32 Do if GetPlayerStat(S,'Alive') = True Then Begin //Checks is target player is alive..
    if RayCast(GetPlayerStat(ID,'X'),GetPlayerStat(ID,'Y'),GetPlayerStat(S,'X'),GetPlayerStat(S,'Y'),Dist,800) = True Then Begin //Check is player S is visible for player ID..
[...] //Here go whatever you want to put it in..
  end; //Ending the RayCast() Function..
 end; //Ending the GetPlayerStat() Function..
end; //Ending the Procedure..

RayCast() Function checks if Player ID can see Player S. You have to determinate if its True or False.
www.soldatx.com.br - The brazilian Soldat community.

DarkCrusade

  • Guest
Re: Question Thread
« Reply #82 on: April 10, 2010, 12:30:01 pm »
Works great. Awesome that there is this Raycast function since I will add a Ninja class. Right now the DoDamage part looks like this:

Code: [Select]
// Do additional damage to the next enemy after the Berserker killed someone.

Procedure OnPlayerKill(Killer,Victim:byte;Weapon:byte);
 begin
if Klasse[Killer] = 'Berserker' then begin
Var S: Byte; Dist: Single;
  Begin
   For S := 1 To 32 Do if GetPlayerStat(S,'Alive') = True Then Begin
    if RayCast(GetPlayerStat(ID,'X'),GetPlayerStat(ID,'Y'),GetPlayerStat(S,'X'),GetPlayerStat(S,'Y'),Dist,800) = True Then Begin
DoDamage(S,Killer,50);
  end;
 end;
end;

But for some reason I get this error:

Code: [Select]
10-04-10 19:26:44  [*] Compiling Knife Server -> KnifeServer.pas...
10-04-10 19:26:44  [*] Knife Server -> [Error] (114:3): Identifier expected
10-04-10 19:26:44  [*] Compilation Failed.
10-04-10 19:26:44 Shutting down server...

I know I am dumb :S

Offline Swompie

  • Camper
  • ***
  • Posts: 390
Re: Question Thread
« Reply #83 on: April 10, 2010, 12:32:50 pm »
http://devs.soldat.pl/wiki/index.php?title=Server_Scripting ftw.
I'm quite sure you used eC's, it's not supporting the current server version anymore, the link above does.

Use DoDamageBy(Victim, Shooter, Damage); instead of DoDamage here

Beside a question, do you want to damage all players around the player or only the nearest?

DarkCrusade

  • Guest
Re: Question Thread
« Reply #84 on: April 10, 2010, 12:42:35 pm »
Only the nearest. I don´t know why you used DoDamageBy(Victim,Shooter,Damage);. devs.Soldat says that it´s DoDamage(ID,Damage); ... I am so confused.
« Last Edit: April 10, 2010, 12:53:05 pm by DarkCrusade »

Offline Swompie

  • Camper
  • ***
  • Posts: 390
Re: Question Thread
« Reply #85 on: April 10, 2010, 02:19:09 pm »
Well, with DoDamageBy you can specify which person deals damage to someone, with DoDamage it's just the player itself whos damaging hismelf afaik.

DarkCrusade

  • Guest
Re: Question Thread
« Reply #86 on: April 10, 2010, 02:37:56 pm »
Code: [Select]
10-04-10 21:36:10  [*] Compiling Knife Server -> KnifeServer.pas...
10-04-10 21:36:10  [*] Knife Server -> [Error] (117:3): Identifier expected
10-04-10 21:36:10  [*] Compilation Failed.
10-04-10 21:36:10 Shutting down server...

For ...

Code: [Select]
Procedure OnPlayerKill(Killer,Victim:byte;Weapon:byte);
 begin
if Klasse[Killer] = 'Berserker' then begin
Var S: Byte; Dist: Single;
  begin
   For S := 1 To 32 Do if GetPlayerStat(S,'Alive') = True Then Begin
    if RayCast(GetPlayerStat(ID,'X'),GetPlayerStat(ID,'Y'),GetPlayerStat(S,'X'),GetPlayerStat(S,'Y'),Dist,800) = True Then Begin
DoDamageBy(S,Killer,50);
  end;
 end;
end;

Offline Gizd

  • Flagrunner
  • ****
  • Posts: 586
  • (Re)tired
    • Eat-this! community site
Re: Question Thread
« Reply #87 on: April 10, 2010, 03:10:47 pm »
Code: [Select]
Procedure OnPlayerKill(Killer,Victim:byte;Weapon:byte);
 begin
if Klasse[Killer] = 'Berserker' then begin
Var S: Byte; Dist: Single;
  begin
   For S := 1 To 32 Do if GetPlayerStat(S,'Alive') = True Then Begin
    if RayCast(GetPlayerStat(ID,'X'),GetPlayerStat(ID,'Y'),GetPlayerStat(S,'X'),GetPlayerStat(S,'Y'),Dist,800) = True Then Begin
DoDamageBy(S,Killer,50);
  end;
 end;
end;

It's because your style of coding sucks:
Code: [Select]
Procedure OnPlayerKill(Killer,Victim:byte;Weapon:byte);
begin
  if Klasse[Killer] = 'Berserker' then begin
    Var S: Byte; Dist: Single;
    begin
      For S := 1 To 32 Do if GetPlayerStat(S,'Alive') = True Then Begin
        if RayCast(GetPlayerStat(ID,'X'),GetPlayerStat(ID,'Y'),GetPlayerStat(S,'X'),GetPlayerStat(S,'Y'),Dist,800) = True Then Begin
          DoDamageBy(S,Killer,50);
        end;
      end;
    end;
Also you can't declare vars inside function...

DarkCrusade

  • Guest
Re: Question Thread
« Reply #88 on: April 10, 2010, 05:01:42 pm »
Well well, Gizd. I put the variables to the beginning and got some errors because of Raycast. Raycast didn´t change.

Offline chutem

  • Veteran
  • *****
  • Posts: 1119
Re: Question Thread
« Reply #89 on: April 10, 2010, 08:15:33 pm »
Why are you using rayCast to find the closest player?...
1NK3FbdNtH6jNH4dc1fzuvd4ruVdMQABvs

Offline SpiltCoffee

  • Veteran
  • *****
  • Posts: 1579
  • Spilt, not Split!
    • SpiltCoffee's Site
Re: Question Thread
« Reply #90 on: April 10, 2010, 08:26:50 pm »
Try this with that procedure that Gizd mentioned.

Code: (pascal) [Select]
Procedure OnPlayerKill(Killer,Victim:byte;Weapon:byte);
Var S: Byte; Dist: Single; //put variable declarations just after the definition of the procedure, but before the first begin
begin
  if Klasse[Killer] = 'Berserker' then begin
    For S := 1 To 32 Do if GetPlayerStat(S,'Alive') = True Then Begin
      if RayCast(GetPlayerStat(ID,'X'),GetPlayerStat(ID,'Y'),GetPlayerStat(S,'X'),GetPlayerStat(S,'Y'),Dist,800) = True Then Begin
        DoDamageBy(S,Killer,50);
      end;
    end;
  end;
end;
When life hands you High Fructose Corn Syrup, Citric Acid, Ascorbic Acid, Maltodextrin, Sodium Acid Pyrophosphate,
Magnesium Oxide, Calcium Fumarate, Yellow 5, Tocopherol and Less Than 2% Natural Flavour... make Lemonade!

DarkCrusade

  • Guest
Re: Question Thread
« Reply #91 on: April 11, 2010, 01:55:16 am »
I´m using Raycast, because it allows me to ignore vanished players. I will try working with your code, Spilt, thanks :)

EDIT: I screwed DoDamage. It seems not to work right now and I had a way better idea for the Berserker. Players that are in range (5-20 metres) of a player that was killed by a Berserker will get blown up immediatly.

Code: [Select]
Procedure OnPlayerKill(Killer,Victim:byte;Weapon:byte); 
Var S: Byte; Dist,x,y: Single;
begin 
if Klasse[Killer] = 'Berserker' then begin 
For S := 1 To 32 Do if GetPlayerStat(S,'Alive') = True then begin   
x := GetPlayerStat(S,'x');
y := GetPlayerStat(S,'y');
if not Raycast (x,y,x,y -3,Dist,20) then begin
CreateBullet(x,y,1,1,100,4,Killer);
WriteConsole(S,'You have just been blown up!', Color);
end;   
end;   
end; 
end; 

Right now my problem is, that no bullet is created OnPlayerKill. The server compiles and stuff so I don´t have an error log but the console tells me that there is an invalid parameter in my OnPlayerKill function.
« Last Edit: April 11, 2010, 02:30:55 am by DarkCrusade »

Offline Swompie

  • Camper
  • ***
  • Posts: 390
Re: Question Thread
« Reply #92 on: April 11, 2010, 03:52:39 am »
Code: [Select]
Weapon: byte; -> Weapon: string;
DO NOT USE eC's MANUAL, ITS FOR THE NEXT SERVER VERSION NOT FOR THE CURRENT
USE THIS ONE TILL NEXT SERVER VERSION COMES OUT O_O

Sry, but had to uppercase  ;D  Idk if you use it, but it looks like :|

Offline Gizd

  • Flagrunner
  • ****
  • Posts: 586
  • (Re)tired
    • Eat-this! community site
Re: Question Thread
« Reply #93 on: April 11, 2010, 04:02:53 am »
*CAPSLOCK ON*
PROTIP: LEARN TO DO PROPER INDENTATIONS OR YOU WON'T FIND MISSING END'S / BEGIN'S

DarkCrusade

  • Guest
Re: Question Thread
« Reply #94 on: April 11, 2010, 04:06:40 am »
@Gizd: my script has proper indentations. The copy/paste thing made it look bad and so I changed it.

@Swompie: I will take a look at it.

FastEdit: LOL Swompie, I just changed what you mentioned and it compiles perfectly! ;D
SlowEdit: Everything is fine. The script compiles and stuff. But I cannot blow up any players ... I don´t know why it happens but I added more line comments to my script so it´s more readable and I marked the lines where I have this urgent problem. Also I added a command that makes testing easier. Type !bots to add 4 different bots ;)

Script attached.
« Last Edit: April 11, 2010, 05:07:59 am by DarkCrusade »

Offline Swompie

  • Camper
  • ***
  • Posts: 390
Re: Question Thread
« Reply #95 on: April 11, 2010, 05:52:49 am »
Attached the script, drops a cluster on enemys in range of 20m, can cause epic explosion effects when lots of enemys are near you :D Ask when you don't understand sth.

DarkCrusade

  • Guest
Re: Question Thread
« Reply #96 on: April 11, 2010, 07:02:57 am »
Thank you very much, Swomp :) I modifyed the script again and added the Mage class (Berserker is finished). I think I messed some things up but I´m not sure. The Mage is granted one grenade for every kill and gains summoning power that allows him to summon a minion that will spawn on his team. The script doesn´t compile correctly so I guess it has something to do with the message. Here are the important lines:

Variables at the beginning:

Code: [Select]
var  
  Klasse: array[1..32] of string;
  SmnPower: array[1..32] of byte;

Procedure OnPlayerSpeak for sure ;)

Code: [Select]

if LowerCase(Text) = '!mage' then begin
WriteConsole(ID,'#You are now a MAGE!', Color);
WriteConsole(ID,'#You are able to summon a minion when you have maximal', Color);
WriteConsole(ID,'#summoning power (10). You get power for killing enemies.', Color);
WriteConsole(ID,'#For every kill you gain one grenade, too!', Color);
Klasse[ID] := 'Mage';
end;

if LowerCase(Text) = '!summon' then begin
if SmnPower = 10 then begin
GetPlayerStat(ID,'Team');
Command('/addbot' + Team + ' Knife Minion');
WriteConsole(ID,'#You have summoned a minion! He will kill others for you!', Color);
end;
if SmnPower < 10 then begin
WriteConsole(ID,'#Your summoning power is too low to summon the minion.', Color);
end;

The timer for the Mage.

Code: [Select]
Procedure AppOnIdle(Ticks: Integer);    var DC: Byte;        begin
                 for DC := 1 to 32 do if GetPlayerStat(DC,'Alive') = true then begin
if Klasse[DC] = 'Mage' then begin
             if Ticks Mod (60 * 7) = 0 then
ForceWeapon(DC,14,255,0);
  end;
end;

OnPlayerKill procedure:

Code: [Select]
Procedure OnPlayerKill(Killer,Victim:byte;Weapon:string);   
begin
if Klasse[Killer] = 'Mage' then begin
GiveBonus(Killer,4); SmnPower := SmnPower+1;
if SmnPower > 10 then begin
SmnPower := 10;
end;
WriteConsole(Killer,'You got a new grenade!',Color);
WriteConsole(Killer,'Your summoning power is ' + + '/10!',Color)     
end;
end;

Sorry, it´s much code but I don´t know where I failed.

Offline Swompie

  • Camper
  • ***
  • Posts: 390
Re: Question Thread
« Reply #97 on: April 11, 2010, 07:33:01 am »
I think it's better you attach the code when you have a problem/need help in more parts of the script, also easier for me to point out errors faster than copying these pieces of code together :E

Heres the code:
In AppOnIdle Player loops you must always check if a players is active before doing anything else.

OnPlayerSpeak was almost right, but you was missing the variable team there, with that it had been:
Code: [Select]
Team := GetPlayerStat(ID, 'Team');
Command('/setteam' + inttostr(Team) + ' Knife Minion');

But you can save this variable and just use GetPlayerStat() in the Command() function itself, look in the code right now to see what I mean.

Aswell you were missing alot of the [ID] brackets. Added them. The ability of grenades will always give him the maximal amount of grenades, since there are also nade kits on all over the map, I would think about giving the mage a Clusters all 4 or 5 kills.

Code: [Select]
var                       
  Klasse: array[1..32] of string;
  SmnPower: array[1..32] of byte;

procedure OnPlayerSpeak(ID: byte; Text: string);
begin

   if LowerCase(Text) = '!mage' then begin
      WriteConsole(ID,'#You are now a MAGE!', Color);
      WriteConsole(ID,'#You are able to summon a minion when you have maximal', Color);
      WriteConsole(ID,'#summoning power (10). You get power for killing enemies.', Color);
      WriteConsole(ID,'#For every kill you gain one grenade, too!', Color);
      Klasse[ID] := 'Mage';
   end;

   if LowerCase(Text) = '!summon' then
      if SmnPower[ID] >= 10 then begin
        Command('/addbot' + inttostr(GetPlayerStat(ID, 'Team')) + ' Knife Minion');
        WriteConsole(ID, 'You have summoned a minion! He will kill others for you!', Color);
      end else WriteConsole(ID, 'You summoning power is too low to summon the minion.', Color);

end;

Procedure AppOnIdle(Ticks: Integer);
var DC: Byte;
begin                             
  for DC := 1 to 32 do
    if GetPlayerStat(DC, 'Active') = true then
      if GetPlayerStat(DC, 'Alive') = true then
        if Klasse[DC] = 'Mage' then                       
          if Ticks Mod (60 * 7) = 0 then
            ForceWeapon(DC,14,255,0);
end;
var                       
  Klasse: array[1..32] of string;
  SmnPower: array[1..32] of byte;

procedure OnPlayerSpeak(ID: byte; Text: string);
begin

   if LowerCase(Text) = '!mage' then begin
      WriteConsole(ID,'#You are now a MAGE!', Color);
      WriteConsole(ID,'#You are able to summon a minion when you have maximal', Color);
      WriteConsole(ID,'#summoning power (10). You get power for killing enemies.', Color);
      WriteConsole(ID,'#For every kill you gain one grenade, too!', Color);
      Klasse[ID] := 'Mage';
   end;

   if LowerCase(Text) = '!summon' then
      if SmnPower[ID] >= 10 then begin
        Command('/addbot' + inttostr(GetPlayerStat(ID, 'Team')) + ' Knife Minion');
        WriteConsole(ID, 'You have summoned a minion! He will kill others for you!', Color);
      end else WriteConsole(ID, 'You summoning power is too low to summon the minion.', Color);

end;

Procedure AppOnIdle(Ticks: Integer);
var DC: Byte;
begin                             
  for DC := 1 to 32 do
    if GetPlayerStat(DC, 'Active') = true then
      if GetPlayerStat(DC, 'Alive') = true then
        if Klasse[DC] = 'Mage' then                       
          if Ticks Mod (60 * 7) = 0 then
            ForceWeapon(DC,14,255,0);
end;

Procedure OnPlayerKill(Killer,Victim:byte;Weapon:string);   
begin
  if Klasse[Killer] = 'Mage' then begin
    GiveBonus(Killer, 4);
    SmnPower[Killing] := SmnPower[Killer] + 1;

    if SmnPower > 10 then
      SmnPower := 10;

    WriteConsole(Killer, 'You got a new grenade!', Color);           
    WriteConsole(Killer, 'Your summoning power is ' + inttostr(SmnPower[Killer]) + '/10!', Color)     
  end;
end;
Not tested, but should work.

Oh, and a side note: remove these #, they're looking annoying ingame ;)
I will later give you a fancy procedure which creates a box around your text.

Also find try to find your indent style for soldat, I use 2-space-steps, works & looks good, alot of people also use TAB, but I think it's too much space. It's your decision  [fist]

DarkCrusade

  • Guest
Re: Question Thread
« Reply #98 on: April 11, 2010, 08:36:41 am »
This returns me the error "Type Mismatch" ...

Code: [Select]
if  smnPower > 10 then
    SmnPower := 10;

... too bad :) Thanks for your advice ;)

Offline Swompie

  • Camper
  • ***
  • Posts: 390
Re: Question Thread
« Reply #99 on: April 11, 2010, 09:04:28 am »
Hint: Look at the variables you declared at the beginning, then this should be solved :]