DEADSOFTWARE

fix small spider pain sound and sensitivity
[d2df-sdl.git] / src / game / g_monsters.pas
index 15790197f17980f45913930944a37349e8bec432..cde1aad4dff139c91b8ffdf65997fa9ce4ba1a3e 100644 (file)
@@ -1,3 +1,19 @@
+(* Copyright (C)  DooM 2D:Forever Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *)
+{$MODE DELPHI}
 unit g_monsters;
 
 interface
@@ -48,6 +64,7 @@ type
     FPain: Integer;
     FSleep: Integer;
     FPainSound: Boolean;
+    FPainTicks: Integer;
     FWaitAttackAnim: Boolean;
     FChainFire: Boolean;
     tx, ty: Integer;
@@ -158,7 +175,7 @@ implementation
 uses
   e_log, g_main, g_sound, g_gfx, g_player, g_game,
   g_weapons, g_triggers, MAPDEF, g_items, g_options,
-  g_console, g_map, Math, SysUtils, g_menu, WADEDITOR,
+  g_console, g_map, Math, SysUtils, g_menu, wadreader,
   g_language, g_netmsg;
 
 const
@@ -220,7 +237,7 @@ const
 
     (Name:'SERG'; Rect:(X:15; Y:8; Width:34; Height:52); Health:20;
      RunVel: 3; MinPain: 0; Pain: 10; Jump: 10),
-                                          
+
     (Name:'CYBER'; Rect:(X:24; Y:9; Width:80; Height:110); Health:500;
      RunVel: 5; MinPain: 50; Pain: 70; Jump: 10),
 
@@ -294,9 +311,9 @@ const
      AnimDeltaRight: ((X:  0; Y: -4), (X:  0; Y: -4), (X: -3; Y: -1), (X: -4; Y: -1), (X:  1; Y: -4), (X:  1; Y: -4), (X:  0; Y: -4));
      AnimDeltaLeft:  ((X:  0; Y: -4), (X:  0; Y: -4), (X: -3; Y: -1), (X: -4; Y: -1), (X:  1; Y: -4), (X:  1; Y: -4), (X:  0; Y: -4))),
 
