DEADSOFTWARE

Add flamethrower weapon, item and ammo
[d2df-sdl.git] / src / game / g_player.pas
index 7dd22f870f497aec99735edd27f4caa7887e7a60..d03247cdc5e4e3f2505078aa28ccd5f165f70f55 100644 (file)
@@ -50,6 +50,12 @@ const
   A_SHELLS          = 1;
   A_ROCKETS         = 2;
   A_CELLS           = 3;
+  A_FUEL            = 4;
+  A_HIGH            = 4;
+
+  AmmoLimits: Array [0..1] of Array [A_BULLETS..A_HIGH] of Word =
+  ((200,  50,  50, 300, 100),
+   (400, 100, 100, 600, 200));
 
   K_SIMPLEKILL      = 0;
   K_HARDKILL        = 1;
@@ -114,8 +120,8 @@ type
     CurrWeap:   Byte;
     NextWeap:   WORD;
     NextWeapDelay: Byte;
-    Ammo:       Array [A_BULLETS..A_CELLS] of Word;
-    MaxAmmo:    Array [A_BULLETS..A_CELLS] of Word;
+    Ammo:       Array [A_BULLETS..A_HIGH] of Word;
+    MaxAmmo:    Array [A_BULLETS..A_HIGH] of Word;
     Weapon:     Array [WP_FIRST..WP_LAST] of Boolean;
     Rulez:      Set of R_ITEM_BACKPACK..R_BERSERK;
     WaitRecall: Boolean;
@@ -216,8 +222,8 @@ type
   public
     FDamageBuffer:   Integer;
 
-    FAmmo:      Array [A_BULLETS..A_CELLS] of Word;
-    FMaxAmmo:   Array [A_BULLETS..A_CELLS] of Word;
+    FAmmo:      Array [A_BULLETS..A_HIGH] of Word;
+    FMaxAmmo:   Array [A_BULLETS..A_HIGH] of Word;
     FWeapon:    Array [WP_FIRST..WP_LAST] of Boolean;
     FRulez:     Set of R_ITEM_BACKPACK..R_BERSERK;
     FBerserk:   Integer;
@@ -542,27 +548,30 @@ const
                                                    (R:0; G:0; B:255));
   DIFFICULT_EASY: TDifficult = (DiagFire: 32; InvisFire: 32; DiagPrecision: 32;
                                 FlyPrecision: 32; Cover: 32; CloseJump: 32;
-                                WeaponPrior:(0,0,0,0,0,0,0,0,0,0); CloseWeaponPrior:(0,0,0,0,0,0,0,0,0,0));
+                                WeaponPrior:(0,0,0,0,0,0,0,0,0,0,0); CloseWeaponPrior:(0,0,0,0,0,0,0,0,0,0,0));
   DIFFICULT_MEDIUM: TDifficult = (DiagFire: 127; InvisFire: 127; DiagPrecision: 127;
                                   FlyPrecision: 127; Cover: 127; CloseJump: 127;
-                                WeaponPrior:(0,0,0,0,0,0,0,0,0,0); CloseWeaponPrior:(0,0,0,0,0,0,0,0,0,0));
+                                WeaponPrior:(0,0,0,0,0,0,0,0,0,0,0); CloseWeaponPrior:(0,0,0,0,0,0,0,0,0,0,0));
   DIFFICULT_HARD: TDifficult = (DiagFire: 255; InvisFire: 255; DiagPrecision: 255;
                                 FlyPrecision: 255; Cover: 255; CloseJump: 255;
-                                WeaponPrior:(0,0,0,0,0,0,0,0,0,0); CloseWeaponPrior:(0,0,0,0,0,0,0,0,0,0));
+                                WeaponPrior:(0,0,0,0,0,0,0,0,0,0,0); CloseWeaponPrior:(0,0,0,0,0,0,0,0,0,0,0));
   WEAPON_PRIOR1: Array [WP_FIRST..WP_LAST] of Byte =
