hedgewars/uTeams.pas
changeset 1 30f2d1037d5d
child 4 bcbd7adb4e4b
equal deleted inserted replaced
0:475c0f2f9d17 1:30f2d1037d5d
       
     1 (*
       
     2  * Hedgewars, a worms-like game
       
     3  * Copyright (c) 2004, 2005 Andrey Korotaev <unC0Rr@gmail.com>
       
     4  *
       
     5  * Distributed under the terms of the BSD-modified licence:
       
     6  *
       
     7  * Permission is hereby granted, free of charge, to any person obtaining a copy
       
     8  * of this software and associated documentation files (the "Software"), to deal
       
     9  * with the Software without restriction, including without limitation the
       
    10  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
       
    11  * sell copies of the Software, and to permit persons to whom the Software is
       
    12  * furnished to do so, subject to the following conditions:
       
    13  *
       
    14  * 1. Redistributions of source code must retain the above copyright notice,
       
    15  *    this list of conditions and the following disclaimer.
       
    16  * 2. Redistributions in binary form must reproduce the above copyright notice,
       
    17  *    this list of conditions and the following disclaimer in the documentation
       
    18  *    and/or other materials provided with the distribution.
       
    19  * 3. The name of the author may not be used to endorse or promote products
       
    20  *    derived from this software without specific prior written permission.
       
    21  *
       
    22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
       
    23  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
       
    24  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
       
    25  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
       
    27  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
       
    28  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
       
    29  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
       
    30  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
       
    31  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    32  *)
       
    33 
       
    34 unit uTeams;
       
    35 interface
       
    36 uses SDLh, uConsts, uKeys, uGears, uRandom;
       
    37 {$INCLUDE options.inc}
       
    38 type PHedgehog = ^THedgehog;
       
    39      PTeam     = ^TTeam;
       
    40      PHHAmmo   = ^THHAmmo;
       
    41      THedgehog = record
       
    42                  Name: string[15];
       
    43                  Gear: PGear;
       
    44                  NameRect, HealthRect, HealthTagRect: TSDL_Rect;
       
    45                  Ammo: PHHAmmo;
       
    46                  CurSlot, CurAmmo: LongWord;
       
    47                  AltSlot, AltAmmo: LongWord;
       
    48                  Team: PTeam;
       
    49                  AttacksNum: Longword;
       
    50                  visStepPos: LongWord;
       
    51                  BotLevel  : LongWord; // 0 - человек
       
    52                  end;
       
    53      THHAmmo   = array[0..cMaxSlot, 0..cMaxSlotAmmo] of TAmmo;
       
    54      TTeam = record
       
    55              Next: PTeam;
       
    56              Color: Cardinal;
       
    57              TeamName: string[15];
       
    58              ExtDriven: boolean;
       
    59              Aliases: array[0..cKeyMaxIndex] of shortstring;
       
    60              Hedgehogs: array[0..cMaxHHIndex] of THedgehog;
       
    61              Ammos: array[0..cMaxHHIndex] of THHAmmo;
       
    62              CurrHedgehog: integer;
       
    63              NameRect, CrossHairRect, GraveRect: TSDL_Rect;
       
    64              GraveName: string;
       
    65              FortName: string;
       
    66              AttackBar: LongWord;
       
    67              end;
       
    68 
       
    69 var CurrentTeam: PTeam = nil;
       
    70     TeamsList: PTeam = nil;
       
    71 
       
    72 function AddTeam: PTeam;
       
    73 procedure ApplyAmmoChanges(Hedgehog: PHedgehog);
       
    74 procedure SwitchHedgehog;
       
    75 procedure InitTeams;
       
    76 procedure OnUsedAmmo(Ammo: PHHAmmo);
       
    77 
       
    78 implementation
       
    79 uses uMisc, uStore, uWorld, uIO, uAIActions;
       
    80 
       
    81 procedure FreeTeamsList; forward;
       
    82 
       
    83 procedure SwitchHedgehog;
       
    84 var tteam: PTeam;
       
    85     th: integer;
       
    86 begin
       
    87 FreeActionsList;
       
    88 TargetPoint.X:= NoPointX;
       
    89 if CurrentTeam = nil then OutError('nil Team', true);
       
    90 tteam:= CurrentTeam;
       
    91 with CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog] do
       
    92      if Gear <> nil then Gear.Message:= 0;
       
    93 
       
    94 repeat
       
    95   CurrentTeam:= CurrentTeam.Next;
       
    96   if CurrentTeam = nil then CurrentTeam:= TeamsList;
       
    97   th:= CurrentTeam.CurrHedgehog;
       
    98   repeat
       
    99     CurrentTeam.CurrHedgehog:= Succ(CurrentTeam.CurrHedgehog) mod cMaxHHIndex;
       
   100   until (CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog].Gear <> nil) or (CurrentTeam.CurrHedgehog = th)
       
   101 until (CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog].Gear <> nil) or (CurrentTeam = tteam);
       
   102 
       
   103 if (CurrentTeam = tteam) then
       
   104    begin
       
   105    if GameType = gmtDemo then
       
   106       begin
       
   107       SendIPC('q');
       
   108       GameState:= gsExit;
       
   109       exit
       
   110       end else OutError('There''s only one team on map!', true);
       
   111    end;
       
   112 with CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog] do
       
   113      begin
       
   114      AttacksNum:= 0;
       
   115      with Gear^ do
       
   116           begin
       
   117           State:= State or gstHHDriven;
       
   118           Active:= true
       
   119           end;
       
   120      FollowGear:= Gear
       
   121      end;
       
   122 ResetKbd;
       
   123 cWindSpeed:= (GetRandom * 2 - 1) * cMaxWindSpeed;
       
   124 {$IFDEF DEBUGFILE}AddFileLog('Wind = '+FloatToStr(cWindSpeed));{$ENDIF}
       
   125 ApplyAmmoChanges(@CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog]);
       
   126 TurnTimeLeft:= cHedgehogTurnTime
       
   127 end;
       
   128 
       
   129 procedure SetFirstTurnHedgehog;
       
   130 var i: integer;
       
   131 begin
       
   132 if CurrentTeam=nil then OutError('nil Team (SetFirstTurnHedgehog)', true);
       
   133 i:= 0;
       
   134 while (i<cMaxHHIndex)and(CurrentTeam.Hedgehogs[i].Gear=nil) do inc(i);
       
   135 if CurrentTeam.Hedgehogs[i].Gear = nil then OutError(errmsgIncorrectUse + ' (sfth)', true);
       
   136 CurrentTeam.CurrHedgehog:= i;
       
   137 end;
       
   138 
       
   139 function AddTeam: PTeam;
       
   140 begin
       
   141 try
       
   142    New(Result);
       
   143 except Result:= nil; OutError(errmsgDynamicVar, true) end;
       
   144 FillChar(Result^, sizeof(TTeam), 0);
       
   145 Result.AttackBar:= 1;
       
   146 if TeamsList = nil then TeamsList:= Result
       
   147                    else begin
       
   148                         Result.Next:= TeamsList;
       
   149                         TeamsList:= Result
       
   150                         end;
       
   151 CurrentTeam:= Result
       
   152 end;
       
   153 
       
   154 procedure FreeTeamsList;
       
   155 var t, tt: PTeam;
       
   156 begin
       
   157 tt:= TeamsList;
       
   158 TeamsList:= nil;
       
   159 while tt<>nil do
       
   160       begin
       
   161       t:= tt;
       
   162       tt:= tt.Next;
       
   163       try
       
   164       Dispose(t)
       
   165       except OutError(errmsgDynamicVar) end;
       
   166       end;
       
   167 end;
       
   168 
       
   169 procedure InitTeams;
       
   170 var p: PTeam;
       
   171     i: integer;
       
   172 begin
       
   173 p:= TeamsList;
       
   174 while p <> nil do
       
   175       begin
       
   176       for i:= 0 to cMaxHHIndex do
       
   177           if p.Hedgehogs[i].Gear <> nil then
       
   178              begin
       
   179              p.Ammos[i][0, 0]:= Ammoz[amGrenade].Ammo;
       
   180              p.Ammos[i][0, 1]:= Ammoz[amUFO].Ammo;
       
   181              p.Ammos[i][1, 0]:= Ammoz[amBazooka].Ammo;
       
   182              p.Ammos[i][2, 0]:= Ammoz[amShotgun].Ammo;
       
   183              p.Ammos[i][3, 0]:= Ammoz[amPickHammer].Ammo;
       
   184              p.Ammos[i][3, 1]:= Ammoz[amRope].Ammo;
       
   185              p.Ammos[i][4, 0]:= Ammoz[amSkip].Ammo;
       
   186              p.Hedgehogs[i].Gear.Health:= 100;
       
   187              p.Hedgehogs[i].Ammo:= @p.Ammos[0]
       
   188              {0 - общее на всех оружие, i - у каждого своё
       
   189              можно группировать ёжиков, чтобы у каждой группы было своё оружие}
       
   190              end;
       
   191       p:= p.Next
       
   192       end;
       
   193 SetFirstTurnHedgehog;
       
   194 end;
       
   195 
       
   196 procedure ApplyAmmoChanges(Hedgehog: PHedgehog);
       
   197 var s: shortstring;
       
   198 begin
       
   199 with Hedgehog^ do
       
   200      begin     
       
   201      if Ammo[CurSlot, CurAmmo].Count = 0 then
       
   202         begin
       
   203         CurAmmo:= 0;
       
   204         while (CurAmmo <= cMaxSlotAmmo) and (Ammo[CurSlot, CurAmmo].Count = 0) do inc(CurAmmo)
       
   205         end;
       
   206 
       
   207 with Ammo[CurSlot, CurAmmo] do
       
   208      begin
       
   209      s:= Ammoz[AmmoType].Name;
       
   210      if Count <> AMMO_INFINITE then
       
   211         s:= s + ' (' + IntToStr(Count) + ')';
       
   212      if (Propz and ammoprop_Timerable) <> 0 then
       
   213         s:= s + ', ' + inttostr(Timer div 1000) + ' sec';
       
   214      AddCaption(s, Team.Color, capgrpAmmoinfo);
       
   215      if (Propz and ammoprop_NeedTarget) <> 0
       
   216         then begin
       
   217         Gear.State:= Gear.State or      gstHHChooseTarget;
       
   218         isCursorVisible:= true
       
   219         end else begin
       
   220         Gear.State:= Gear.State and not gstHHChooseTarget;
       
   221         AdjustMPoint;
       
   222         isCursorVisible:= false
       
   223         end
       
   224      end
       
   225      end
       
   226 end;
       
   227 
       
   228 procedure PackAmmo(Ammo: PHHAmmo; Slot: integer);
       
   229 var ami: integer;
       
   230     b: boolean;
       
   231 begin
       
   232     repeat
       
   233       b:= false;
       
   234       ami:= 0;
       
   235       while (not b) and (ami < cMaxSlotAmmo) do
       
   236           if (Ammo[slot, ami].Count = 0)
       
   237              and (Ammo[slot, ami + 1].Count > 0) then b:= true
       
   238                                                  else inc(ami);
       
   239       if b then // есть пустое место
       
   240          begin
       
   241          Ammo[slot, ami]:= Ammo[slot, ami + 1]
       
   242          end
       
   243     until not b;
       
   244 end;
       
   245 
       
   246 procedure OnUsedAmmo(Ammo: PHHAmmo);
       
   247 var s, a: Longword;
       
   248 begin
       
   249 with CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog] do
       
   250      begin
       
   251      if CurAmmoGear = nil then begin s:= CurSlot; a:= CurAmmo end
       
   252                           else begin s:= AltSlot; a:= AltAmmo end;
       
   253      with Ammo[s, a] do
       
   254           if Count <> AMMO_INFINITE then
       
   255              begin
       
   256              dec(Count);
       
   257              if Count = 0 then PackAmmo(Ammo, CurSlot)
       
   258              end
       
   259      end
       
   260 end;
       
   261 
       
   262 initialization
       
   263 
       
   264 finalization
       
   265 
       
   266 FreeTeamsList
       
   267 
       
   268 end.