DEADSOFTWARE

generalize warmup stuff
[d2df-sdl.git] / src / game / g_monsters.pas
index 83714cbdd0ec333d5f9a581bfd35c78aae655fd5..ac28f340a08b8fcd694d0aee764a53a32b086c4c 100644 (file)
@@ -2,8 +2,7 @@
  *
  * 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.
+ * the Free Software Foundation, version 3 of the License ONLY.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -40,6 +39,8 @@ const
   MONSTATE_REVIVE = 10;
   MONSTATE_RUNOUT = 11;
 
+  MON_BURN_TIME   = 100;
+
 { in mapdef now
   BH_NORMAL   = 0;
   BH_KILLER   = 1;
@@ -145,7 +146,7 @@ type
     function  AnimIsReverse: Boolean;
     function  shoot(o: PObj; immediately: Boolean): Boolean;
     function  kick(o: PObj): Boolean;
-    procedure CatchFire(Attacker: Word);
+    procedure CatchFire(Attacker: Word; Timeout: Integer = MON_BURN_TIME);
     procedure OnFireFlame(Times: DWORD = 1);
 
     procedure positionChanged (); //WARNING! call this after monster position was changed, or coldet will not work right!
@@ -1992,6 +1993,9 @@ var
 begin
   Result := False;
 
+// Ìîíñòð ñòàòè÷åí ïîêà èäåò warmup
+  if (gLMSRespawn > LMS_RESPAWN_NONE) then exit;
+
 // Óìèðàåò, óìåð èëè âîñêðåøàåòñÿ => óðîí äåëàòü íåêîìó:
   if (FState = MONSTATE_DEAD) or (FState = MONSTATE_DIE) or (FState = MONSTATE_REVIVE) then
     Exit;
@@ -2006,6 +2010,15 @@ begin
     Exit;
   end;
 
+// Àð÷è íå ãîðÿò, ÷åðåïà óæå ãîðÿò
+  if (t = HIT_FLAME) and (FMonsterType in [MONSTER_VILE, MONSTER_SOUL]) then
+  begin
+  // Ïðîñíóòüñÿ âñå-òàêè ñòîèò
+    if FState = MONSTATE_SLEEP then
+      SetState(MONSTATE_GO);
+    Exit;
+  end;
+
 // Ëîâóøêà óáèâàåò ñðàçó:
   if t = HIT_TRAP then
     FHealth := -100;
@@ -2433,11 +2446,16 @@ var
   o, co: TObj;
   fall: Boolean;
   mon: TMonster;
+  mit: PMonster;
+  it: TMonsterGrid.Iter;
 label
   _end;
 begin
   fall := True;
 
+// Ìîíñòð ñòàòè÷åí ïîêà èäåò warmup
+  if (gLMSRespawn > LMS_RESPAWN_NONE) then exit;
+
 // Ðûáû "ëåòàþò" òîëüêî â âîäå:
   if FMonsterType = MONSTER_FISH then
     if g_Obj_CollidePanel(@FObj, 0, 0, PANEL_WATER or PANEL_ACID1 or PANEL_ACID2) then
@@ -2469,13 +2487,14 @@ begin
   st := g_Obj_Move(@FObj, fall, True, True);
   positionChanged(); // this updates spatial accelerators
 
-// Åñëè ãîðèì - ïîäæèãàåì äðóãèõ ìîíñòðîâ:
+// Åñëè ãîðèì - ïîäæèãàåì äðóãèõ ìîíñòðîâ, íî íå íà 100 òèêîâ êàæäûé ðàç:
   if FFireTime > 0 then
-    for a := 0 to High(gMonsters) do
-      if (gMonsters[a] <> nil) and (gMonsters[a].alive) and
-         (gMonsters[a].FUID <> FUID) and
-         g_Obj_Collide(@FObj, @gMonsters[a].Obj) then
-        gMonsters[a].CatchFire(FFireAttacker);
+  begin
+    it := monsGrid.forEachInAABB(FObj.X+FObj.Rect.X, FObj.Y+FObj.Rect.Y, FObj.Rect.Width, FObj.Rect.Height);
+    for mit in it do
+      if mit.UID <> FUID then
+        mit.CatchFire(FFireAttacker, FFireTime);
+  end;
 
 // Âûëåòåë çà êàðòó - óäàëÿåì è çàïóñêàåì òðèããåðû:
   if WordBool(st and MOVE_FALLOUT) or (FObj.X < -1000) or
@@ -3426,6 +3445,10 @@ begin
   sx := 0; // SHUT UP COMPILER
   sy := 0;
   fall := True;
+
+// Ìîíñòð ñòàòè÷åí ïîêà èäåò warmup
+  if (gLMSRespawn > LMS_RESPAWN_NONE) then exit;
+
 // Ðûáû "ëåòàþò" òîëüêî â âîäå:
   if FMonsterType = MONSTER_FISH then
     if g_Obj_CollidePanel(@FObj, 0, 0, PANEL_WATER or PANEL_ACID1 or PANEL_ACID2) then
@@ -4644,11 +4667,16 @@ begin
   SetLength(FDieTriggers, 0);
 end;
 
-procedure TMonster.CatchFire(Attacker: Word);
+procedure TMonster.CatchFire(Attacker: Word; Timeout: Integer = MON_BURN_TIME);
 begin
+  if FMonsterType in [MONSTER_SOUL, MONSTER_VILE] then
+    exit; // àð÷è íå ãîðÿò, ÷åðåïà óæå ãîðÿò
+  if Timeout <= 0 then exit;
+  if g_Obj_CollidePanel(@FObj, 0, 0, PANEL_WATER or PANEL_ACID1 or PANEL_ACID2) then
+    exit; // íå ïîäãîðàåì â âîäå íà âñÿêèé ñëó÷àé
   if FFireTime <= 0 then
     g_Sound_PlayExAt('SOUND_IGNITE', FObj.X, FObj.Y);
-  FFireTime := 100;
+  FFireTime := Timeout;
   FFireAttacker := Attacker;
   if g_Game_IsNet and g_Game_IsServer then MH_SEND_MonsterState(FUID);
 end;