hedgewars/uTeams.pas
branchsdl2transition
changeset 11362 ed5a6478e710
parent 11178 7b2b181f84f8
child 11471 458d90012c22
--- a/hedgewars/uTeams.pas	Tue Nov 10 18:16:35 2015 +0100
+++ b/hedgewars/uTeams.pas	Tue Nov 10 20:43:13 2015 +0100
@@ -1,6 +1,6 @@
  (*
  * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com>
+ * Copyright (c) 2004-2015 Andrey Korotaev <unC0Rr@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -13,14 +13,14 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *)
 
 {$INCLUDE "options.inc"}
 
 unit uTeams;
 interface
-uses uConsts, uInputHandler, uRandom, uFloat, uStats, 
+uses uConsts, uInputHandler, uRandom, uFloat, uStats,
      uCollisions, uSound, uStore, uTypes, uScript
      {$IFDEF USE_TOUCH_INTERFACE}, uWorld{$ENDIF};
 
@@ -34,6 +34,7 @@
 procedure InitTeams;
 function  TeamSize(p: PTeam): Longword;
 procedure RecountTeamHealth(team: PTeam);
+procedure RecountAllTeamsHealth();
 procedure RestoreHog(HH: PHedgehog);
 
 procedure RestoreTeamsFromSave;
@@ -53,7 +54,7 @@
 
 function CheckForWin: boolean;
 var AliveClan: PClan;
-    s: shortstring;
+    s, ts: ansistring;
     t, AliveCount, i, j: LongInt;
 begin
 CheckForWin:= false;
@@ -81,16 +82,17 @@
     if AliveCount = 0 then
         begin // draw
         AddCaption(trmsg[sidDraw], cWhiteColor, capgrpGameState);
-        SendStat(siGameResult, trmsg[sidDraw]);
+        SendStat(siGameResult, shortstring(trmsg[sidDraw]));
         AddGear(0, 0, gtATFinishGame, 0, _0, _0, 3000)
         end
     else // win
         with AliveClan^ do
             begin
+            ts:= ansistring(Teams[0]^.TeamName);
             if TeamsNumber = 1 then
-                s:= Format(shortstring(trmsg[sidWinner]), Teams[0]^.TeamName)  // team wins
+                s:= FormatA(trmsg[sidWinner], ts)  // team wins
             else
-                s:= Format(shortstring(trmsg[sidWinner]), Teams[0]^.TeamName); // clan wins
+                s:= FormatA(trmsg[sidWinner], ts); // clan wins
 
             for j:= 0 to Pred(TeamsNumber) do
                 with Teams[j]^ do
@@ -104,7 +106,7 @@
                 AddVoice(sndVictory, Teams[0]^.voicepack);
 
             AddCaption(s, cWhiteColor, capgrpGameState);
-            SendStat(siGameResult, s);
+            SendStat(siGameResult, shortstring(s));
             AddGear(0, 0, gtATFinishGame, 0, _0, _0, 3000)
             end;
     SendStats;
@@ -155,7 +157,7 @@
             if c > cMaxHHIndex then
                 c:= 0
             end
-        until (c = CurrHedgehog) or (Hedgehogs[c].Gear <> nil);
+        until (c = CurrHedgehog) or (Hedgehogs[c].Gear <> nil) and (Hedgehogs[c].Effects[heFrozen] < 50255);
         LocalAmmo:= Hedgehogs[c].AmmoStore
         end;
 
@@ -237,7 +239,7 @@
     CurWeapon: PAmmo;
     w: real;
     vg: PVisualGear;
-
+    s: ansistring;
 begin
 if PlacingHogs then
     begin
@@ -334,7 +336,8 @@
         end;
     if cHedgehogTurnTime < 1000000 then
         ReadyTimeLeft:= cReadyDelay;
-    AddCaption(Format(shortstring(trmsg[sidReady]), CurrentTeam^.TeamName), cWhiteColor, capgrpGameState)
+    s:= ansistring(CurrentTeam^.TeamName);
+    AddCaption(FormatA(trmsg[sidReady], s), cWhiteColor, capgrpGameState)
     end
 else
     begin
@@ -514,20 +517,31 @@
 procedure TeamGoneEffect(var Team: TTeam);
 var i: LongInt;
 begin
-with Team do
-    for i:= 0 to cMaxHHIndex do
-        with Hedgehogs[i] do
+    with Team do
+        if skippedTurns < 3 then
             begin
-            if Hedgehogs[i].GearHidden <> nil then
-                RestoreHog(@Hedgehogs[i]);
+            inc(skippedTurns);
+            for i:= 0 to cMaxHHIndex do
+                with Hedgehogs[i] do
+                    if Gear <> nil then
+                        Gear^.State:= Gear^.State and (not gstHHDriven);
 