-                                (WEAPON_SUPERPULEMET, WEAPON_SHOTGUN2, WEAPON_SHOTGUN1,
+                                (WEAPON_FLAMETHROWER, WEAPON_SUPERPULEMET,
+                                 WEAPON_SHOTGUN2, WEAPON_SHOTGUN1,
                                  WEAPON_CHAINGUN, WEAPON_PLASMA, WEAPON_ROCKETLAUNCHER,
                                  WEAPON_BFG, WEAPON_PISTOL, WEAPON_SAW, WEAPON_KASTET);
   WEAPON_PRIOR2: Array [WP_FIRST..WP_LAST] of Byte =
-                                (WEAPON_SUPERPULEMET, WEAPON_BFG, WEAPON_ROCKETLAUNCHER,
+                                (WEAPON_FLAMETHROWER, WEAPON_SUPERPULEMET,
+                                 WEAPON_BFG, WEAPON_ROCKETLAUNCHER,
                                  WEAPON_SHOTGUN2, WEAPON_PLASMA, WEAPON_SHOTGUN1,
                                  WEAPON_CHAINGUN, WEAPON_PISTOL, WEAPON_SAW, WEAPON_KASTET);
   //WEAPON_PRIOR3: Array [WP_FIRST..WP_LAST] of Byte =
-  //                              (WEAPON_SUPERPULEMET, WEAPON_BFG, WEAPON_PLASMA,
-  //                               WEAPON_SHOTGUN2, WEAPON_CHAINGUN, WEAPON_SHOTGUN1,
-  //                               WEAPON_SAW, WEAPON_ROCKETLAUNCHER, WEAPON_PISTOL, WEAPON_KASTET);
+  //                              (WEAPON_FLAMETHROWER, WEAPON_SUPERPULEMET,
+  //                               WEAPON_BFG, WEAPON_PLASMA, WEAPON_SHOTGUN2,
+  //                               WEAPON_CHAINGUN, WEAPON_SHOTGUN1, WEAPON_SAW,
+  //                               WEAPON_ROCKETLAUNCHER, WEAPON_PISTOL, WEAPON_KASTET);
   WEAPON_RELOAD: Array [WP_FIRST..WP_LAST] of Byte =
-                                (5, 2, 6, 18, 36, 2, 12, 2, 14, 2);
+                                (5, 2, 6, 18, 36, 2, 12, 2, 14, 2, 0);
 
   PLAYER_SIGNATURE = $52594C50; // 'PLYR'
   CORPSE_SIGNATURE = $50524F43; // 'CORP'
@@ -822,10 +831,10 @@ begin
 // Îáúåêò èãðîêà:
   Obj_LoadState(@gPlayers[a].FObj, Mem);
 // Òåêóùåå êîëè÷åñòâî ïàòðîíîâ:
-  for i := A_BULLETS to A_CELLS do
+  for i := A_BULLETS to A_HIGH do
     Mem.ReadWord(gPlayers[a].FAmmo[i]);
 // Ìàêñèìàëüíîå êîëè÷åñòâî ïàòðîíîâ:
-  for i := A_BULLETS to A_CELLS do
+  for i := A_BULLETS to A_HIGH do
     Mem.ReadWord(gPlayers[a].FMaxAmmo[i]);
 // Íàëè÷èå îðóæèÿ:
   for i := WP_FIRST to WP_LAST do
@@ -2487,6 +2496,7 @@ begin
     WEAPON_ROCKETLAUNCHER: ID := gItemsTexturesID[ITEM_WEAPON_ROCKETLAUNCHER];
     WEAPON_PLASMA: ID := gItemsTexturesID[ITEM_WEAPON_PLASMA];
     WEAPON_BFG: ID := gItemsTexturesID[ITEM_WEAPON_BFG];
+    WEAPON_FLAMETHROWER: ID := gItemsTexturesID[ITEM_WEAPON_FLAMETHROWER];
   end;
 
   e_CharFont_GetSize(gMenuFont, s, tw, th);
@@ -2794,6 +2804,16 @@ begin
         g_Player_CreateShell(GameX+PLAYER_RECT_CX, GameY+PLAYER_RECT_CX,
                              GameVelX, GameVelY-2, SHELL_SHELL);
       end;
+
+    WEAPON_FLAMETHROWER:
+      if FAmmo[A_FUEL] > 0 then
+      begin
+        FReloading[FCurrWeap] := WEAPON_RELOAD[FCurrWeap];
+        Dec(FAmmo[A_FUEL]);
+        FFireAngle := FAngle;
+        f := True;
+        DidFire := True;
+      end;
   end;
 
   if g_Game_IsNet then
@@ -2824,6 +2844,7 @@ begin
     WEAPON_SHOTGUN1, WEAPON_SHOTGUN2, WEAPON_SUPERPULEMET: Result := FAmmo[A_SHELLS];
     WEAPON_ROCKETLAUNCHER: Result := FAmmo[A_ROCKETS];
     WEAPON_PLASMA, WEAPON_BFG: Result := FAmmo[A_CELLS];
+    WEAPON_FLAMETHROWER: Result := FAmmo[A_FUEL];
     else Result := 0;
   end;
 end;
@@ -3095,6 +3116,7 @@ begin
           WEAPON_PLASMA: i := ITEM_WEAPON_PLASMA;
           WEAPON_BFG: i := ITEM_WEAPON_BFG;
           WEAPON_SUPERPULEMET: i := ITEM_WEAPON_SUPERPULEMET;
+          WEAPON_FLAMETHROWER: i := ITEM_WEAPON_FLAMETHROWER;
           else i := 0;
         end;
 
@@ -3302,6 +3324,7 @@ begin
     WEAPON_PISTOL, WEAPON_CHAINGUN, WEAPON_SUPERPULEMET: result := (FAmmo[A_BULLETS] > 0);
     WEAPON_ROCKETLAUNCHER: result := (FAmmo[A_ROCKETS] > 0);
     WEAPON_PLASMA, WEAPON_BFG: result := (FAmmo[A_CELLS] > 0);
+    WEAPON_FLAMETHROWER: result := (FAmmo[A_FUEL] > 0);
     else result := (weapon < length(FWeapon));
   end;
 end;
@@ -3606,6 +3629,18 @@ begin
         if a and g_Game_IsNet then MH_SEND_Sound(GameX, GameY, 'SOUND_ITEM_GETWEAPON');
       end;
 
+    ITEM_WEAPON_FLAMETHROWER:
+      if (FAmmo[A_FUEL] < FMaxAmmo[A_FUEL]) or not FWeapon[WEAPON_FLAMETHROWER] then
+      begin
+        if a and FWeapon[WEAPON_FLAMETHROWER] then Exit;
+
+        IncMax(FAmmo[A_FUEL], 100, FMaxAmmo[A_FUEL]);
+        FWeapon[WEAPON_FLAMETHROWER] := True;
+        Result := True;
+        if gFlash = 2 then Inc(FPickup, 5);
+        if a and g_Game_IsNet then MH_SEND_Sound(GameX, GameY, 'SOUND_ITEM_GETWEAPON');
+      end;
+
     ITEM_AMMO_BULLETS:
       if FAmmo[A_BULLETS] < FMaxAmmo[A_BULLETS] then
       begin
@@ -3678,17 +3713,28 @@ begin
         if gFlash = 2 then Inc(FPickup, 5);
       end;
 
+    ITEM_AMMO_FUELCAN:
+      if FAmmo[A_FUEL] < FMaxAmmo[A_FUEL] then
+      begin
+        IncMax(FAmmo[A_FUEL], 100, FMaxAmmo[A_FUEL]);
+        Result := True;
+        remove := True;
+        if gFlash = 2 then Inc(FPickup, 5);
+      end;
+
     ITEM_AMMO_BACKPACK:
       if not(R_ITEM_BACKPACK in FRulez) or
             (FAmmo[A_BULLETS] < FMaxAmmo[A_BULLETS]) or
             (FAmmo[A_SHELLS] < FMaxAmmo[A_SHELLS]) or
             (FAmmo[A_ROCKETS] < FMaxAmmo[A_ROCKETS]) or
-            (FAmmo[A_CELLS] < FMaxAmmo[A_CELLS]) then
+            (FAmmo[A_CELLS] < FMaxAmmo[A_CELLS]) or
+            (FMaxAmmo[A_FUEL] < AmmoLimits[1, A_FUEL]) then
       begin
-        FMaxAmmo[A_BULLETS] := 400;
-        FMaxAmmo[A_SHELLS] := 100;
-        FMaxAmmo[A_ROCKETS] := 100;
-        FMaxAmmo[A_CELLS] := 600;
+        FMaxAmmo[A_BULLETS] := AmmoLimits[1, A_BULLETS];
+        FMaxAmmo[A_SHELLS] := AmmoLimits[1, A_SHELLS];
+        FMaxAmmo[A_ROCKETS] := AmmoLimits[1, A_ROCKETS];
+        FMaxAmmo[A_CELLS] := AmmoLimits[1, A_CELLS];
+        FMaxAmmo[A_FUEL] := AmmoLimits[1, A_FUEL];
 
         if FAmmo[A_BULLETS] < FMaxAmmo[A_BULLETS] then
           IncMax(FAmmo[A_BULLETS], 10, FMaxAmmo[A_BULLETS]);
@@ -4120,15 +4166,16 @@ begin
 
     FModel.SetWeapon(FCurrWeap);
 
-    for b := A_BULLETS to A_CELLS do
+    for b := A_BULLETS to A_HIGH do
       FAmmo[b] := 0;
 
     FAmmo[A_BULLETS] := 50;
 
-    FMaxAmmo[A_BULLETS] := 200;
-    FMaxAmmo[A_SHELLS] := 50;
-    FMaxAmmo[A_ROCKETS] := 50;
-    FMaxAmmo[A_CELLS] := 300;
+    FMaxAmmo[A_BULLETS] := AmmoLimits[0, A_BULLETS];
+    FMaxAmmo[A_SHELLS] := AmmoLimits[0, A_SHELLS];
+    FMaxAmmo[A_ROCKETS] := AmmoLimits[0, A_SHELLS];
+    FMaxAmmo[A_CELLS] := AmmoLimits[0, A_CELLS];
+    FMaxAmmo[A_FUEL] := AmmoLimits[0, A_FUEL];
 
     if gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF] then
       FRulez := [R_KEY_RED, R_KEY_GREEN, R_KEY_BLUE]
@@ -5037,6 +5084,12 @@ begin
       g_Player_CreateShell(GameX+PLAYER_RECT_CX, GameY+PLAYER_RECT_CX,
                              GameVelX, GameVelY-2, SHELL_SHELL);
     end;
+
+    WEAPON_FLAMETHROWER:
+    begin
+      FFireAngle := FAngle;
+      f := True;
+    end;
   end;
 
   if not f then Exit;
@@ -5392,10 +5445,10 @@ begin
 // Îáúåêò èãðîêà:
   Obj_SaveState(@FObj, Mem);
 // Òåêóùåå êîëè÷åñòâî ïàòðîíîâ:
-  for i := A_BULLETS to A_CELLS do
+  for i := A_BULLETS to A_HIGH do
     Mem.WriteWord(FAmmo[i]);
 // Ìàêñèìàëüíîå êîëè÷åñòâî ïàòðîíîâ:
-  for i := A_BULLETS to A_CELLS do
+  for i := A_BULLETS to A_HIGH do
     Mem.WriteWord(FMaxAmmo[i]);
 // Íàëè÷èå îðóæèÿ:
   for i := WP_FIRST to WP_LAST do
@@ -5532,10 +5585,10 @@ begin
 // Îáúåêò èãðîêà:
   Obj_LoadState(@FObj, Mem);
 // Òåêóùåå êîëè÷åñòâî ïàòðîíîâ:
-  for i := A_BULLETS to A_CELLS do
+  for i := A_BULLETS to A_HIGH do
     Mem.ReadWord(FAmmo[i]);
 // Ìàêñèìàëüíîå êîëè÷åñòâî ïàòðîíîâ:
-  for i := A_BULLETS to A_CELLS do
+  for i := A_BULLETS to A_HIGH do
     Mem.ReadWord(FMaxAmmo[i]);
 // Íàëè÷èå îðóæèÿ:
   for i := WP_FIRST to WP_LAST do
@@ -5605,7 +5658,7 @@ begin
   end;
 
   for a := WP_FIRST to WP_LAST do FWeapon[a] := True;
-  for a := A_BULLETS to A_CELLS do FAmmo[a] := 30000;
+  for a := A_BULLETS to A_HIGH do FAmmo[a] := 30000;
   FRulez := FRulez+[R_KEY_RED, R_KEY_GREEN, R_KEY_BLUE];
 end;
 
@@ -5721,6 +5774,7 @@ begin
     ITEM_WEAPON_PLASMA: FWeapon[WEAPON_PLASMA] := True;
     ITEM_WEAPON_BFG: FWeapon[WEAPON_BFG] := True;
     ITEM_WEAPON_SUPERPULEMET: FWeapon[WEAPON_SUPERPULEMET] := True;
+    ITEM_WEAPON_FLAMETHROWER: FWeapon[WEAPON_FLAMETHROWER] := True;
 
     ITEM_AMMO_BULLETS: if FAmmo[A_BULLETS] < FMaxAmmo[A_BULLETS] then IncMax(FAmmo[A_BULLETS], 10, FMaxAmmo[A_BULLETS]);
     ITEM_AMMO_BULLETS_BOX: if FAmmo[A_BULLETS] < FMaxAmmo[A_BULLETS] then IncMax(FAmmo[A_BULLETS], 50, FMaxAmmo[A_BULLETS]);
@@ -5730,17 +5784,20 @@ begin
     ITEM_AMMO_ROCKET_BOX: if FAmmo[A_ROCKETS] < FMaxAmmo[A_ROCKETS] then IncMax(FAmmo[A_ROCKETS], 5, FMaxAmmo[A_ROCKETS]);
     ITEM_AMMO_CELL: if FAmmo[A_CELLS] < FMaxAmmo[A_CELLS] then IncMax(FAmmo[A_CELLS], 40, FMaxAmmo[A_CELLS]);
     ITEM_AMMO_CELL_BIG: if FAmmo[A_CELLS] < FMaxAmmo[A_CELLS] then IncMax(FAmmo[A_CELLS], 100, FMaxAmmo[A_CELLS]);
+    ITEM_AMMO_FUELCAN: if FAmmo[A_FUEL] < FMaxAmmo[A_FUEL] then IncMax(FAmmo[A_FUEL], 100, FMaxAmmo[A_FUEL]);
 
     ITEM_AMMO_BACKPACK:
       if (FAmmo[A_BULLETS] < FMaxAmmo[A_BULLETS]) or
          (FAmmo[A_SHELLS] < FMaxAmmo[A_SHELLS]) or
          (FAmmo[A_ROCKETS] < FMaxAmmo[A_ROCKETS]) or
-         (FAmmo[A_CELLS] < FMaxAmmo[A_CELLS]) then
+         (FAmmo[A_CELLS] < FMaxAmmo[A_CELLS]) or
+         (FMaxAmmo[A_FUEL] < AmmoLimits[1, A_FUEL]) then
       begin
-        FMaxAmmo[A_BULLETS] := 400;
-        FMaxAmmo[A_SHELLS] := 100;
-        FMaxAmmo[A_ROCKETS] := 100;
-        FMaxAmmo[A_CELLS] := 600;
+        FMaxAmmo[A_BULLETS] := AmmoLimits[1, A_BULLETS];
+        FMaxAmmo[A_SHELLS] := AmmoLimits[1, A_SHELLS];
+        FMaxAmmo[A_ROCKETS] := AmmoLimits[1, A_ROCKETS];
+        FMaxAmmo[A_CELLS] := AmmoLimits[1, A_CELLS];
+        FMaxAmmo[A_FUEL] := AmmoLimits[1, A_FUEL];
 
         if FAmmo[A_BULLETS] < FMaxAmmo[A_BULLETS] then IncMax(FAmmo[A_BULLETS], 10, FMaxAmmo[A_BULLETS]);
         if FAmmo[A_SHELLS] < FMaxAmmo[A_SHELLS] then IncMax(FAmmo[A_SHELLS], 4, FMaxAmmo[A_SHELLS]);
@@ -6105,7 +6162,7 @@ begin
 
       case FCurrWeap of
         WEAPON_PLASMA, WEAPON_SUPERPULEMET, WEAPON_CHAINGUN: PressKey(KEY_FIRE, 20);
-        WEAPON_SAW, WEAPON_KASTET, WEAPON_MEGAKASTET: PressKey(KEY_FIRE, 40);
+        WEAPON_SAW, WEAPON_KASTET, WEAPON_FLAMETHROWER: PressKey(KEY_FIRE, 40);
         else PressKey(KEY_FIRE);
       end;
     end;
@@ -7077,6 +7134,7 @@ var
       WEAPON_PLASMA: Result := FAmmo[A_CELLS] >= 10;
       WEAPON_BFG: Result := FAmmo[A_CELLS] >= 40;
       WEAPON_SUPERPULEMET: Result := FAmmo[A_SHELLS] >= 1;
+      WEAPON_FLAMETHROWER: Result := FAmmo[A_FUEL] >= 1;
       else Result := True;
     end;
   end;