Add FastForward/StopFastForward (/ff hh:mm:ss, /sff) chat commands to fast forward to a specific timestamp in a demo
authorS.D.
Fri, 23 Sep 2022 02:21:21 +0300
changeset 15875 d7b53d08ad9c
parent 15872 c09063ea0267
child 15876 1878d95d6e15
Add FastForward/StopFastForward (/ff hh:mm:ss, /sff) chat commands to fast forward to a specific timestamp in a demo
hedgewars/uChat.pas
hedgewars/uCommandHandlers.pas
hedgewars/uGame.pas
hedgewars/uGears.pas
hedgewars/uUtils.pas
hedgewars/uVariables.pas
hedgewars/uVisualGearsList.pas
--- 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