Add FastForward/StopFastForward (/ff hh:mm:ss, /sff) chat commands to fast forward to a specific timestamp in a demo
--- a/hedgewars/uChat.pas Wed Sep 21 06:55:31 2022 +0300
+++ b/hedgewars/uChat.pas Fri Sep 23 02:21:21 2022 +0300
@@ -633,6 +633,18 @@
exit
end;
+ if (copy(s, 2, 3) = 'ff ') then
+ begin
+ ParseCommand(s, true);
+ exit
+ end;
+
+ if (copy(s, 2, 3) = 'sff') then
+ begin
+ ParseCommand(s, true);
+ exit
+ end;
+
// debugging commands
if (copy(s, 2, 7) = 'debugvl') then
// This command intentionally not documented in /help
--- a/hedgewars/uCommandHandlers.pas Wed Sep 21 06:55:31 2022 +0300
+++ b/hedgewars/uCommandHandlers.pas Fri Sep 23 02:21:21 2022 +0300
@@ -885,6 +885,7 @@
procedure chFastUntilLag(var s: shortstring);
begin
fastUntilLag:= StrToInt(s) <> 0;
+ fastForward:= fastUntilLag;
if not fastUntilLag then
begin
@@ -894,6 +895,53 @@
end
end;
+procedure chFastForward(var cmd: shortstring);
+var str0, str1, str2 : shortstring;
+ h, m, s : integer;
+begin
+ if gameType <> gmtDemo then
+ exit;
+ if CountChar(cmd, ':') > 2 then
+ exit;
+ str0:= cmd;
+ SplitByChar(str0, str1, ':');
+ SplitByChar(str1, str2, ':');
+ if str2 <> '' then
+ begin
+ h:= StrToInt(str0);
+ m:= StrToInt(str1);
+ s:= StrToInt(str2)
+ end
+ else if str1 <> '' then
+ begin
+ h:= 0;
+ m:= StrToInt(str0);
+ s:= StrToInt(str1)
+ end
+ else
+ begin
+ h:= 0;
+ m:= 0;
+ s:= StrToInt(str0)
+ end;
+ FFGameTick:= (s + m * 60 + h * 60 * 60) * 1000;
+ if FFGameTick > GameTicks then
+ begin
+ fastUntilLag:= True;
+ fastForward:= True;
+ end
+end;
+
+procedure chStopFastForward(var s: shortstring);
+begin
+ if gameType <> gmtDemo then
+ exit;
+ fastUntilLag:= False;
+ fastForward:= False;
+ AddVisualGear(0, 0, vgtTeamHealthSorter);
+ AddVisualGear(0, 0, vgtSmoothWindBar)
+end;
+
procedure chCampVar(var s:shortstring);
begin
CampaignVariable := s;
@@ -1026,6 +1074,8 @@
RegisterVariable('record' , @chRecord , true );
RegisterVariable('worldedge',@chWorldEdge , false);
RegisterVariable('advmapgen',@chAdvancedMapGenMode, false);
+ RegisterVariable('ff' , @chFastForward , true);
+ RegisterVariable('sff' , @chStopFastForward, true);
RegisterVariable('+mission', @chShowMission_p, true);
RegisterVariable('-mission', @chShowMission_m, true);
RegisterVariable('gearinfo', @chGearInfo , true );
--- a/hedgewars/uGame.pas Wed Sep 21 06:55:31 2022 +0300
+++ b/hedgewars/uGame.pas Fri Sep 23 02:21:21 2022 +0300
@@ -81,7 +81,7 @@
begin
if Lag > 100 then
Lag:= 100
- else if (GameType = gmtSave) or (fastUntilLag and (GameType = gmtNet)) then
+ else if (GameType = gmtSave) or (fastUntilLag and (GameType = gmtNet)) or fastForward then
Lag:= 2500;
if (GameType = gmtDemo) then
--- a/hedgewars/uGears.pas Wed Sep 21 06:55:31 2022 +0300
+++ b/hedgewars/uGears.pas Fri Sep 23 02:21:21 2022 +0300
@@ -628,6 +628,8 @@
inc(GameTicks);
if (OuchTauntTimer > 0) then
dec(OuchTauntTimer);
+if fastForward and (GameTicks = FFGameTick) then
+ ParseCommand('sff', true);
end;
//Purpose, to reset all transient attributes toggled by a utility and clean up various gears and effects at end of turn
--- a/hedgewars/uUtils.pas Wed Sep 21 06:55:31 2022 +0300
+++ b/hedgewars/uUtils.pas Fri Sep 23 02:21:21 2022 +0300
@@ -26,6 +26,7 @@
// returns s with whitespaces (chars <= #32) removed form both ends
function Trim(s: shortstring) : shortstring;
+function CountChar(s : shortstring; c: char) : LongInt;
procedure SplitBySpace(var a, b: shortstring);
procedure SplitByChar(var a, b: shortstring; c: char);
procedure SplitByCharA(var a, b: ansistring; c: char);
@@ -218,6 +219,18 @@
ExtractFilename:= copy(s, lslash + 1, len);
end;
+function CountChar(s : shortstring; c: char): LongInt;
+var i, res : LongInt;
+begin
+ res:= 0;
+ for i:= 1 to Length(s) do
+ begin
+ if s[i] = c then
+ Inc(res)
+ end;
+ CountChar:= res
+end;
+
procedure SplitBySpace(var a,b: shortstring);
begin
SplitByChar(a,b,' ');
--- a/hedgewars/uVariables.pas Wed Sep 21 06:55:31 2022 +0300
+++ b/hedgewars/uVariables.pas Fri Sep 23 02:21:21 2022 +0300
@@ -86,6 +86,7 @@
SpeedStart : LongWord;
fastUntilLag : boolean;
+ fastForward : boolean;
fastScrolling : boolean;
autoCameraOn : boolean;
@@ -93,6 +94,7 @@
CampaignVariable: shortstring;
MissionVariable : shortstring;
GameTicks : LongWord;
+ FFGameTick : LongWord;
OuchTauntTimer : LongWord; // Timer which blocks sndOuch from being played too often and fast
GameState : TGameState;
GameType : TGameType;
@@ -2930,6 +2932,7 @@
CursorMovementX := 0;
CursorMovementY := 0;
GameTicks := 0;
+ FFGameTick := 0;
OuchTauntTimer := 0;
CheckSum := 0;
cWaterLine := LAND_HEIGHT;
@@ -3008,6 +3011,7 @@
isForceMission := false;
SpeedStart := 0;
fastUntilLag := false;
+ fastForward := false;
fastScrolling := false;
autoCameraOn := true;
cSeed := '';
--- a/hedgewars/uVisualGearsList.pas Wed Sep 21 06:55:31 2022 +0300
+++ b/hedgewars/uVisualGearsList.pas Fri Sep 23 02:21:21 2022 +0300
@@ -64,6 +64,8 @@
sp: real;
begin
AddVisualGear:= nil;
+if fastUntilLag and (not Critical) then
+ exit;
if (GameType <> gmtRecord) and
(((GameType = gmtSave) or (fastUntilLag and (GameType = gmtNet)) or fastScrolling) and // we are scrolling now
(not Critical)) then