-            if Gear <> nil then
-                begin
-                Gear^.Hedgehog^.Effects[heInvulnerable]:= 0;
-                Gear^.Damage:= Gear^.Health;
-                Gear^.State:= (Gear^.State or gstHHGone) and (not gstHHDriven)
-                end
+            ParseCommand('/skip', true);
             end
+        else
+            for i:= 0 to cMaxHHIndex do
+                with Hedgehogs[i] do
+                    begin
+                    if Hedgehogs[i].GearHidden <> nil then
+                        RestoreHog(@Hedgehogs[i]);
+
+                    if Gear <> nil then
+                        begin
+                        Gear^.Hedgehog^.Effects[heInvulnerable]:= 0;
+                        Gear^.Damage:= Gear^.Health;
+                        Gear^.State:= (Gear^.State or gstHHGone) and (not gstHHDriven)
+                        end
+                    end
 end;
 
 procedure chAddHH(var id: shortstring);
@@ -535,10 +549,12 @@
     Gear: PGear;
 begin
 s:= '';
-if (not isDeveloperMode) or (CurrentTeam = nil) then
+if (not isDeveloperMode) then
     exit;
+TryDo((CurrentTeam <> nil), 'Can''t add hedgehogs yet, add a team first!', true);
 with CurrentTeam^ do
     begin
+    TryDo(HedgehogsNumber<=cMaxHHIndex, 'Can''t add hedgehog to "' + TeamName + '"! (already ' + intToStr(HedgehogsNumber) + ' hogs)', true);
     SplitBySpace(id, s);
     SwitchCurrentHedgehog(@Hedgehogs[HedgehogsNumber]);
     CurrentHedgehog^.BotLevel:= StrToInt(id);
@@ -567,7 +583,10 @@
 var i: LongInt;
 begin
     for i:= 1 to length(s) do