-    (LeftAnim: True; wX: 70; wY: 73; AnimSpeed:(3, 3, 3, 3, 3, 0, 3);  //CYBER
-     AnimDeltaRight: ((X:  2; Y: -6), (X:  2; Y: -6), (X: -3; Y: -4), (X: -3; Y: -4), (X: 25; Y: -6), (X: 25; Y: -6), (X: -2; Y: -6));
-     AnimDeltaLeft:  ((X:  3; Y: -3), (X:  3; Y: -3), (X: -3; Y: -4), (X: -3; Y: -4), (X:-26; Y: -3), (X:-26; Y: -3), (X:  1; Y: -3))),
+    (LeftAnim: True; wX: 70; wY: 73; AnimSpeed:(3, 3, 3, 3, 3, 4, 3);  //CYBER
+     AnimDeltaRight: ((X:  2; Y: -6), (X:  2; Y: -6), (X: -3; Y: -4), (X: -3; Y: -4), (X: 25; Y: -6), (X: 0; Y: -6), (X: -2; Y: -6));
+     AnimDeltaLeft:  ((X:  3; Y: -3), (X:  3; Y: -3), (X: -3; Y: -4), (X: -3; Y: -4), (X:-26; Y: -3), (X:-1; Y: -3), (X:  1; Y: -3))),
 
     (LeftAnim: True; wX: 32; wY: 32; AnimSpeed:(3, 2, 2, 2, 1, 0, 4);  //CGUN
      AnimDeltaRight: ((X: -1; Y: -2), (X: -1; Y: -2), (X: -2; Y:  0), (X: -2; Y:  0), (X:  0; Y: -3), (X:  0; Y: -3), (X: -1; Y: -2));
@@ -642,6 +659,8 @@ begin
   g_Frames_CreateWAD(nil, 'FRAMES_MONSTER_CYBER_PAIN_L', GameWAD+':MTEXTURES\CYBER_PAIN_L', 128, 128, 1);
   g_Frames_CreateWAD(nil, 'FRAMES_MONSTER_CYBER_ATTACK', GameWAD+':MTEXTURES\CYBER_ATTACK', 128, 128, 2);
   g_Frames_CreateWAD(nil, 'FRAMES_MONSTER_CYBER_ATTACK_L', GameWAD+':MTEXTURES\CYBER_ATTACK_L', 128, 128, 2);
+  g_Frames_CreateWAD(nil, 'FRAMES_MONSTER_CYBER_ATTACK2', GameWAD+':MTEXTURES\CYBER_ATTACK2', 128, 128, 2);
+  g_Frames_CreateWAD(nil, 'FRAMES_MONSTER_CYBER_ATTACK2_L', GameWAD+':MTEXTURES\CYBER_ATTACK2_L', 128, 128, 2);
   g_Frames_CreateWAD(nil, 'FRAMES_MONSTER_CYBER_DIE', GameWAD+':MTEXTURES\CYBER_DIE', 128, 128, 9);
 
   g_Game_SetLoadingText(_lc[I_LOAD_MONSTER_SOUNDS], 0, False);
@@ -858,6 +877,8 @@ begin
   g_Frames_DeleteByName('FRAMES_MONSTER_CYBER_PAIN_L');
   g_Frames_DeleteByName('FRAMES_MONSTER_CYBER_ATTACK');
   g_Frames_DeleteByName('FRAMES_MONSTER_CYBER_ATTACK_L');
+  g_Frames_DeleteByName('FRAMES_MONSTER_CYBER_ATTACK2');
+  g_Frames_DeleteByName('FRAMES_MONSTER_CYBER_ATTACK2_L');
   g_Frames_DeleteByName('FRAMES_MONSTER_CYBER_DIE');
 
   g_Sound_Delete('SOUND_MONSTER_BARREL_DIE');
@@ -1051,7 +1072,7 @@ begin
             gMonsters[a].Update();
         end
         else
-          begin 
+          begin
             gMonsters[a].Free();
             gMonsters[a] := nil;
           end;
@@ -1248,6 +1269,7 @@ begin
     Exit;
 
   FPainSound := True;
+  FPainTicks := 20;
 
   case FMonsterType of
     MONSTER_IMP, MONSTER_ZOMBY, MONSTER_SERG,
@@ -1255,7 +1277,7 @@ begin
       g_Sound_PlayExAt('SOUND_MONSTER_PAIN', FObj.X, FObj.Y);
     MONSTER_SOUL, MONSTER_BARON, MONSTER_CACO,
     MONSTER_KNIGHT, MONSTER_DEMON, MONSTER_SPIDER,
-    MONSTER_CYBER:
+    MONSTER_BSP, MONSTER_CYBER:
       g_Sound_PlayExAt('SOUND_MONSTER_PAIN2', FObj.X, FObj.Y);
     MONSTER_VILE:
       g_Sound_PlayExAt('SOUND_MONSTER_VILE_PAIN', FObj.X, FObj.Y);
@@ -1416,7 +1438,7 @@ begin
   FWaitAttackAnim := False;
   FChainFire := False;
   FShellTimer := -1;
-  
+
   FState := STATE_SLEEP;
   FCurAnim := ANIM_SLEEP;
 
@@ -1790,7 +1812,7 @@ begin
         // Ýòî çíà÷èò: dX := -frameWidth - animDeltaX + hitX + hitWidth + hitX
         end;
       end
-    else // Ïðàâàÿ àíèìàöèÿ                    
+    else // Ïðàâàÿ àíèìàöèÿ
       begin
         dx := MONSTER_ANIMTABLE[FMonsterType].AnimDeltaRight[FCurAnim].X;
         dy := MONSTER_ANIMTABLE[FMonsterType].AnimDeltaRight[FCurAnim].Y;
@@ -1876,7 +1898,7 @@ begin
 
         FObj.Rect := MONSTERTABLE[FMonsterType].Rect;
         FHealth := MONSTERTABLE[FMonsterType].Health;
-        FAmmo := 0; 
+        FAmmo := 0;
         FPain := 0;
       end;
     else Exit;
@@ -1886,7 +1908,7 @@ begin
   if ForceAnim <> 255 then
     Anim := ForceAnim;
 
-// Åñëè àíèìàöèÿ íîâàÿ - ïåðåçàïóñêàåì å¸: 
+// Åñëè àíèìàöèÿ íîâàÿ - ïåðåçàïóñêàåì å¸:
   if FCurAnim <> Anim then
     if FAnim[Anim, FDirection] <> nil then
     begin
@@ -1995,7 +2017,10 @@ begin
     Exit;
   end;
 
-  FPainSound := False;
+  if FPainTicks > 0 then
+    Dec(FPainTicks)
+  else
+    FPainSound := False;
 
 // Äâèãàåìñÿ:
   st := g_Obj_Move(@FObj, fall, True, True);
@@ -2118,6 +2143,8 @@ begin
           FPain := MONSTERTABLE[FMonsterType].Pain;
           if gSoundEffectsDF then PainSound();
         end;
+        if (not gSoundEffectsDF) and (FPain >= MONSTERTABLE[FMonsterType].MinPain) then
+          PainSound();
 
       // Ñíèæàåì áîëü ñî âðåìåíåì:
         FPain := FPain - 5;
@@ -2242,8 +2269,11 @@ begin
         if g_Obj_Collide(@FObj, @o) and (FTargetUID <> 0) then
         begin
           FTargetTime := 0;
-          if kick(@o) then
-            goto _end;
+          if (FMonsterType <> MONSTER_CYBER) or (Random(2) = 0) then
+          begin
+            if kick(@o) then
+              goto _end;
+          end;
         end;
 
       // Ðàññòîÿíèå äî öåëè:
@@ -2272,7 +2302,7 @@ begin
               FDirection := D_LEFT
             else
               FDirection := D_RIGHT;
-              
+
             goto _end;
           end;
 
@@ -2675,7 +2705,7 @@ _end:
 
           FWaitAttackAnim := False;
         end
-        
+
       else // Àíèìàöèÿ àòàêè åùå èäåò (èñêëþ÷åíèå - Lost_Soul):
         if (FMonsterType = MONSTER_SOUL) or
            ( (not FWaitAttackAnim) and
@@ -2702,13 +2732,13 @@ _end:
                   if g_Weapon_Hit(@FObj, 10, FUID, HIT_SOME) <> 0 then
                     g_Sound_PlayExAt('SOUND_MONSTER_FISH_ATTACK', FObj.X, FObj.Y);
 
-                MONSTER_SKEL, MONSTER_ROBO:
-                // Ðîáîò èëè ñêåëåò ñèëüíî ïèíàþòñÿ:
+                MONSTER_SKEL, MONSTER_ROBO, MONSTER_CYBER:
+                // Ðîáîò, êèáåð èëè ñêåëåò ñèëüíî ïèíàþòñÿ:
                   if FCurAnim = ANIM_ATTACK2 then
                   begin
                     o := FObj;
-                    o.Vel.X := IfThen(FDirection = D_RIGHT, 1, -1)*50;
-                    if g_Weapon_Hit(@o, 50, FUID, HIT_SOME) <> 0 then
+                    o.Vel.X := IfThen(FDirection = D_RIGHT, 1, -1)*IfThen(FMonsterType = MONSTER_CYBER, 60, 50);
+                    if g_Weapon_Hit(@o, IfThen(FMonsterType = MONSTER_CYBER, 33, 50), FUID, HIT_SOME) <> 0 then
                       g_Sound_PlayExAt('SOUND_MONSTER_SKEL_HIT', FObj.X, FObj.Y);
                   end;
 
@@ -2925,7 +2955,10 @@ begin
     Exit;
   end;
 
-  FPainSound := False;
+  if FPainTicks > 0 then
+    Dec(FPainTicks)
+  else
+    FPainSound := False;
 
 // Äâèãàåìñÿ:
   st := g_Obj_Move(@FObj, fall, True, True);
@@ -3030,8 +3063,10 @@ begin
         if FPain >= MONSTERTABLE[FMonsterType].Pain then
         begin
           FPain := MONSTERTABLE[FMonsterType].Pain;
-          PainSound();
+          if gSoundEffectsDF then PainSound();
         end;
+        if (not gSoundEffectsDF) and (FPain >= MONSTERTABLE[FMonsterType].MinPain) then
+          PainSound();
 
       // Ñíèæàåì áîëü ñî âðåìåíåì:
         FPain := FPain - 5;
@@ -3430,7 +3465,7 @@ _end:
 
           FWaitAttackAnim := False;
         end
-        
+
       else // Àíèìàöèÿ àòàêè åùå èäåò (èñêëþ÷åíèå - Lost_Soul):
         if (FMonsterType = MONSTER_SOUL) or
            ( (not FWaitAttackAnim) and
@@ -3451,17 +3486,17 @@ _end:
                   // Lost_Soul óêóñèë êîãî-òî => ïåðåõîäèò íà øàã:
                     if FMonsterType = MONSTER_SOUL then
                       SetState(STATE_GO);
-                          
+
                 MONSTER_FISH:
                   g_Weapon_Hit(@FObj, 10, FUID, HIT_SOME);
 
-                MONSTER_SKEL, MONSTER_ROBO:
-                // Ðîáîò èëè ñêåëåò ñèëüíî ïèíàþòñÿ:
+                MONSTER_SKEL, MONSTER_ROBO, MONSTER_CYBER:
+                // Ðîáîò, êèáåð èëè ñêåëåò ñèëüíî ïèíàþòñÿ:
                   if FCurAnim = ANIM_ATTACK2 then
                   begin
                     o := FObj;
-                    o.Vel.X := IfThen(FDirection = D_RIGHT, 1, -1)*50;
-                    g_Weapon_Hit(@o, 50, FUID, HIT_SOME);
+                    o.Vel.X := IfThen(FDirection = D_RIGHT, 1, -1)*IfThen(FMonsterType = MONSTER_CYBER, 60, 50);
+                    g_Weapon_Hit(@o, IfThen(FMonsterType = MONSTER_CYBER, 33, 50), FUID, HIT_SOME);
                   end;
 
                 MONSTER_VILE:
@@ -3528,7 +3563,7 @@ _end:
   if g_Obj_CollidePanel(@FObj, 0, 0, PANEL_LIFTLEFT or PANEL_LIFTRIGHT) and
      not ((FState = STATE_DEAD) or (FState = STATE_DIE))  then
     FObj.Vel.X := oldvelx;
-    
+
 // Åñëè åñòü àíèìàöèÿ, òî ïóñòü îíà èäåò:
   if FAnim[FCurAnim, FDirection] <> nil then
     FAnim[FCurAnim, FDirection].Update();
@@ -3752,13 +3787,7 @@ begin
         g_Sound_PlayExAt('SOUND_MONSTER_IMP_ATTACK', FObj.X, FObj.Y);
         Result := True;
       end;
-    MONSTER_SKEL:
-      begin
-        SetState(STATE_ATTACK, ANIM_ATTACK2);
-        g_Sound_PlayExAt('SOUND_MONSTER_SKEL_ATTACK', FObj.X, FObj.Y);
-        Result := True;
-      end;
-    MONSTER_ROBO:
+    MONSTER_SKEL, MONSTER_ROBO, MONSTER_CYBER:
       begin
         SetState(STATE_ATTACK, ANIM_ATTACK2);
         g_Sound_PlayExAt('SOUND_MONSTER_SKEL_ATTACK', FObj.X, FObj.Y);