hedgewars/uAmmos.pas
changeset 6580 6155187bf599
parent 6519 b0dc69bb1f54
child 6622 01889d5bc79b
equal deleted inserted replaced
6579:fc52f7c22c9b 6580:6155187bf599
    65 {$HINTS ON}
    65 {$HINTS ON}
    66 FillChar(Ammo^, sizeof(Ammo^), 0);
    66 FillChar(Ammo^, sizeof(Ammo^), 0);
    67 for a:= Low(TAmmoType) to High(TAmmoType) do
    67 for a:= Low(TAmmoType) to High(TAmmoType) do
    68     begin
    68     begin
    69     if cnts[a] > 0 then
    69     if cnts[a] > 0 then
    70        begin
    70         begin
    71        TryDo(mi[Ammoz[a].Slot] <= cMaxSlotAmmoIndex, 'Ammo slot overflow', true);
    71         TryDo(mi[Ammoz[a].Slot] <= cMaxSlotAmmoIndex, 'Ammo slot overflow', true);
    72        Ammo^[Ammoz[a].Slot, mi[Ammoz[a].Slot]]:= Ammoz[a].Ammo;
    72         Ammo^[Ammoz[a].Slot, mi[Ammoz[a].Slot]]:= Ammoz[a].Ammo;
    73        with Ammo^[Ammoz[a].Slot, mi[Ammoz[a].Slot]] do Count:= cnts[a];
    73         with Ammo^[Ammoz[a].Slot, mi[Ammoz[a].Slot]] do
    74        inc(mi[Ammoz[a].Slot])
    74             Count:= cnts[a];
    75        end
    75         inc(mi[Ammoz[a].Slot])
       
    76         end
    76     end
    77     end
    77 end;
    78 end;
    78 
    79 
    79 procedure AddAmmoStore;
    80 procedure AddAmmoStore;
    80 const probability: array [0..8] of LongWord = (0,20,30,60,100,200,400,600,800);
    81 const probability: array [0..8] of LongWord = (0,20,30,60,100,200,400,600,800);
   101         if cnt = 9 then
   102         if cnt = 9 then
   102             begin
   103             begin
   103             cnt:= AMMO_INFINITE;
   104             cnt:= AMMO_INFINITE;
   104             Ammoz[a].Probability:= 0
   105             Ammoz[a].Probability:= 0
   105             end;
   106             end;
   106         if Ammoz[a].NumberInCase = 0 then Ammoz[a].Probability:= 0;
   107         if Ammoz[a].NumberInCase = 0 then
       
   108             Ammoz[a].Probability:= 0;
   107 
   109 
   108         // avoid things we already have by scheme
   110         // avoid things we already have by scheme
   109         // merge this into DisableSomeWeapons ?
   111         // merge this into DisableSomeWeapons ?
   110         if ((a = amLowGravity) and ((GameFlags and gfLowGravity) <> 0)) or
   112         if ((a = amLowGravity) and ((GameFlags and gfLowGravity) <> 0))
   111            ((a = amInvulnerable) and ((GameFlags and gfInvulnerable) <> 0)) or
   113         or ((a = amInvulnerable) and ((GameFlags and gfInvulnerable) <> 0))
   112            ((a = amLaserSight) and ((GameFlags and gfLaserSight) <> 0)) or
   114         or ((a = amLaserSight) and ((GameFlags and gfLaserSight) <> 0))
   113            ((a = amVampiric) and ((GameFlags and gfVampiric) <> 0)) or
   115         or ((a = amVampiric) and ((GameFlags and gfVampiric) <> 0))
   114            ((a = amExtraTime) and (cHedgehogTurnTime >= 1000000)) then
   116         or ((a = amExtraTime) and (cHedgehogTurnTime >= 1000000)) then
   115             begin
   117             begin
   116             cnt:= 0;
   118             cnt:= 0;
   117             Ammoz[a].Probability:= 0
   119             Ammoz[a].Probability:= 0
   118             end;
   120             end;
   119         ammos[a]:= cnt;
   121         ammos[a]:= cnt;
   120 
   122 
   121         if ((GameFlags and gfKing) <> 0) and ((GameFlags and gfPlaceHog) = 0) and (Ammoz[a].SkipTurns = 0) and (a <> amTeleport) and (a <> amSkip) then
   123         if ((GameFlags and gfKing) <> 0) and ((GameFlags and gfPlaceHog) = 0)
       
   124         and (Ammoz[a].SkipTurns = 0) and (a <> amTeleport) and (a <> amSkip) then
   122             Ammoz[a].SkipTurns:= 1;
   125             Ammoz[a].SkipTurns:= 1;
   123 
   126 
   124         if ((GameFlags and gfPlaceHog) <> 0) and
   127         if ((GameFlags and gfPlaceHog) <> 0)
   125             (a <> amTeleport) and (a <> amSkip) and
   128         and (a <> amTeleport) and (a <> amSkip)
   126             (Ammoz[a].SkipTurns < 10000) then inc(Ammoz[a].SkipTurns,10000);
   129         and (Ammoz[a].SkipTurns < 10000) then
   127     if ((GameFlags and gfPlaceHog) <> 0) and (a = amTeleport) then ammos[a]:= AMMO_INFINITE
   130             inc(Ammoz[a].SkipTurns,10000);
       
   131     if ((GameFlags and gfPlaceHog) <> 0) and (a = amTeleport) then
       
   132         ammos[a]:= AMMO_INFINITE
   128         end 
   133         end 
   129     else ammos[a]:= AMMO_INFINITE;
   134         
       
   135     else
       
   136         ammos[a]:= AMMO_INFINITE;
   130     if ((GameFlags and gfPlaceHog) <> 0) and (a = amTeleport) then 
   137     if ((GameFlags and gfPlaceHog) <> 0) and (a = amTeleport) then 
   131         InitialCounts[Pred(StoreCnt)][a]:= cnt
   138         InitialCounts[Pred(StoreCnt)][a]:= cnt
   132     else
   139     else
   133         InitialCounts[Pred(StoreCnt)][a]:= ammos[a];
   140         InitialCounts[Pred(StoreCnt)][a]:= ammos[a];
   134     end;
   141     end;
   151 begin
   158 begin
   152 with Hedgehog do
   159 with Hedgehog do
   153     begin
   160     begin
   154     slot:= Ammoz[am].Slot;
   161     slot:= Ammoz[am].Slot;
   155     ammoidx:= 0;
   162     ammoidx:= 0;
   156     while (ammoidx < cMaxSlotAmmoIndex) and (Ammo^[slot, ammoidx].AmmoType <> am) do inc(ammoidx);
   163     while (ammoidx < cMaxSlotAmmoIndex) and (Ammo^[slot, ammoidx].AmmoType <> am) do
       
   164         inc(ammoidx);
   157     GetAmmoEntry:= @Ammo^[slot, ammoidx];
   165     GetAmmoEntry:= @Ammo^[slot, ammoidx];
   158     if (Ammo^[slot, ammoidx].AmmoType <> am) then GetAmmoEntry:= GetAmmoEntry(Hedgehog, amNothing)
   166     if (Ammo^[slot, ammoidx].AmmoType <> am) then
       
   167         GetAmmoEntry:= GetAmmoEntry(Hedgehog, amNothing)
   159     end;
   168     end;
   160 end;
   169 end;
   161 
   170 
   162 procedure AssignStores;
   171 procedure AssignStores;
   163 var t: LongInt;
   172 var t: LongInt;
   164     i: Longword;
   173     i: Longword;
   165 begin
   174 begin
   166 for t:= 0 to Pred(TeamsCount) do
   175 for t:= 0 to Pred(TeamsCount) do
   167    with TeamsArray[t]^ do
   176     with TeamsArray[t]^ do
   168       begin
   177         begin
   169       for i:= 0 to cMaxHHIndex do
   178         for i:= 0 to cMaxHHIndex do
   170           if Hedgehogs[i].Gear <> nil then
   179             if Hedgehogs[i].Gear <> nil then
   171              begin
   180                 begin
   172              Hedgehogs[i].Ammo:= GetAmmoByNum(Hedgehogs[i].AmmoStore);
   181                 Hedgehogs[i].Ammo:= GetAmmoByNum(Hedgehogs[i].AmmoStore);
   173              if (GameFlags and gfPlaceHog) <> 0 then
   182                 if (GameFlags and gfPlaceHog) <> 0 then
   174                 Hedgehogs[i].CurAmmoType:= amTeleport
   183                     Hedgehogs[i].CurAmmoType:= amTeleport
   175              else
   184                 else
   176                 Hedgehogs[i].CurAmmoType:= amNothing
   185                     Hedgehogs[i].CurAmmoType:= amNothing
   177              end
   186                 end
   178       end
   187         end
   179 end;
   188 end;
   180 
   189 
   181 procedure AddAmmo(var Hedgehog: THedgehog; ammo: TAmmoType);
   190 procedure AddAmmo(var Hedgehog: THedgehog; ammo: TAmmoType);
   182 var cnt: LongWord;
   191 var cnt: LongWord;
   183     a: PAmmo;
   192     a: PAmmo;
   184 begin
   193 begin
   185 a:= GetAmmoEntry(Hedgehog, ammo);
   194 a:= GetAmmoEntry(Hedgehog, ammo);
   186 if (a^.AmmoType <> amNothing) then cnt:= a^.Count
   195 if (a^.AmmoType <> amNothing) then
   187 else cnt:= 0;
   196     cnt:= a^.Count
       
   197 else
       
   198     cnt:= 0;
   188 if (cnt <> AMMO_INFINITE) then
   199 if (cnt <> AMMO_INFINITE) then
   189     begin
   200     begin
   190     inc(cnt, Ammoz[ammo].NumberInCase);
   201     inc(cnt, Ammoz[ammo].NumberInCase);
   191     AddAmmo(Hedgehog, ammo, cnt)
   202     AddAmmo(Hedgehog, ammo, cnt)
   192     end
   203     end
   204 hhammo:= Hedgehog.Ammo;
   215 hhammo:= Hedgehog.Ammo;
   205 
   216 
   206 for slot:= 0 to cMaxSlotIndex do
   217 for slot:= 0 to cMaxSlotIndex do
   207     for ami:= 0 to cMaxSlotAmmoIndex do
   218     for ami:= 0 to cMaxSlotAmmoIndex do
   208         if hhammo^[slot, ami].Count > 0 then
   219         if hhammo^[slot, ami].Count > 0 then
   209            ammos[hhammo^[slot, ami].AmmoType]:= hhammo^[slot, ami].Count;
   220             ammos[hhammo^[slot, ami].AmmoType]:= hhammo^[slot, ami].Count;
   210 
   221 
   211 ammos[ammo]:= cnt;
   222 ammos[ammo]:= cnt;
   212 if ammos[ammo] > AMMO_INFINITE then ammos[ammo]:= AMMO_INFINITE;
   223 if ammos[ammo] > AMMO_INFINITE then ammos[ammo]:= AMMO_INFINITE;
   213 
   224 
   214 FillAmmoStore(hhammo, ammos);
   225 FillAmmoStore(hhammo, ammos);
   215 CurWeapon:= GetAmmoEntry(Hedgehog);
   226 CurWeapon:= GetAmmoEntry(Hedgehog);
   216 with Hedgehog, CurWeapon^ do
   227 with Hedgehog, CurWeapon^ do
   217         if (Count = 0) or (AmmoType = amNothing) then
   228     if (Count = 0) or (AmmoType = amNothing) then
   218             begin
   229         begin
   219             PackAmmo(Ammo, Ammoz[AmmoType].Slot);
   230         PackAmmo(Ammo, Ammoz[AmmoType].Slot);
   220             CurAmmoType:= amNothing
   231         CurAmmoType:= amNothing
   221             end
   232         end
   222 end;
   233 end;
   223 
   234 
   224 procedure PackAmmo(Ammo: PHHAmmo; Slot: LongInt);
   235 procedure PackAmmo(Ammo: PHHAmmo; Slot: LongInt);
   225 var ami: LongInt;
   236 var ami: LongInt;
   226     b: boolean;
   237     b: boolean;
   227 begin
   238 begin
   228     repeat
   239     repeat
   229       b:= false;
   240         b:= false;
   230       ami:= 0;
   241         ami:= 0;
   231       while (not b) and (ami < cMaxSlotAmmoIndex) do
   242         while (not b) and (ami < cMaxSlotAmmoIndex) do
   232           if (Ammo^[Slot, ami].Count = 0)
   243             if (Ammo^[Slot, ami].Count = 0)
   233              and (Ammo^[Slot, ami + 1].Count > 0) then b:= true
   244             and (Ammo^[Slot, ami + 1].Count > 0) then
   234                                                   else inc(ami);
   245                 b:= true
   235       if b then // there is a free item in ammo stack
   246             else
   236          begin
   247                 inc(ami);
   237          Ammo^[Slot, ami]:= Ammo^[Slot, ami + 1];
   248         if b then // there is a free item in ammo stack
   238          Ammo^[Slot, ami + 1].Count:= 0
   249             begin
   239          end;
   250             Ammo^[Slot, ami]:= Ammo^[Slot, ami + 1];
       
   251             Ammo^[Slot, ami + 1].Count:= 0
       
   252             end;
   240     until not b;
   253     until not b;
   241 end;
   254 end;
   242 
   255 
   243 procedure OnUsedAmmo(var Hedgehog: THedgehog);
   256 procedure OnUsedAmmo(var Hedgehog: THedgehog);
   244 var CurWeapon: PAmmo;
   257 var CurWeapon: PAmmo;
   267 var slot, ami: LongInt;
   280 var slot, ami: LongInt;
   268 begin
   281 begin
   269 Slot:= Ammoz[Ammo].Slot;
   282 Slot:= Ammoz[Ammo].Slot;
   270 ami:= 0;
   283 ami:= 0;
   271 while (ami <= cMaxSlotAmmoIndex) do
   284 while (ami <= cMaxSlotAmmoIndex) do
   272       begin
   285         begin
   273       with Hedgehog.Ammo^[Slot, ami] do
   286         with Hedgehog.Ammo^[Slot, ami] do
   274             if (AmmoType = Ammo) then
   287             if (AmmoType = Ammo) then
   275                exit((Count > 0) and (Hedgehog.Team^.Clan^.TurnNumber > Ammoz[AmmoType].SkipTurns));
   288                 exit((Count > 0) and (Hedgehog.Team^.Clan^.TurnNumber > Ammoz[AmmoType].SkipTurns));
   276       inc(ami)
   289       inc(ami)
   277       end;
   290       end;
   278 HHHasAmmo:= false
   291 HHHasAmmo:= false
   279 end;
   292 end;
   280 
   293 
   288     else
   301     else
   289         CurMaxAngle:= cMaxAngle;
   302         CurMaxAngle:= cMaxAngle;
   290 
   303 
   291     with Hedgehog.Gear^ do
   304     with Hedgehog.Gear^ do
   292         begin
   305         begin
   293         if Angle < CurMinAngle then Angle:= CurMinAngle;
   306         if Angle < CurMinAngle then
   294         if Angle > CurMaxAngle then Angle:= CurMaxAngle;
   307             Angle:= CurMinAngle;
       
   308         if Angle > CurMaxAngle then
       
   309             Angle:= CurMaxAngle;
   295         end
   310         end
   296     end
   311     end
   297 end;
   312 end;
   298 
   313 
   299 procedure SwitchToFirstLegalAmmo(var Hedgehog: THedgehog);
   314 procedure SwitchToFirstLegalAmmo(var Hedgehog: THedgehog);
   306     ammoidx:= 0;
   321     ammoidx:= 0;
   307     while (slot <= cMaxSlotIndex) and
   322     while (slot <= cMaxSlotIndex) and
   308         ((Ammo^[slot, ammoidx].Count = 0) or
   323         ((Ammo^[slot, ammoidx].Count = 0) or
   309         (Ammoz[Ammo^[slot, ammoidx].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber >= 0))
   324         (Ammoz[Ammo^[slot, ammoidx].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber >= 0))
   310         do
   325         do
   311         begin
   326             begin
   312         while (ammoidx <= cMaxSlotAmmoIndex) and
   327             while (ammoidx <= cMaxSlotAmmoIndex)
   313             ((Ammo^[slot, ammoidx].Count = 0) or
   328             and ((Ammo^[slot, ammoidx].Count = 0) or (Ammoz[Ammo^[slot, ammoidx].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber >= 0))
   314             (Ammoz[Ammo^[slot, ammoidx].AmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber >= 0))
   329                 do inc(ammoidx);
   315             do inc(ammoidx);
       
   316 
   330 
   317         if (ammoidx > cMaxSlotAmmoIndex) then
   331         if (ammoidx > cMaxSlotAmmoIndex) then
   318             begin
   332             begin
   319             ammoidx:= 0;
   333             ammoidx:= 0;
   320             inc(slot)
   334             inc(slot)
   337 
   351 
   338     CurWeapon:= GetAmmoEntry(Hedgehog);
   352     CurWeapon:= GetAmmoEntry(Hedgehog);
   339 
   353 
   340     if (CurWeapon^.Count = 0) then
   354     if (CurWeapon^.Count = 0) then
   341         SwitchToFirstLegalAmmo(Hedgehog)
   355         SwitchToFirstLegalAmmo(Hedgehog)
   342     else if CurWeapon^.AmmoType = amNothing then Hedgehog.CurAmmoType:= amNothing;
   356     else if CurWeapon^.AmmoType = amNothing then
       
   357         Hedgehog.CurAmmoType:= amNothing;
   343 
   358 
   344     CurWeapon:= GetAmmoEntry(Hedgehog);
   359     CurWeapon:= GetAmmoEntry(Hedgehog);
   345 
   360 
   346     ApplyAngleBounds(Hedgehog, CurWeapon^.AmmoType);
   361     ApplyAngleBounds(Hedgehog, CurWeapon^.AmmoType);
   347 
   362 
   351         if (Count <> AMMO_INFINITE) and not (Hedgehog.Team^.ExtDriven or (Hedgehog.BotLevel > 0)) then
   366         if (Count <> AMMO_INFINITE) and not (Hedgehog.Team^.ExtDriven or (Hedgehog.BotLevel > 0)) then
   352             s:= s + ' (' + IntToStr(Count) + ')';
   367             s:= s + ' (' + IntToStr(Count) + ')';
   353         if (Propz and ammoprop_Timerable) <> 0 then
   368         if (Propz and ammoprop_Timerable) <> 0 then
   354             s:= s + ', ' + IntToStr(Timer div 1000) + ' ' + trammo[sidSeconds];
   369             s:= s + ', ' + IntToStr(Timer div 1000) + ' ' + trammo[sidSeconds];
   355         AddCaption(s, Team^.Clan^.Color, capgrpAmmoinfo);
   370         AddCaption(s, Team^.Clan^.Color, capgrpAmmoinfo);
   356         if (Propz and ammoprop_NeedTarget) <> 0
   371         if (Propz and ammoprop_NeedTarget) <> 0 then
   357             then begin
   372             begin
   358             Gear^.State:= Gear^.State or      gstHHChooseTarget;
   373             Gear^.State:= Gear^.State or      gstHHChooseTarget;
   359             isCursorVisible:= true
   374             isCursorVisible:= true
   360             end else begin
   375             end
       
   376         else
       
   377             begin
   361             Gear^.State:= Gear^.State and not gstHHChooseTarget;
   378             Gear^.State:= Gear^.State and not gstHHChooseTarget;
   362             isCursorVisible:= false
   379             isCursorVisible:= false
   363             end;
   380             end;
   364         end
   381         end
   365     end;
   382     end;
   366 end;
   383 end;
   367 
   384 
   368 procedure SwitchNotHeldAmmo(var Hedgehog: THedgehog);
   385 procedure SwitchNotHeldAmmo(var Hedgehog: THedgehog);
   369 begin
   386 begin
   370 with Hedgehog do
   387 with Hedgehog do
   371     if ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_DontHold) <> 0) or
   388     if ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_DontHold) <> 0)
   372         (Ammoz[CurAmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber >= 0) then
   389     or (Ammoz[CurAmmoType].SkipTurns - CurrentTeam^.Clan^.TurnNumber >= 0) then
   373         SwitchToFirstLegalAmmo(Hedgehog);
   390         SwitchToFirstLegalAmmo(Hedgehog);
   374 end;
   391 end;
   375 
   392 
   376 procedure SetWeapon(weap: TAmmoType);
   393 procedure SetWeapon(weap: TAmmoType);
   377 begin
   394 begin
   395 
   412 
   396         PackAmmo(StoresList[i], slot)
   413         PackAmmo(StoresList[i], slot)
   397         end;
   414         end;
   398 
   415 
   399 for t:= Low(TAmmoType) to High(TAmmoType) do
   416 for t:= Low(TAmmoType) to High(TAmmoType) do
   400     if (Ammoz[t].Ammo.Propz and ammoprop_NotBorder) <> 0 then Ammoz[t].Probability:= 0
   417     if (Ammoz[t].Ammo.Propz and ammoprop_NotBorder) <> 0 then
       
   418         Ammoz[t].Probability:= 0
   401 end;
   419 end;
   402 
   420 
   403 procedure SetAmmoLoadout(s: shortstring);
   421 procedure SetAmmoLoadout(s: shortstring);
   404 begin
   422 begin
   405     ammoLoadout:= s;
   423     ammoLoadout:= s;
   424 procedure ResetWeapons;
   442 procedure ResetWeapons;
   425 var i, t: Longword;
   443 var i, t: Longword;
   426     a: TAmmoType;
   444     a: TAmmoType;
   427 begin
   445 begin
   428 for t:= 0 to Pred(TeamsCount) do
   446 for t:= 0 to Pred(TeamsCount) do
   429    with TeamsArray[t]^ do
   447     with TeamsArray[t]^ do
   430       for i:= 0 to cMaxHHIndex do
   448         for i:= 0 to cMaxHHIndex do
   431          Hedgehogs[i].CurAmmoType:= amNothing;
   449             Hedgehogs[i].CurAmmoType:= amNothing;
   432 
   450 
   433 for i:= 0 to Pred(StoreCnt) do FillAmmoStore(StoresList[i], InitialCounts[i]);
   451 for i:= 0 to Pred(StoreCnt) do
       
   452     FillAmmoStore(StoresList[i], InitialCounts[i]);
   434 
   453 
   435 for a:= Low(TAmmoType) to High(TAmmoType) do
   454 for a:= Low(TAmmoType) to High(TAmmoType) do
   436     if Ammoz[a].SkipTurns >= 10000 then dec(Ammoz[a].SkipTurns,10000)
   455     if Ammoz[a].SkipTurns >= 10000 then
       
   456         dec(Ammoz[a].SkipTurns,10000)
   437 end;
   457 end;
   438 
   458 
   439 
   459 
   440 
   460 
   441 procedure chAddAmmoStore(var descr: shortstring);
   461 procedure chAddAmmoStore(var descr: shortstring);
   462 
   482 
   463 procedure freeModule;
   483 procedure freeModule;
   464 var i: LongWord;
   484 var i: LongWord;
   465 begin
   485 begin
   466     if StoreCnt > 0 then
   486     if StoreCnt > 0 then
   467         for i:= 0 to Pred(StoreCnt) do Dispose(StoresList[i])
   487         for i:= 0 to Pred(StoreCnt) do
       
   488             Dispose(StoresList[i])
   468 end;
   489 end;
   469 
   490 
   470 end.
   491 end.