Add SetTeamPassive. Passive teams are treated like frozen teams
authorWuzzy <Wuzzy2@mail.ru>
Wed, 16 Jan 2019 15:40:11 +0100
changeset 14611 3cf7799e04b5
parent 14610 de34abf040ed
child 14612 bd15c8551318
Add SetTeamPassive. Passive teams are treated like frozen teams
ChangeLog.txt
hedgewars/uScript.pas
hedgewars/uStats.pas
hedgewars/uTeams.pas
hedgewars/uTypes.pas
--- a/ChangeLog.txt	Wed Jan 16 07:30:06 2019 +0100
+++ b/ChangeLog.txt	Wed Jan 16 15:40:11 2019 +0100
@@ -73,6 +73,7 @@
  + New call: GetTurnTimePaused(): Returns true if turn time is paused due to Lua
  + New call: AddMissionTeam(color): Add mission team, i.e. the team selected by player in campaign/mission page
  + New call: AddMissionHog(health): Add a hedgehog for the mission team
+ + New call: SetTeamPassive(teamname, isPassive): Mark a team as passive. Passive teams do not play and are treated like frozen teams.
  + New return value: AddTeam/AddMissionTeam return <real team name>, <team index>
  + Utils library: New calls: getReadableChallengeRecord, updateChallengeRecord
  + New callback: onGameResult(winningClan): Called when the game ends normally. winningClan = index of winning clan or -1 on draw
--- a/hedgewars/uScript.pas	Wed Jan 16 07:30:06 2019 +0100
+++ b/hedgewars/uScript.pas	Wed Jan 16 15:40:11 2019 +0100
@@ -2409,6 +2409,46 @@
     lc_setteamlabel:= 1;
 end;
 
+function lc_setteampassive(L : Plua_State) : LongInt; Cdecl;
+var i, j: LongInt;
+    success, passive, passiveClan: boolean;
+begin
+	success:= false;
+    if CheckLuaParamCount(L, 2, 'SetTeamPassive', 'teamname, isPassive') then
+        begin
+        success:= false;
+        // fetch team
+        if TeamsCount > 0 then
+            for i:= 0 to Pred(TeamsCount) do
+                if TeamsArray[i]^.TeamName = lua_tostring(L, 1) then
+                    begin
+                    passive:= lua_toboolean(L, 2);
+                    TeamsArray[i]^.Passive:= passive;
+                    // also update clan state
+                    if passive then
+                        begin
+                        passiveClan:= true;
+                        for j:= 0 to Pred(TeamsCount) do
+                            if (not TeamsArray[j]^.Passive) then
+                                begin
+                                passiveClan:= false;
+                                break;
+                                end;
+                        end
+                    else
+                        passiveClan:= false;
+                    TeamsArray[i]^.Clan^.Passive:= passiveClan;
+
+                    success:= true;
+                    // don't change more than one team
+                    break;
+                    end;
+        end;
+    // return true if operation was successful, false otherwise
+    lua_pushboolean(L, success);
+    lc_setteampassive:= 1;
+end;
+
 function lc_getteamname(L : Plua_State) : LongInt; Cdecl;
 var t: LongInt;
 begin
@@ -4377,6 +4417,7 @@
 lua_register(luaState, _P'AddTeam', @lc_addteam);
 lua_register(luaState, _P'AddMissionTeam', @lc_addmissionteam);
 lua_register(luaState, _P'SetTeamLabel', @lc_setteamlabel);
+lua_register(luaState, _P'SetTeamPassive', @lc_setteampassive);
 lua_register(luaState, _P'AddHog', @lc_addhog);
 lua_register(luaState, _P'AddMissionHog', @lc_addmissionhog);
 lua_register(luaState, _P'AddAmmo', @lc_addammo);
--- a/hedgewars/uStats.pas	Wed Jan 16 07:30:06 2019 +0100
+++ b/hedgewars/uStats.pas	Wed Jan 16 15:40:11 2019 +0100
@@ -480,7 +480,7 @@
 
             { Send player stats for winner clans/teams.
             The clan that survived is ranked 1st. }
-            if Clan^.ClanHealth > 0 then
+            if (Clan^.ClanHealth > 0) and (not Clan^.Passive) then
                 begin
                 winnersClan:= Clan;
                 if SendRankingStatsOn then
@@ -532,7 +532,7 @@
                 if ((deathEntry^.KilledClans[c]^.ClanHealth) = 0) and (not deathEntry^.KilledClans[c]^.StatsHandled) then
                     begin
                     for t:= 0 to Pred(TeamsCount) do