-        if s[i] in ['\', '/', ':'] then s[i]:= '_';
+        if ((s[i] = '\') or
+            (s[i] = '/') or
+            (s[i] = ':')) then
+            s[i]:= '_';
 
     s:= cPathz[ptTeams] + '/' + s + '.hwt';
 
@@ -585,7 +604,6 @@
     SplitBySpace(s, cs);
     SplitBySpace(cs, ts);
     Color:= StrToInt(cs);
-    TryDo(Color <> 0, 'Error: black team color', true);
 
     // color is always little endian so the mask must be constant also in big endian archs
     Color:= Color or $FF000000;
@@ -593,7 +611,7 @@
     CurrentTeam^.TeamName:= ts;
     CurrentTeam^.PlayerHash:= s;
     loadTeamBinds(ts);
-    
+
     if GameType in [gmtDemo, gmtSave, gmtRecord] then
         CurrentTeam^.ExtDriven:= true;
 
@@ -624,21 +642,85 @@
 end;
 
 procedure chTeamGone(var s:shortstring);
-var t: LongInt;
+var t, i: LongInt;
+    isSynced: boolean;
 begin
-t:= 0;
-while (t < cMaxTeams) and (TeamsArray[t] <> nil) and (TeamsArray[t]^.TeamName <> s) do
-    inc(t);
-if (t = cMaxTeams) or (TeamsArray[t] = nil) then
-    exit;
+    isSynced:= s[1] = 's';
+
+    Delete(s, 1, 1);
+
+    t:= 0;
+    while (t < TeamsCount) and (TeamsArray[t]^.TeamName <> s) do
+        inc(t);
+    if t = TeamsCount then
+        exit;
+
+    TeamsArray[t]^.isGoneFlagPendingToBeSet:= true;
+
+    if isSynced then
+        begin
+        for i:= 0 to Pred(TeamsCount) do
+            with TeamsArray[i]^ do
+                begin
+                if (not hasGone) and isGoneFlagPendingToBeSet then
+                    begin
+                    AddChatString(#7 + '* '+ TeamName + ' is gone'); // TODO: localize
+                    if not CurrentTeam^.ExtDriven then SendIPC(_S'f' + s);
+                    hasGone:= true;
+                    skippedTurns:= 0;
+                    isGoneFlagPendingToBeSet:= false;
+                    RecountTeamHealth(TeamsArray[i])
+                    end;
+                if hasGone and isGoneFlagPendingToBeUnset then
+                    ParseCommand('/teamback s' + s, true)
+                end
+        end
+    else
+        begin
+        //TeamsArray[t]^.isGoneFlagPendingToBeSet:= true;
 
-with TeamsArray[t]^ do
-    if not hasGone then
+        if (not CurrentTeam^.ExtDriven) or (CurrentTeam^.TeamName = s) or (CurrentTeam^.hasGone) then
+            ParseCommand('/teamgone s' + s, true)
+        end;
+end;
+
+procedure chTeamBack(var s:shortstring);
+var t: LongInt;
+    isSynced: boolean;
+begin
+    isSynced:= s[1] = 's';
+
+    Delete(s, 1, 1);
+
+    t:= 0;
+    while (t < TeamsCount) and (TeamsArray[t]^.TeamName <> s) do
+        inc(t);
+    if t = TeamsCount then
+        exit;
+
+    if isSynced then
         begin
-        AddChatString('** '+ TeamName + ' is gone');
-        hasGone:= true;
+        with TeamsArray[t]^ do
+            if hasGone then
+                begin
+                AddChatString(#8 + '* '+ TeamName + ' is back');
+                if not CurrentTeam^.ExtDriven then SendIPC(_S'g' + s);
+                hasGone:= false;
+
+                RecountTeamHealth(TeamsArray[t]);
 
-        RecountTeamHealth(TeamsArray[t])
+                if isGoneFlagPendingToBeUnset and (Owner = UserNick) then
+                    ExtDriven:= false;
+
+                isGoneFlagPendingToBeUnset:= false;
+                end;
+        end
+    else
+        begin
+        TeamsArray[t]^.isGoneFlagPendingToBeUnset:= true;
+
+        if not CurrentTeam^.ExtDriven then
+            ParseCommand('/teamback s' + s, true);
         end;
 end;
 
@@ -649,14 +731,16 @@
 // avoid compiler hint
 s:= s;
 
+isPaused:= false;
+
 t:= 0;
-while (t < cMaxTeams) and (TeamsArray[t] <> nil) do
+while t < TeamsCount do
     begin
     TeamsArray[t]^.hasGone:= true;
-    inc(t);
+    inc(t)
     end;
 
-AddChatString('** Good-bye!');
+AddChatString(#7 + '* Good-bye!');
 RecountAllTeamsHealth();
 end;
 
@@ -672,8 +756,6 @@
     if newCI then DeleteCI(newHog^.Gear);
     oldHH:= CurrentHedgehog;
     CurrentHedgehog:= newHog;
-   if (CurrentHedgehog <> nil) and (CurrentHedgehog^.CurAmmoType = amKnife) then
-       LoadHedgehogHat(CurrentHedgehog^, 'Reserved/chef');
     if oldCI then AddCI(oldHH^.Gear);
     if newCI then AddCI(newHog^.Gear)
 end;
@@ -742,6 +824,7 @@
 RegisterVariable('hhcoords', @chSetHHCoords, false);
 RegisterVariable('bind', @chBind, true );
 RegisterVariable('teamgone', @chTeamGone, true );
+RegisterVariable('teamback', @chTeamBack, true );
 RegisterVariable('finish', @chFinish, true ); // all teams gone
 RegisterVariable('fort'    , @chFort         , false);
 RegisterVariable('grave'   , @chGrave        , false);
@@ -765,6 +848,7 @@
 procedure freeModule;
 var i, h: LongWord;
 begin
+CurrentHedgehog:= nil;
 if TeamsCount > 0 then
     begin
     for i:= 0 to Pred(TeamsCount) do
@@ -772,28 +856,32 @@
         for h:= 0 to cMaxHHIndex do
             with TeamsArray[i]^.Hedgehogs[h] do
                 begin
+//                if Gear <> nil then
+//                    DeleteGearStage(Gear, true);
                 if GearHidden <> nil then
                     Dispose(GearHidden);
+//                    DeleteGearStage(GearHidden, true);
 
-                FreeTexture(NameTagTex);
-                FreeTexture(HealthTagTex);
-                FreeTexture(HatTex);
+                FreeAndNilTexture(NameTagTex);
+                FreeAndNilTexture(HealthTagTex);
+                FreeAndNilTexture(HatTex)
                 end;
 
         with TeamsArray[i]^ do
             begin
-            FreeTexture(NameTagTex);
-            FreeTexture(GraveTex);
-            FreeTexture(AIKillsTex);
-            FreeTexture(FlagTex);
+            FreeAndNilTexture(NameTagTex);
+            FreeAndNilTexture(OwnerTex);
+            FreeAndNilTexture(GraveTex);
+            FreeAndNilTexture(AIKillsTex);
+            FreeAndNilTexture(FlagTex);
             end;
 
-        Dispose(TeamsArray[i]);
-    end;
+        Dispose(TeamsArray[i])
+        end;
     for i:= 0 to Pred(ClansCount) do
         begin
-        FreeTexture(ClansArray[i]^.HealthTex);
-        Dispose(ClansArray[i]);
+        FreeAndNilTexture(ClansArray[i]^.HealthTex);
+        Dispose(ClansArray[i])
         end
     end;
 TeamsCount:= 0;