hedgewars/uTeams.pas
changeset 351 29bc9c36ad5f
parent 312 c36d0b34ac3d
child 364 52cb4d6f84b7
equal deleted inserted replaced
350:c3ccec3834e8 351:29bc9c36ad5f
    16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
    16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
    17  *)
    17  *)
    18 
    18 
    19 unit uTeams;
    19 unit uTeams;
    20 interface
    20 interface
    21 uses SDLh, uConsts, uKeys, uGears, uRandom, uAmmos;
    21 uses SDLh, uConsts, uKeys, uGears, uRandom, uAmmos, uFloat;
    22 {$INCLUDE options.inc}
    22 {$INCLUDE options.inc}
    23 type PHedgehog = ^THedgehog;
    23 type PHedgehog = ^THedgehog;
    24      PTeam     = ^TTeam;
    24      PTeam     = ^TTeam;
    25      THedgehog = record
    25      THedgehog = record
    26                  Name: string[MAXNAMELEN];
    26                  Name: string[MAXNAMELEN];
    81 function CheckForWin: boolean;
    81 function CheckForWin: boolean;
    82 var team, AliveTeam: PTeam;
    82 var team, AliveTeam: PTeam;
    83     AliveCount: Longword;
    83     AliveCount: Longword;
    84     s: shortstring;
    84     s: shortstring;
    85 begin
    85 begin
    86 Result:= false;
       
    87 AliveCount:= 0;
    86 AliveCount:= 0;
    88 AliveTeam:= nil;
    87 AliveTeam:= nil;
    89 team:= TeamsList;
    88 team:= TeamsList;
    90 while team <> nil do
    89 while team <> nil do
    91       begin
    90       begin
    92       if team.TeamHealth > 0 then
    91       if team^.TeamHealth > 0 then
    93          begin
    92          begin
    94          inc(AliveCount);
    93          inc(AliveCount);
    95          AliveTeam:= team
    94          AliveTeam:= team
    96          end;
    95          end;
    97       team:= team.Next
    96       team:= team^.Next
    98       end;
    97       end;
    99 
    98 
   100 if AliveCount >= 2 then exit;
    99 if AliveCount >= 2 then exit(false);
   101 Result:= true;
   100 CheckForWin:= true;
   102 
   101 
   103 TurnTimeLeft:= 0;
   102 TurnTimeLeft:= 0;
   104 if AliveCount = 0 then
   103 if AliveCount = 0 then
   105    begin // draw
   104    begin // draw
   106    AddCaption(trmsg[sidDraw], $FFFFFF, capgrpGameState);
   105    AddCaption(trmsg[sidDraw], $FFFFFF, capgrpGameState);
   107    SendStat(siGameResult, trmsg[sidDraw]);
   106    SendStat(siGameResult, trmsg[sidDraw]);
   108    AddGear(0, 0, gtATFinishGame, 0, 0, 0, 2000)
   107    AddGear(0, 0, gtATFinishGame, 0, 0, 0, 2000)
   109    end else // win
   108    end else // win
   110    begin
   109    begin
   111    s:= Format(trmsg[sidWinner], AliveTeam.TeamName);
   110    s:= Format(trmsg[sidWinner], AliveTeam^.TeamName);
   112    AddCaption(s, $FFFFFF, capgrpGameState);
   111    AddCaption(s, $FFFFFF, capgrpGameState);
   113    SendStat(siGameResult, s);
   112    SendStat(siGameResult, s);
   114    AddGear(0, 0, gtATFinishGame, 0, 0, 0, 2000)
   113    AddGear(0, 0, gtATFinishGame, 0, 0, 0, 2000)
   115    end;
   114    end;
   116 SendStats
   115 SendStats
   117 end;
   116 end;
   118 
   117 
   119 procedure SwitchHedgehog;
   118 procedure SwitchHedgehog;
   120 var tteam: PTeam;
   119 var tteam: PTeam;
   121     th: integer;
   120     th: integer;
       
   121     g: PGear;
   122 begin
   122 begin
   123 FreeActionsList;
   123 FreeActionsList;
   124 TargetPoint.X:= NoPointX;
   124 TargetPoint.X:= NoPointX;
   125 TryDo(CurrentTeam <> nil, 'nil Team', true);
   125 TryDo(CurrentTeam <> nil, 'nil Team', true);
   126 tteam:= CurrentTeam;
   126 tteam:= CurrentTeam;
   127 with CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog] do
   127 with CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog] do
   128      if Gear <> nil then
   128      if Gear <> nil then
   129         begin
   129         begin
   130         Gear.Message:= 0;
   130         Gear^.Message:= 0;
   131         Gear.Z:= cHHZ
   131         Gear^.Z:= cHHZ
   132         end;
   132         end;
   133 
   133 
   134 repeat
   134 repeat
   135   CurrentTeam:= CurrentTeam.Next;
   135   CurrentTeam:= CurrentTeam^.Next;
   136   if CurrentTeam = nil then CurrentTeam:= TeamsList;
   136   if CurrentTeam = nil then CurrentTeam:= TeamsList;
   137   th:= CurrentTeam.CurrHedgehog;
   137   th:= CurrentTeam^.CurrHedgehog;
   138   repeat
   138   repeat
   139     CurrentTeam.CurrHedgehog:= Succ(CurrentTeam.CurrHedgehog) mod (cMaxHHIndex + 1);
   139     CurrentTeam^.CurrHedgehog:= Succ(CurrentTeam^.CurrHedgehog) mod (cMaxHHIndex + 1);
   140   until (CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog].Gear <> nil) or (CurrentTeam.CurrHedgehog = th)
   140   until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) or (CurrentTeam^.CurrHedgehog = th)
   141 until (CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog].Gear <> nil) or (CurrentTeam = tteam);
   141 until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) or (CurrentTeam = tteam);
   142 
   142 
   143 TryDo(CurrentTeam <> tteam, 'Switch hedgehog: only one team?!', true);
   143 TryDo(CurrentTeam <> tteam, 'Switch hedgehog: only one team?!', true);
   144 
   144 
   145 with CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog] do
   145 with CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog] do
   146      begin
   146      begin
   147      AttacksNum:= 0;
   147      AttacksNum:= 0;
   148      with Gear^ do
   148      with Gear^ do
   149           begin
   149           begin
   150           Z:= cCurrHHZ;
   150           Z:= cCurrHHZ;
   154      RemoveGearFromList(Gear);
   154      RemoveGearFromList(Gear);
   155      InsertGearToList(Gear);
   155      InsertGearToList(Gear);
   156      FollowGear:= Gear
   156      FollowGear:= Gear
   157      end;
   157      end;
   158 ResetKbd;
   158 ResetKbd;
   159 cWindSpeed:= (GetRandom * 2 - 1) * cMaxWindSpeed;
   159 
   160 AddGear(0, 0, gtATSmoothWindCh, 0, 0, 0, 1).Tag:= round(72 * cWindSpeed / cMaxWindSpeed);
   160 cWindSpeed:= rndSign(GetRandom * cMaxWindSpeed);
       
   161 addfilelog('SwitchHedgehog 06');
       
   162 g:= AddGear(0, 0, gtATSmoothWindCh, 0, 0, 0, 1);
       
   163 g^.Tag:= hwRound(cWindSpeed * 72 / cMaxWindSpeed);
       
   164 addfilelog('SwitchHedgehog 07');
   161 {$IFDEF DEBUGFILE}AddFileLog('Wind = '+FloatToStr(cWindSpeed));{$ENDIF}
   165 {$IFDEF DEBUGFILE}AddFileLog('Wind = '+FloatToStr(cWindSpeed));{$ENDIF}
   162 ApplyAmmoChanges(CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog]);
   166 ApplyAmmoChanges(CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]);
   163 if CurrentTeam.ExtDriven then SetDefaultBinds
   167 if CurrentTeam^.ExtDriven then SetDefaultBinds
   164                          else SetBinds(CurrentTeam.Binds);
   168                           else SetBinds(CurrentTeam^.Binds);
   165 bShowFinger:= true;
   169 bShowFinger:= true;
   166 TurnTimeLeft:= cHedgehogTurnTime
   170 TurnTimeLeft:= cHedgehogTurnTime
   167 end;
   171 end;
   168 
   172 
   169 function AddTeam: PTeam;
   173 function AddTeam: PTeam;
       
   174 var Result: PTeam;
   170 begin
   175 begin
   171 New(Result);
   176 New(Result);
   172 TryDo(Result <> nil, 'AddTeam: Result = nil', true);
   177 TryDo(Result <> nil, 'AddTeam: Result = nil', true);
   173 FillChar(Result^, sizeof(TTeam), 0);
   178 FillChar(Result^, sizeof(TTeam), 0);
   174 Result.AttackBar:= 2;
   179 Result^.AttackBar:= 2;
   175 Result.CurrHedgehog:= cMaxHHIndex;
   180 Result^.CurrHedgehog:= cMaxHHIndex;
   176 if TeamsList = nil then TeamsList:= Result
   181 if TeamsList = nil then TeamsList:= Result
   177                    else begin
   182                    else begin
   178                         Result.Next:= TeamsList;
   183                         Result^.Next:= TeamsList;
   179                         TeamsList:= Result
   184                         TeamsList:= Result
   180                         end;
   185                         end;
   181 CurrentTeam:= Result
   186 CurrentTeam:= Result;
       
   187 AddTeam:= Result
   182 end;
   188 end;
   183 
   189 
   184 procedure FreeTeamsList;
   190 procedure FreeTeamsList;
   185 var t, tt: PTeam;
   191 var t, tt: PTeam;
   186 begin
   192 begin
   187 tt:= TeamsList;
   193 tt:= TeamsList;
   188 TeamsList:= nil;
   194 TeamsList:= nil;
   189 while tt<>nil do
   195 while tt <> nil do
   190       begin
   196       begin
   191       t:= tt;
   197       t:= tt;
   192       tt:= tt.Next;
   198       tt:= tt^.Next;
   193       Dispose(t)
   199       Dispose(t)
   194       end;
   200       end;
   195 end;
   201 end;
   196 
   202 
   197 procedure RecountAllTeamsHealth;
   203 procedure RecountAllTeamsHealth;
   199 begin
   205 begin
   200 p:= TeamsList;
   206 p:= TeamsList;
   201 while p <> nil do
   207 while p <> nil do
   202       begin
   208       begin
   203       RecountTeamHealth(p);
   209       RecountTeamHealth(p);
   204       p:= p.Next
   210       p:= p^.Next
   205       end
   211       end
   206 end;
   212 end;
   207 
   213 
   208 procedure InitTeams;
   214 procedure InitTeams;
   209 var p: PTeam;
   215 var p: PTeam;
   213 p:= TeamsList;
   219 p:= TeamsList;
   214 while p <> nil do
   220 while p <> nil do
   215       begin
   221       begin
   216       th:= 0;
   222       th:= 0;
   217       for i:= 0 to cMaxHHIndex do
   223       for i:= 0 to cMaxHHIndex do
   218           if p.Hedgehogs[i].Gear <> nil then
   224           if p^.Hedgehogs[i].Gear <> nil then
   219              inc(th, p.Hedgehogs[i].Gear.Health);
   225              inc(th, p^.Hedgehogs[i].Gear^.Health);
   220       if th > MaxTeamHealth then MaxTeamHealth:= th;
   226       if th > MaxTeamHealth then MaxTeamHealth:= th;
   221       p:= p.Next
   227       p:= p^.Next
   222       end;
   228       end;
   223 RecountAllTeamsHealth
   229 RecountAllTeamsHealth
   224 end;
   230 end;
   225 
   231 
   226 procedure ApplyAmmoChanges(var Hedgehog: THedgehog);
   232 procedure ApplyAmmoChanges(var Hedgehog: THedgehog);
   228 begin
   234 begin
   229 TargetPoint.X:= NoPointX;
   235 TargetPoint.X:= NoPointX;
   230 
   236 
   231 with Hedgehog do
   237 with Hedgehog do
   232      begin
   238      begin
   233      if Ammo[CurSlot, CurAmmo].Count = 0 then
   239      if Ammo^[CurSlot, CurAmmo].Count = 0 then
   234         begin
   240         begin
   235         CurAmmo:= 0;
   241         CurAmmo:= 0;
   236         CurSlot:= 0;
   242         CurSlot:= 0;
   237         while (CurSlot <= cMaxSlotIndex) and (Ammo[CurSlot, CurAmmo].Count = 0) do inc(CurSlot)
   243         while (CurSlot <= cMaxSlotIndex) and (Ammo^[CurSlot, CurAmmo].Count = 0) do inc(CurSlot)
   238         end;
   244         end;
   239 
   245 
   240 with Ammo[CurSlot, CurAmmo] do
   246 with Ammo^[CurSlot, CurAmmo] do
   241      begin
   247      begin
   242      CurMinAngle:= Ammoz[AmmoType].minAngle;
   248      CurMinAngle:= Ammoz[AmmoType].minAngle;
   243      if Ammoz[AmmoType].maxAngle <> 0 then CurMaxAngle:= Ammoz[AmmoType].maxAngle
   249      if Ammoz[AmmoType].maxAngle <> 0 then CurMaxAngle:= Ammoz[AmmoType].maxAngle
   244                                       else CurMaxAngle:= cMaxAngle;
   250                                       else CurMaxAngle:= cMaxAngle;
   245      with Hedgehog.Gear^ do
   251      with Hedgehog.Gear^ do
   246         begin
   252         begin
   247         if Angle < CurMinAngle then Angle:= CurMinAngle;
   253         if Angle < CurMinAngle then Angle:= CurMinAngle;
   248         if Angle > CurMaxAngle then Angle:= CurMaxAngle;
   254         if Angle > CurMaxAngle then Angle:= CurMaxAngle;
   249         end;
   255         end;
   250         
   256 
   251      s:= trammo[Ammoz[AmmoType].NameId];
   257      s:= trammo[Ammoz[AmmoType].NameId];
   252      if Count <> AMMO_INFINITE then
   258      if Count <> AMMO_INFINITE then
   253         s:= s + ' (' + IntToStr(Count) + ')';
   259         s:= s + ' (' + IntToStr(Count) + ')';
   254      if (Propz and ammoprop_Timerable) <> 0 then
   260      if (Propz and ammoprop_Timerable) <> 0 then
   255         s:= s + ', ' + inttostr(Timer div 1000) + ' ' + trammo[sidSeconds];
   261         s:= s + ', ' + inttostr(Timer div 1000) + ' ' + trammo[sidSeconds];
   256      AddCaption(s, Team.Color, capgrpAmmoinfo);
   262      AddCaption(s, Team^.Color, capgrpAmmoinfo);
   257      if (Propz and ammoprop_NeedTarget) <> 0
   263      if (Propz and ammoprop_NeedTarget) <> 0
   258         then begin
   264         then begin
   259         Gear.State:= Gear.State or      gstHHChooseTarget;
   265         Gear^.State:= Gear^.State or      gstHHChooseTarget;
   260         isCursorVisible:= true
   266         isCursorVisible:= true
   261         end else begin
   267         end else begin
   262         Gear.State:= Gear.State and not gstHHChooseTarget;
   268         Gear^.State:= Gear^.State and not gstHHChooseTarget;
   263         isCursorVisible:= false
   269         isCursorVisible:= false
   264         end;
   270         end;
   265      ShowCrosshair:= (Propz and ammoprop_NoCrosshair) = 0
   271      ShowCrosshair:= (Propz and ammoprop_NoCrosshair) = 0
   266      end
   272      end
   267      end
   273      end
   268 end;
   274 end;
   269 
   275 
   270 function  TeamSize(p: PTeam): Longword;
   276 function  TeamSize(p: PTeam): Longword;
   271 var i: Longword;
   277 var i, Result: Longword;
   272 begin
   278 begin
   273 Result:= 0;
   279 Result:= 0;
   274 for i:= 0 to cMaxHHIndex do
   280 for i:= 0 to cMaxHHIndex do
   275     if p.Hedgehogs[i].Gear <> nil then inc(Result)
   281     if p^.Hedgehogs[i].Gear <> nil then inc(Result);
       
   282 TeamSize:= Result
   276 end;
   283 end;
   277 
   284 
   278 procedure RecountTeamHealth(team: PTeam);
   285 procedure RecountTeamHealth(team: PTeam);
   279 var i: integer;
   286 var i: integer;
   280 begin
   287 begin
   281 with team^ do
   288 with team^ do
   282      begin
   289      begin
   283      TeamHealthBarWidth:= 0;
   290      TeamHealthBarWidth:= 0;
   284      for i:= 0 to cMaxHHIndex do
   291      for i:= 0 to cMaxHHIndex do
   285          if Hedgehogs[i].Gear <> nil then
   292          if Hedgehogs[i].Gear <> nil then
   286             inc(TeamHealthBarWidth, Hedgehogs[i].Gear.Health);
   293             inc(TeamHealthBarWidth, Hedgehogs[i].Gear^.Health);
   287      TeamHealth:= TeamHealthBarWidth;
   294      TeamHealth:= TeamHealthBarWidth;
   288      if TeamHealthBarWidth > MaxTeamHealth then
   295      if TeamHealthBarWidth > MaxTeamHealth then
   289         begin
   296         begin
   290         MaxTeamHealth:= TeamHealthBarWidth;
   297         MaxTeamHealth:= TeamHealthBarWidth;
   291         RecountAllTeamsHealth;
   298         RecountAllTeamsHealth;
   292         end else TeamHealthBarWidth:= (TeamHealthBarWidth * cTeamHealthWidth) div MaxTeamHealth
   299         end else TeamHealthBarWidth:= (TeamHealthBarWidth * cTeamHealthWidth) div MaxTeamHealth
   293      end;
   300      end;
   294 // FIXME: at the game init, gtTeamHealthSorters are created for each team, and they work simultaneously
   301 // FIXME: at the game init, gtTeamHealthSorters are created for each team, and they work simultaneously
   295 AddGear(0, 0, gtTeamHealthSorter, 0)
   302 AddGear(0, 0, gtTeamHealthSorter, 0, 0, 0, 0)
   296 end;
   303 end;
   297 
   304 
   298 procedure RestoreTeamsFromSave;
   305 procedure RestoreTeamsFromSave;
   299 var p: PTeam;
   306 var p: PTeam;
   300 begin
   307 begin
   301 p:= TeamsList;
   308 p:= TeamsList;
   302 while p <> nil do
   309 while p <> nil do
   303       begin
   310       begin
   304       p.ExtDriven:= false;
   311       p^.ExtDriven:= false;
   305       p:= p.Next
   312       p:= p^.Next
   306       end;
   313       end;
   307 end;
   314 end;
   308 
   315 
   309 procedure SetWeapon(weap: TAmmoType);
   316 procedure SetWeapon(weap: TAmmoType);
   310 var t: integer;
   317 var t: integer;
   311 begin
   318 begin
   312 t:= cMaxSlotAmmoIndex;
   319 t:= cMaxSlotAmmoIndex;
   313 with CurrentTeam^ do
   320 with CurrentTeam^ do
   314      with Hedgehogs[CurrHedgehog] do
   321      with Hedgehogs[CurrHedgehog] do
   315           while (Ammo[CurSlot, CurAmmo].AmmoType <> weap) and (t >= 0) do
   322           while (Ammo^[CurSlot, CurAmmo].AmmoType <> weap) and (t >= 0) do
   316                 begin
   323                 begin
   317                 ParseCommand('/slot ' + chr(49 + Ammoz[TAmmoType(weap)].Slot));
   324                 ParseCommand('/slot ' + chr(49 + Ammoz[TAmmoType(weap)].Slot), true);
   318                 dec(t)
   325                 dec(t)
   319                 end
   326                 end
   320 end;
   327 end;
   321 
   328 
   322 procedure SendStats;
   329 procedure SendStats;
   327 msd:= 0; msdhh:= nil;
   334 msd:= 0; msdhh:= nil;
   328 p:= TeamsList;
   335 p:= TeamsList;
   329 while p <> nil do
   336 while p <> nil do
   330       begin
   337       begin
   331       for i:= 0 to cMaxHHIndex do
   338       for i:= 0 to cMaxHHIndex do
   332           if p.Hedgehogs[i].MaxStepDamage > msd then
   339           if p^.Hedgehogs[i].MaxStepDamage > msd then
   333              begin
   340              begin
   334              msdhh:= @p.Hedgehogs[i];
   341              msdhh:= @(p^.Hedgehogs[i]);
   335              msd:= p.Hedgehogs[i].MaxStepDamage
   342              msd:= p^.Hedgehogs[i].MaxStepDamage
   336              end;
   343              end;
   337       p:= p.Next
   344       p:= p^.Next
   338       end;
   345       end;
   339 if msdhh <> nil then SendStat(siMaxStepDamage, inttostr(msdhh.MaxStepDamage) + ' ' +
   346 if msdhh <> nil then SendStat(siMaxStepDamage, inttostr(msdhh^.MaxStepDamage) + ' ' +
   340                                                msdhh.Name + ' (' + msdhh.Team.TeamName + ')');
   347                                                msdhh^.Name + ' (' + msdhh^.Team^.TeamName + ')');
   341 if KilledHHs > 0 then SendStat(siKilledHHs, inttostr(KilledHHs));
   348 if KilledHHs > 0 then SendStat(siKilledHHs, inttostr(KilledHHs));
   342 end;
   349 end;
   343 
   350 
   344 initialization
   351 initialization
   345 
   352