-                        if TeamsArray[t]^.Clan^.ClanIndex = deathEntry^.KilledClans[c]^.ClanIndex then
+                        if (TeamsArray[t]^.Clan^.ClanIndex = deathEntry^.KilledClans[c]^.ClanIndex) and (not TeamsArray[t]^.Passive) then
                             begin
                             SendStat(siTeamRank, IntToStr(currentRank));
                             SendStat(siPlayerKills, IntToStr(deathEntry^.killedClans[c]^.Color) + ' ' +
--- a/hedgewars/uTeams.pas	Wed Jan 16 07:30:06 2019 +0100
+++ b/hedgewars/uTeams.pas	Wed Jan 16 15:40:11 2019 +0100
@@ -58,19 +58,21 @@
 var AliveClan: PClan;
     s, cap: ansistring;
     ts: array[0..(cMaxTeams - 1)] of ansistring;
-    t, AliveCount, i, j: LongInt;
+    t, ActiveAliveCount, i, j: LongInt;
     allWin, winCamera: boolean;
 begin
 CheckForWin:= false;
-AliveCount:= 0;
+ActiveAliveCount:= 0;
+// Victory if there is 1 living and non-passive clan left
 for t:= 0 to Pred(ClansCount) do
-    if ClansArray[t]^.ClanHealth > 0 then
+    if (ClansArray[t]^.ClanHealth > 0) and (not ClansArray[t]^.Passive) then
         begin
-        inc(AliveCount);
+        inc(ActiveAliveCount);
         AliveClan:= ClansArray[t]
         end;
 
-if (AliveCount > 1) or ((AliveCount = 1) and ((GameFlags and gfOneClanMode) <> 0)) then
+// Exception: gfOneClanMode, then there is no winner
+if (ActiveAliveCount > 1) or ((ActiveAliveCount = 1) and ((GameFlags and gfOneClanMode) <> 0)) then
     exit;
 CheckForWin:= true;
 
@@ -89,7 +91,7 @@
 
 if not TeamsGameOver then
     begin
-    if AliveCount = 0 then
+    if ActiveAliveCount = 0 then
         begin // draw
         AddCaption(GetEventString(eidRoundDraw), capcolDefault, capgrpGameState);
         if SendGameResultOn then
@@ -278,15 +280,16 @@
             CurrTeam:= Succ(CurrTeam) mod TeamsNumber;
             CurrentTeam:= Teams[CurrTeam];
             with CurrentTeam^ do
-                begin
-                PrevHH:= CurrHedgehog mod HedgehogsNumber; // prevent infinite loop when CurrHedgehog = 7, but HedgehogsNumber < 8 (team is destroyed before its first turn)
-                repeat
-                    CurrHedgehog:= Succ(CurrHedgehog) mod HedgehogsNumber;
-                until ((Hedgehogs[CurrHedgehog].Gear <> nil) and (Hedgehogs[CurrHedgehog].Effects[heFrozen] < 256)) or (CurrHedgehog = PrevHH)
-                end
-        until ((CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Effects[heFrozen] < 256)) or (PrevTeam = CurrTeam) or ((CurrTeam = TagTeamIndex) and ((GameFlags and gfTagTeam) <> 0))
+                if (not Passive) then
+                    begin
+                    PrevHH:= CurrHedgehog mod HedgehogsNumber; // prevent infinite loop when CurrHedgehog = 7, but HedgehogsNumber < 8 (team is destroyed before its first turn)
+                    repeat
+                        CurrHedgehog:= Succ(CurrHedgehog) mod HedgehogsNumber;
+                    until ((Hedgehogs[CurrHedgehog].Gear <> nil) and (Hedgehogs[CurrHedgehog].Effects[heFrozen] < 256)) or (CurrHedgehog = PrevHH)
+                    end
+        until ((not CurrentTeam^.Passive) and (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Effects[heFrozen] < 256)) or (PrevTeam = CurrTeam) or ((CurrTeam = TagTeamIndex) and ((GameFlags and gfTagTeam) <> 0))
         end;
-        if (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear = nil) or (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Effects[heFrozen] > 255) then
+        if (CurrentTeam^.Passive) or (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear = nil) or (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Effects[heFrozen] > 255) then
             begin
             with CurrentTeam^.Clan^ do
                 for t:= 0 to Pred(TeamsNumber) do
@@ -298,10 +301,10 @@
                                 if (Gear <> nil) and (Effects[heFrozen] < 256) and (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Effects[heFrozen] > 255) then
                                     CurrHedgehog:= i
                                 end;
-            if (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear = nil) or (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Effects[heFrozen] > 255) then
+            if (not CurrentTeam^.Passive) and ((CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear = nil) or (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Effects[heFrozen] > 255)) then
                 inc(CurrentTeam^.Clan^.TurnNumber);
-            end
-until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Effects[heFrozen] < 256);
+            end;
+until (not CurrentTeam^.Passive) and (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Effects[heFrozen] < 256);
 
 SwitchCurrentHedgehog(@(CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]));
 {$IFDEF USE_TOUCH_INTERFACE}
@@ -508,6 +511,7 @@
 inc(VisibleTeamsCount);
 
 team^.Binds:= DefaultBinds;
+team^.Passive:= false;
 
 c:= Pred(ClansCount);
 while (c >= 0) and (ClansArray[c]^.Color <> TeamColor) do dec(c);
@@ -535,6 +539,7 @@
 with team^.Clan^ do
     begin
     Teams[TeamsNumber]:= team;
+    Passive:= false;
     inc(TeamsNumber)
     end;
 
--- a/hedgewars/uTypes.pas	Wed Jan 16 07:30:06 2019 +0100
+++ b/hedgewars/uTypes.pas	Wed Jan 16 15:40:11 2019 +0100
@@ -446,6 +446,8 @@
             voicepack: PVoicepack;
             PlayerHash: shortstring;   // md5 hash of player name. For temporary enabling of hats as thank you. Hashed for privacy of players
             stats: TTeamStats;
+            Passive: boolean; // if true, team will not participate in game. It is treated as if all its hedgehogs are frozen.
+                              // updating this value requires updating Passive in TClan as well!
             hasKing: boolean; // true if team has a living king
             hasGone: boolean;
             skippedTurns: Longword;
@@ -467,6 +469,7 @@
             DeathLogged: boolean; // true if clan is dead and its latest death has been logged in the clan death log
             StatsHandled : boolean; // true if clan's rank has been handled for stats screen
             Flawless: boolean;
+            Passive: boolean; // informational. Must be set to true if all of the teams are passive
             end;
 
      cdeclPtr = procedure; cdecl;