hedgewars/uTeams.pas
changeset 547 b81a055f2d06
parent 540 b06c5aace2fa
child 548 ac1e32b538fd
equal deleted inserted replaced
546:0e7cc3fb05cd 547:b81a055f2d06
    40                  BotLevel  : LongWord; // 0 - Human player
    40                  BotLevel  : LongWord; // 0 - Human player
    41                  DamageGiven: Longword;
    41                  DamageGiven: Longword;
    42                  MaxStepDamage: Longword;
    42                  MaxStepDamage: Longword;
    43                  end;
    43                  end;
    44      TTeam = record
    44      TTeam = record
    45              Next: PTeam;
       
    46              Color, AdjColor: Longword;
    45              Color, AdjColor: Longword;
    47              TeamName: string[MAXNAMELEN];
    46              TeamName: string[MAXNAMELEN];
    48              ExtDriven: boolean;
    47              ExtDriven: boolean;
    49              Binds: TBinds;
    48              Binds: TBinds;
    50              Hedgehogs: array[0..cMaxHHIndex] of THedgehog;
    49              Hedgehogs: array[0..cMaxHHIndex] of THedgehog;
    60              AttackBar: LongWord;
    59              AttackBar: LongWord;
    61              HedgehogsNumber: byte;
    60              HedgehogsNumber: byte;
    62              end;
    61              end;
    63 
    62 
    64 var CurrentTeam: PTeam = nil;
    63 var CurrentTeam: PTeam = nil;
    65     TeamsList: PTeam = nil;
    64     TeamsArray: array[0..Pred(cMaxTeams)] of PTeam;
       
    65     TeamsCount: Longword = 0;
    66     CurMinAngle, CurMaxAngle: Longword;
    66     CurMinAngle, CurMaxAngle: Longword;
    67 
    67 
    68 function AddTeam: PTeam;
    68 function AddTeam: PTeam;
    69 procedure ApplyAmmoChanges(var Hedgehog: THedgehog);
    69 procedure ApplyAmmoChanges(var Hedgehog: THedgehog);
    70 procedure SwitchHedgehog;
    70 procedure SwitchHedgehog;
    82 
    82 
    83 procedure FreeTeamsList; forward;
    83 procedure FreeTeamsList; forward;
    84 
    84 
    85 function CheckForWin: boolean;
    85 function CheckForWin: boolean;
    86 var team, AliveTeam: PTeam;
    86 var team, AliveTeam: PTeam;
    87     AliveCount: Longword;
       
    88     s: shortstring;
    87     s: shortstring;
    89 begin
    88 begin
    90 AliveCount:= 0;
    89 if TeamsCount >= 2 then exit(false);
    91 AliveTeam:= nil;
       
    92 team:= TeamsList;
       
    93 while team <> nil do
       
    94       begin
       
    95       if team^.TeamHealth > 0 then
       
    96          begin
       
    97          inc(AliveCount);
       
    98          AliveTeam:= team
       
    99          end;
       
   100       team:= team^.Next
       
   101       end;
       
   102 
       
   103 if AliveCount >= 2 then exit(false);
       
   104 CheckForWin:= true;
    90 CheckForWin:= true;
   105 
    91 
   106 TurnTimeLeft:= 0;
    92 TurnTimeLeft:= 0;
   107 if AliveCount = 0 then
    93 if TeamsCount = 0 then
   108    begin // draw
    94    begin // draw
   109    AddCaption(trmsg[sidDraw], $FFFFFF, capgrpGameState);
    95    AddCaption(trmsg[sidDraw], $FFFFFF, capgrpGameState);
   110    SendStat(siGameResult, trmsg[sidDraw]);
    96    SendStat(siGameResult, trmsg[sidDraw]);
   111    AddGear(0, 0, gtATFinishGame, 0, _0, _0, 2000)
    97    AddGear(0, 0, gtATFinishGame, 0, _0, _0, 2000)
   112    end else // win
    98    end else // win
   113    begin
    99    begin
   114    s:= Format(trmsg[sidWinner], AliveTeam^.TeamName);
   100    s:= Format(trmsg[sidWinner], TeamsArray[0]^.TeamName);
   115    AddCaption(s, $FFFFFF, capgrpGameState);
   101    AddCaption(s, $FFFFFF, capgrpGameState);
   116    SendStat(siGameResult, s);
   102    SendStat(siGameResult, s);
   117    AddGear(0, 0, gtATFinishGame, 0, _0, _0, 2000)
   103    AddGear(0, 0, gtATFinishGame, 0, _0, _0, 2000)
   118    end;
   104    end;
   119 SendStats
   105 SendStats
   120 end;
   106 end;
   121 
   107 
   122 procedure SwitchHedgehog;
   108 procedure SwitchHedgehog;
   123 var tteam: PTeam;
   109 var th: LongInt;
   124     th: LongInt;
   110     t: LongWord;
   125     g: PGear;
   111     g: PGear;
   126 begin
   112 begin
   127 FreeActionsList;
   113 FreeActionsList;
   128 TargetPoint.X:= NoPointX;
   114 TargetPoint.X:= NoPointX;
   129 TryDo(CurrentTeam <> nil, 'nil Team', true);
   115 TryDo(CurrentTeam <> nil, 'nil Team', true);
   130 tteam:= CurrentTeam;
   116 
   131 with CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog] do
   117 with CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog] do
   132      if Gear <> nil then
   118      if Gear <> nil then
   133         begin
   119         begin
   134         AttacksNum:= 0;
   120         AttacksNum:= 0;
   135         Gear^.Message:= 0;
   121         Gear^.Message:= 0;
   136         Gear^.Z:= cHHZ;
   122         Gear^.Z:= cHHZ;
   137         RemoveGearFromList(Gear);
   123         RemoveGearFromList(Gear);
   138         InsertGearToList(Gear)
   124         InsertGearToList(Gear)
   139         end;
   125         end;
   140 
   126 
       
   127 t:= 0;
       
   128 while CurrentTeam <> TeamsArray[t] do inc(t);
       
   129 CurrentTeam:= TeamsArray[(t + 1) mod TeamsCount];
       
   130 
       
   131 th:= CurrentTeam^.CurrHedgehog;
   141 repeat
   132 repeat
   142   CurrentTeam:= CurrentTeam^.Next;
   133   CurrentTeam^.CurrHedgehog:= Succ(CurrentTeam^.CurrHedgehog) mod (cMaxHHIndex + 1);
   143   if CurrentTeam = nil then CurrentTeam:= TeamsList;
   134 until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) or (CurrentTeam^.CurrHedgehog = th);
   144   th:= CurrentTeam^.CurrHedgehog;
       
   145   repeat
       
   146     CurrentTeam^.CurrHedgehog:= Succ(CurrentTeam^.CurrHedgehog) mod (cMaxHHIndex + 1);
       
   147   until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) or (CurrentTeam^.CurrHedgehog = th)
       
   148 until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) or (CurrentTeam = tteam);
       
   149 
       
   150 TryDo(CurrentTeam <> tteam, 'Switch hedgehog: only one team?!', true);
       
   151 
   135 
   152 with CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog] do
   136 with CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog] do
   153      begin
   137      begin
   154      with Gear^ do
   138      with Gear^ do
   155           begin
   139           begin
   175 end;
   159 end;
   176 
   160 
   177 function AddTeam: PTeam;
   161 function AddTeam: PTeam;
   178 var Result: PTeam;
   162 var Result: PTeam;
   179 begin
   163 begin
       
   164 TryDo(TeamsCount <= cMaxTeams, 'Too many teams', true);
   180 New(Result);
   165 New(Result);
   181 TryDo(Result <> nil, 'AddTeam: Result = nil', true);
   166 TryDo(Result <> nil, 'AddTeam: Result = nil', true);
   182 FillChar(Result^, sizeof(TTeam), 0);
   167 FillChar(Result^, sizeof(TTeam), 0);
   183 Result^.AttackBar:= 2;
   168 Result^.AttackBar:= 2;
   184 Result^.CurrHedgehog:= cMaxHHIndex;
   169 Result^.CurrHedgehog:= cMaxHHIndex;
   185 if TeamsList = nil then TeamsList:= Result
   170 
   186                    else begin
   171 TeamsArray[TeamsCount]:= Result;
   187                         Result^.Next:= TeamsList;
   172 inc(TeamsCount);
   188                         TeamsList:= Result
   173 
   189                         end;
       
   190 CurrentTeam:= Result;
   174 CurrentTeam:= Result;
   191 AddTeam:= Result
   175 AddTeam:= Result
   192 end;
   176 end;
   193 
   177 
   194 procedure FreeTeamsList;
   178 procedure FreeTeamsList;
   195 var t, tt: PTeam;
   179 var t: LongInt;
   196 begin
   180 begin
   197 tt:= TeamsList;
   181 for t:= 0 to Pred(TeamsCount) do Dispose(TeamsArray[t]);
   198 TeamsList:= nil;
   182 TeamsCount:= 0
   199 while tt <> nil do
       
   200       begin
       
   201       t:= tt;
       
   202       tt:= tt^.Next;
       
   203       Dispose(t)
       
   204       end;
       
   205 end;
   183 end;
   206 
   184 
   207 procedure RecountAllTeamsHealth;
   185 procedure RecountAllTeamsHealth;
   208 var p: PTeam;
   186 var t: LongInt;
   209 begin
   187 begin 
   210 p:= TeamsList;
   188 for t:= 0 to Pred(TeamsCount) do
   211 while p <> nil do
   189     RecountTeamHealth(TeamsArray[t])
   212       begin
       
   213       RecountTeamHealth(p);
       
   214       p:= p^.Next
       
   215       end
       
   216 end;
   190 end;
   217 
   191 
   218 procedure InitTeams;
   192 procedure InitTeams;
   219 var p: PTeam;
   193 var i, t: LongInt;
   220     i: LongInt;
       
   221     th: LongInt;
   194     th: LongInt;
   222 begin
   195 begin
   223 p:= TeamsList;
   196 for t:= 0 to Pred(TeamsCount) do
   224 while p <> nil do
   197    with TeamsArray[t]^ do
   225       begin
   198       begin
   226       th:= 0;
   199       th:= 0;
   227       for i:= 0 to cMaxHHIndex do
   200       for i:= 0 to cMaxHHIndex do
   228           if p^.Hedgehogs[i].Gear <> nil then
   201           if Hedgehogs[i].Gear <> nil then
   229              inc(th, p^.Hedgehogs[i].Gear^.Health);
   202              inc(th, Hedgehogs[i].Gear^.Health);
   230       if th > MaxTeamHealth then MaxTeamHealth:= th;
   203       if th > MaxTeamHealth then MaxTeamHealth:= th;
   231       p:= p^.Next
       
   232       end;
   204       end;
   233 RecountAllTeamsHealth
   205 RecountAllTeamsHealth
   234 end;
   206 end;
   235 
   207 
   236 procedure ApplyAmmoChanges(var Hedgehog: THedgehog);
   208 procedure ApplyAmmoChanges(var Hedgehog: THedgehog);
   305 // FIXME: at the game init, gtTeamHealthSorters are created for each team, and they work simultaneously
   277 // FIXME: at the game init, gtTeamHealthSorters are created for each team, and they work simultaneously
   306 AddGear(0, 0, gtTeamHealthSorter, 0, _0, _0, 0)
   278 AddGear(0, 0, gtTeamHealthSorter, 0, _0, _0, 0)
   307 end;
   279 end;
   308 
   280 
   309 procedure RestoreTeamsFromSave;
   281 procedure RestoreTeamsFromSave;
   310 var p: PTeam;
   282 var t: LongInt;
   311 begin
   283 begin
   312 p:= TeamsList;
   284 for t:= 0 to Pred(TeamsCount) do
   313 while p <> nil do
   285    TeamsArray[t]^.ExtDriven:= false
   314       begin
       
   315       p^.ExtDriven:= false;
       
   316       p:= p^.Next
       
   317       end;
       
   318 end;
   286 end;
   319 
   287 
   320 procedure SetWeapon(weap: TAmmoType);
   288 procedure SetWeapon(weap: TAmmoType);
   321 var t: LongInt;
   289 var t: LongInt;
   322 begin
   290 begin
   329                 dec(t)
   297                 dec(t)
   330                 end
   298                 end
   331 end;
   299 end;
   332 
   300 
   333 procedure SendStats;
   301 procedure SendStats;
   334 var p: PTeam;
   302 var i, t: LongInt;
   335     i: LongInt;
       
   336     msd: Longword; msdhh: PHedgehog;
   303     msd: Longword; msdhh: PHedgehog;
   337 begin
   304 begin
   338 msd:= 0; msdhh:= nil;
   305 msd:= 0; msdhh:= nil;
   339 p:= TeamsList;
   306 for t:= 0 to Pred(TeamsCount) do
   340 while p <> nil do
   307    with TeamsArray[t]^ do
   341       begin
   308       begin
   342       for i:= 0 to cMaxHHIndex do
   309       for i:= 0 to cMaxHHIndex do
   343           if p^.Hedgehogs[i].MaxStepDamage > msd then
   310           if Hedgehogs[i].MaxStepDamage > msd then
   344              begin
   311              begin
   345              msdhh:= @(p^.Hedgehogs[i]);
   312              msdhh:= @Hedgehogs[i];
   346              msd:= p^.Hedgehogs[i].MaxStepDamage
   313              msd:= Hedgehogs[i].MaxStepDamage
   347              end;
   314              end;
   348       p:= p^.Next
       
   349       end;
   315       end;
   350 if msdhh <> nil then SendStat(siMaxStepDamage, inttostr(msdhh^.MaxStepDamage) + ' ' +
   316 if msdhh <> nil then SendStat(siMaxStepDamage, inttostr(msdhh^.MaxStepDamage) + ' ' +
   351                                                msdhh^.Name + ' (' + msdhh^.Team^.TeamName + ')');
   317                                                msdhh^.Name + ' (' + msdhh^.Team^.TeamName + ')');
   352 if KilledHHs > 0 then SendStat(siKilledHHs, inttostr(KilledHHs));
   318 if KilledHHs > 0 then SendStat(siKilledHHs, inttostr(KilledHHs));
   353 end;
   319 end;