DEADSOFTWARE

Game: Archviles and souls don't burn; use iterators in burn propagation
authorfgsfds <pvt.fgsfds@gmail.com>
Fri, 9 Aug 2019 02:08:47 +0000 (05:08 +0300)
committerfgsfds <pvt.fgsfds@gmail.com>
Fri, 9 Aug 2019 02:08:47 +0000 (05:08 +0300)
src/game/g_monsters.pas

index 02bea1f632bb906c89b5b56a220b757ec2d1b484..a19fa4b568e5dbab3163ff1eb8d256b8c5234d82 100644 (file)
@@ -2008,6 +2008,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;
@@ -2435,6 +2444,8 @@ var
   o, co: TObj;
   fall: Boolean;
   mon: TMonster;
+  mit: PMonster;
+  it: TMonsterGrid.Iter;
 label
   _end;
 begin
@@ -2473,11 +2484,12 @@ begin
 
 // Åñëè ãîðèì - ïîäæèãàåì äðóãèõ ìîíñòðîâ, íî íå íà 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, FFireTime);
+  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
@@ -4648,6 +4660,8 @@ end;
 
 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 FFireTime <= 0 then
     g_Sound_PlayExAt('SOUND_IGNITE', FObj.X, FObj.Y);