DEADSOFTWARE

Game: Sync the spawning of lostsouls with the elemental death animation
authorDmitry D. Chernov <blackdoomer@yandex.ru>
Sun, 17 Sep 2023 18:39:21 +0000 (04:39 +1000)
committerDmitry D. Chernov <blackdoomer@yandex.ru>
Sun, 17 Sep 2023 18:39:45 +0000 (04:39 +1000)
src/game/g_monsters.pas

index ad887adfdd29d7e102c3a36069630eb0734437af..875db7f0808e43f8f55293a62797790bad5704ca 100644 (file)
@@ -708,11 +708,8 @@ begin
         Exit; // Ýòè íå áüþò ñâîèõ
     end;
 
-// Lost_Soul íå ìîæåò ðàíèòü Pain_Elemental'à:
-  if (a = MONSTER_SOUL) and (b = MONSTER_PAIN) then
-    Exit;
-// Pain_Elemental íå ìîæåò ðàíèòü Lost_Soul'à:
-  if (b = MONSTER_SOUL) and (a = MONSTER_PAIN) then
+// Pain_Elemental è Lost_Soul íå âîþþò äðóã ñ äðóãîì:
+  if [a, b] = [MONSTER_PAIN, MONSTER_SOUL] then
     Exit;
 
 // Â îñòàëüíûõ ñëó÷àÿõ - áóäóò áèòü äðóã äðóãà:
@@ -1349,7 +1346,7 @@ begin
   if MonsterType = MONSTER_SOUL then
   begin
     if soulcount > MAX_SOUL then exit;
-    soulcount := soulcount + 1;
+    soulcount += 1;
   end;
 
   find_id := allocMonster();
@@ -2362,7 +2359,7 @@ begin
     MONSTATE_ATTACK: Anim := ANIM_ATTACK;
     MONSTATE_DIE: Anim := ANIM_DIE;
     MONSTATE_REVIVE:
-      begin // íà÷àëè âîñðåøàòüñÿ
+      begin // íà÷àëè âîñêðåøàòüñÿ
         Anim := FCurAnim;
         FAnim[Anim, FDirection].Revert(True);
 
@@ -2465,7 +2462,7 @@ end;
 
 procedure TMonster.Update();
 var
-  a, b, sx, sy, wx, wy, oldvelx: Integer;
+  a, b, sx, sy, wx, wy, oldvelx, i: Integer;
   st: Word;
   o, co: TObj;
   fall: Boolean;
@@ -2486,7 +2483,7 @@ begin
       if (FState <> MONSTATE_DIE) and (FState <> MONSTATE_DEAD) then
         fall := False;
 
-// Ëåòàþùèå ìîíòñðû:
+// Ëåòàþùèå ìîíñòðû:
   if ((FMonsterType = MONSTER_SOUL) or
       (FMonsterType = MONSTER_PAIN) or
       (FMonsterType = MONSTER_CACO)) and
@@ -3143,56 +3140,37 @@ _end:
   if vilefire <> nil then
     vilefire.Update();
 
-// Ñîñòîÿíèå - Óìèðàåò è òåêóùàÿ àíèìàöèÿ ïðîèãðàíà:
-  if (FState = MONSTATE_DIE) and
-     (FAnim[FCurAnim, FDirection] <> nil) and
-     (FAnim[FCurAnim, FDirection].Played) then
-    begin
-    // Óìåð:
+  // Ñîñòîÿíèå - Óìèðàåò è òåêóùàÿ àíèìàöèÿ ïðîèãðàíà:
+  if (FState = MONSTATE_DIE) and (FAnim[FCurAnim, FDirection] <> nil) then
+  begin
+    if FAnim[FCurAnim, FDirection].Played then
+    begin  // Óìåð:
       SetState(MONSTATE_DEAD);
+      if g_Game_IsNet then MH_SEND_CoopStats();
 
-    // Pain_Elemental ïðè ñìåðòè âûïóñêàåò 3 Lost_Soul'à:
-      if (FMonsterType = MONSTER_PAIN) then
+      // Ó ýòèõ ìîíñòðîâ íåò òðóïîâ:
+      if FMonsterType in [MONSTER_PAIN, MONSTER_SOUL, MONSTER_BARREL] then
+        FRemoved := True;
+    end
+    else if (FMonsterType = MONSTER_PAIN) and
+        (FAnim[FCurAnim, FDirection].CurrentFrame =
+         FAnim[FCurAnim, FDirection].TotalFrames div 2 + 1) and
+        (FAnim[FCurAnim, FDirection].Counter = 0) then
+      for i := 0 to 2 do  // Pain_Elemental ïðè ñìåðòè âûïóñêàåò 3 Lost_Soul'à ïîñåðåäèíå àíèìàöèè:
       begin
-        mon := g_Monsters_Create(MONSTER_SOUL, FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2)-30,
-                                 FObj.Y+FObj.Rect.Y+20, TDirection.D_LEFT);
+        // FIXME: lostsouls may stuck in walls here
+        mon := g_Monsters_Create(MONSTER_SOUL,
+                                 FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2)+RandomRange(-15,16),
+                                 FObj.Y+FObj.Rect.Y+RandomRange(-7,8), FDirection);
         if mon <> nil then
         begin
           mon.SetState(MONSTATE_GO);
           mon.FNoRespawn := True;
-          Inc(gTotalMonsters);
+          gTotalMonsters += 1;
           if g_Game_IsNet then MH_SEND_MonsterSpawn(mon.UID);
         end;
-
-        mon := g_Monsters_Create(MONSTER_SOUL, FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2),
-                                 FObj.Y+FObj.Rect.Y+20, TDirection.D_RIGHT);
-        if mon <> nil then
-        begin
-          mon.SetState(MONSTATE_GO);
-          mon.FNoRespawn := True;
-          Inc(gTotalMonsters);
-          if g_Game_IsNet then MH_SEND_MonsterSpawn(mon.UID);
-        end;
-
-        mon := g_Monsters_Create(MONSTER_SOUL, FObj.X+FObj.Rect.X+(FObj.Rect.Width div 2)-15,
-                                 FObj.Y+FObj.Rect.Y, TDirection.D_RIGHT);
-        if mon <> nil then
-        begin
-          mon.SetState(MONSTATE_GO);
-          mon.FNoRespawn := True;
-          Inc(gTotalMonsters);
-          if g_Game_IsNet then MH_SEND_MonsterSpawn(mon.UID);
-        end;
-
-        if g_Game_IsNet then MH_SEND_CoopStats();
       end;
-
-    // Ó ýòèõ ìîíñòðîâ íåò òðóïîâ:
-      if (FMonsterType = MONSTER_PAIN) or
-         (FMonsterType = MONSTER_SOUL) or
-         (FMonsterType = MONSTER_BARREL) then
-        FRemoved := True;
-    end;
+  end;
 
 // Ñîâåðøåíèå àòàêè è ñòðåëüáû:
   if (FState = MONSTATE_ATTACK) or (FState = MONSTATE_SHOOT) then
@@ -4471,7 +4449,7 @@ end;
 
 function TMonster.alive(): Boolean;
 begin
-  Result := (FState <> MONSTATE_DIE) and (FState <> MONSTATE_DEAD) and (FHealth > 0);
+  Result := (FHealth > 0) and not (FState in [MONSTATE_DIE, MONSTATE_DEAD]);
 end;
 
 procedure TMonster.SetHealth(aH: Integer);