MantisBT - Soldat Dedicated Server
View Issue Details
0000008Soldat Dedicated ServerScripting Corepublic2011-09-13 19:262012-06-23 20:28
fri 
Falcon 
normalmajoralways
closednot fixable 
2.7.0 
 
0000008: Incorrect byte subtraction
Bytes subtraction used to work differently on 2.6.5 than it does now.

When using formulas like this (result: integer):
result := (AlphaPlayers-BravoPlayers)*Weight + AlphaScore - BravoScore;
on AlphaPlayers = 0, BravoPlayers = 6, AlphaScore = 0, BravoScore = 8
2.6.5 returned "normal" result, while 2.7.0 goes out of range and returns something about 240 (it depends on Weight, but the issue is in inconsistency between 2.6.5 and 2.7.0).
It can be fixed by using temporary integer values (in this case, for AlphaPlayers and AlphaScore).
No tags attached.
Issue History
2011-09-13 19:26friNew Issue
2011-09-13 19:26friStatusnew => assigned
2011-09-13 19:26friAssigned To => EnEsCe
2011-09-13 20:13ShoozzaAssigned ToEnEsCe =>
2011-09-13 20:14ShoozzaStatusassigned => new
2011-09-21 02:55ShoozzaNote Added: 0001151
2011-09-21 02:55ShoozzaStatusnew => feedback
2011-09-21 12:00friNote Added: 0001152
2011-09-21 12:00friStatusfeedback => new
2011-09-21 12:11friNote Edited: 0001152bug_revision_view_page.php?bugnote_id=1152#r60
2011-09-21 16:56QuantifierNote Added: 0001154
2012-03-02 16:35ShoozzaStatusnew => acknowledged
2012-06-23 20:28FalconNote Added: 0001560
2012-06-23 20:28FalconStatusacknowledged => closed
2012-06-23 20:28FalconAssigned To => Falcon
2012-06-23 20:28FalconResolutionopen => not fixable

Notes
(0001151)
Shoozza   
2011-09-21 02:55   
Does this happen for linux and windows soldat dedicated servers?
Could you provide a ready to run script which tests the correct results (one with runs with uses the temp vars and tests them against the version with has no temp vars)?
(0001152)
fri   
2011-09-21 12:00   
(edited on: 2011-09-21 12:11)
I tested it on Windows, but I think it would be the same on Linux. Servers that ran previous versions of my script acted weird because of this issue; I think those ran on Linux.
Anyway, I made a script and noticed that it not only returns different result on 2.6.5 and 2.7.0, but on both servers AlphaScore returns 0, even though I set it to 1 point.



Script (first two screenshots):

function OnPlayerCommand(id: byte; text: string): boolean;
var i: byte;
begin
  if (lowercase(text) = '/test') then begin
    command('/pause');
    command('/setteam1 ' + inttostr(id));
    for i := 1 to 5 do command('/addbot2 Boogie Man');
    setteamscore(1, 1);
    setteamscore(2, 8);
    writeconsole(id, 'Alpha Players: ' + inttostr(AlphaPlayers), $FFFFAAAA);
    writeconsole(id, 'Bravo Players: ' + inttostr(BravoPlayers), $FFAAAAFF);
    writeconsole(id, 'Alpha Score: ' + inttostr(AlphaScore), $FFAAFFAA);
    writeconsole(id, 'Bravo Score: ' + inttostr(BravoScore), $FFAAFFAA);
    writeconsole(id, '-----------------------', $FF000000);
    writeconsole(id, 'AP - BP + AS - BS = ' + inttostr(AlphaPlayers-BravoPlayers+AlphaScore-BravoScore), $FFFFFFFF);
  end;
  result := false;
end;



Script (the third screenshot):

function OnPlayerCommand(id: byte; text: string): boolean;
var i: byte;
    intAlphaPlayers, intAlphaScore: integer;
begin
  if (lowercase(text) = '/test') then begin
    command('/pause');
    command('/setteam1 ' + inttostr(id));
    for i := 1 to 5 do command('/addbot2 Boogie Man');
    setteamscore(1, 1);
    setteamscore(2, 8);
    writeconsole(id, 'Alpha Players: ' + inttostr(AlphaPlayers), $FFFFAAAA);
    writeconsole(id, 'Bravo Players: ' + inttostr(BravoPlayers), $FFAAAAFF);
    writeconsole(id, 'Alpha Score: ' + inttostr(AlphaScore), $FFAAFFAA);
    writeconsole(id, 'Bravo Score: ' + inttostr(BravoScore), $FFAAFFAA);
    writeconsole(id, '-----------------------', $FF000000);
    writeconsole(id, 'AP - BP + AS - BS = ' + inttostr(AlphaPlayers-BravoPlayers+AlphaScore-BravoScore), $FFFFFFFF);
    intAlphaPlayers := AlphaPlayers;
    intAlphaScore := AlphaScore;
    writeconsole(id, 'intAP - BP + intAS - BS = ' + inttostr(intAlphaPlayers-BravoPlayers+intAlphaScore-BravoScore), $FFFFFFFF);
    writeconsole(id, 'AP - BP + intAS - BS = ' + inttostr(AlphaPlayers-BravoPlayers+intAlphaScore-BravoScore), $FFFFFFFF);
    writeconsole(id, 'intAP - BP + AS - BS = ' + inttostr(intAlphaPlayers-BravoPlayers+AlphaScore-BravoScore), $FFFFFFFF);
  end;
  result := false;
end;



Screenshots:
http://tehoko.info/paste/2011-09/server265.jpg [^] (correct result)
http://tehoko.info/paste/2011-09/server270.jpg [^] (incorrect result)
http://tehoko.info/paste/2011-09/server270comp.png [^] (comparison with all combinations of intAlphaPlayers and intAlphaScore)

There are 10 bots, because SetTeamScore is rather slow and I had to reuse the /test command to make it register the new score values - so five bots were added twice. As you can see, there's a difference in result and AlphaScore returns 0, while it shouldn't. Also, only the first one needs to be converted to integer. Looks like the first used variable defines the type of the result.

(0001154)
Quantifier   
2011-09-21 16:56   
If AlphaPlayers and BravoPlayers are defined as Byte (an unsigned type), then subtracting one from another will obviously overflow the range. Using temporary signed variables is the right way here.
(0001560)
Falcon   
2012-06-23 20:28   
I'm pretty sure that i've had this problems in 2.6.5 as well. Even if not, this bug is strongly dependant on compiler and pascal script version we use, thus not fixable.