DEADSOFTWARE

gl: handle archvile fire animaton in render
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Mon, 13 Jun 2022 18:50:31 +0000 (21:50 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Fri, 9 Jun 2023 08:53:13 +0000 (11:53 +0300)
src/game/g_monsters.pas
src/game/renders/opengl/r_map.pas

index 718921baf0934e810cc9db38725f7c7396b52692..db552adb8122da64e4441c52811555460bded0b1 100644 (file)
@@ -93,7 +93,7 @@ type
     {$ENDIF}
     FFirePainTime: Integer;
     FFireAttacker: Word;
-    vilefire: TAnimState;
+    FVileFireTime: LongWord;
     mProxyId: Integer; // node in dyntree or -1
     mArrIdx: Integer; // in gMonsters
 
@@ -198,7 +198,7 @@ type
 
     property StartID: Integer read FStartID;
 
-    property VileFireAnim: TAnimState read vilefire;
+    property VileFireTime: LongWord read FVileFireTime;
     property DirAnim: ADirectedAnim read FAnim;
 
   published
@@ -1685,8 +1685,8 @@ begin
     FAnim[a, TDirection.D_RIGHT] := TAnimState.Create(ANIMTABLE[a].loop, MONSTER_ANIMTABLE[MonsterType].AnimSpeed[a], MONSTER_ANIMTABLE[MonsterType].AnimCount[a]);
     FAnim[a, TDirection.D_LEFT] := TAnimState.Create(ANIMTABLE[a].loop, MONSTER_ANIMTABLE[MonsterType].AnimSpeed[a], MONSTER_ANIMTABLE[MonsterType].AnimCount[a]);
   end;
-  if MonsterType = MONSTER_VILE then
-    vilefire := TAnimState.Create(True, 2, 8);
+
+  FVileFireTime := gTime;
 end;
 
 function TMonster.Damage(aDamage: Word; VelX, VelY: Integer; SpawnerUID: Word; t: Byte): Boolean;
@@ -1883,7 +1883,7 @@ begin
     FAnim[a, TDirection.D_RIGHT].Invalidate;
   end;
 
-  vilefire.Invalidate;
+  FVileFireTime := 0;
 
   if (mProxyId <> -1) then
   begin
@@ -2777,10 +2777,6 @@ _end:
       SetState(MONSTATE_GO);
     end;
 
-// Если есть анимация огня колдуна - пусть она идет:
-  if vilefire.IsValid() then
-    vilefire.Update();
-
 // Состояние - Умирает и текущая анимация проиграна:
   if (FState = MONSTATE_DIE) and
      (FAnim[FCurAnim, FDirection].IsValid()) and
@@ -3640,10 +3636,6 @@ _end:
       SetState(MONSTATE_GO);
     end;
 
-// Если есть анимация огня колдуна - пусть она идет:
-  if vilefire.IsValid() then
-    vilefire.Update();
-
 // Состояние - Умирает и текущая анимация проиграна:
   if (FState = MONSTATE_DIE) and
      (FAnim[FCurAnim, FDirection].IsValid()) and
@@ -4115,7 +4107,7 @@ begin
         ty := o^.Y+o^.Rect.Y;
         SetState(MONSTATE_SHOOT);
 
-        vilefire.Reset();
+        FVileFireTime := gTime;
 
         g_Sound_PlayExAt('SOUND_MONSTER_VILE_ATTACK', FObj.X, FObj.Y);
         g_Sound_PlayExAt('SOUND_FIRE', o^.X, o^.Y);
@@ -4178,6 +4170,7 @@ var
   i: Integer;
   b: Byte;
   anim: Boolean;
+  stub: TAnimState;
 begin
   assert(st <> nil);
 
@@ -4227,10 +4220,15 @@ begin
   // Объект монстра
   Obj_SaveState(st, @FObj);
   // Есть ли анимация огня колдуна
-  anim := (vilefire.IsValid());
+  anim := FMonsterType = MONSTER_VILE;
   utils.writeBool(st, anim);
   // Если есть - сохраняем:
-  if anim then vilefire.SaveState(st, 0, False);
+  if anim then
+  begin
+    stub := TAnimState.Create(true, 2, 8);
+    stub.SaveState(st, 0, False);
+    stub.Invalidate;
+  end;
   // Анимации
   for i := ANIM_SLEEP to ANIM_PAIN do
   begin
@@ -4253,6 +4251,7 @@ var
   i: Integer;
   b, alpha: Byte;
   anim, blending: Boolean;
+  stub: TAnimState;
 begin
   assert(st <> nil);
 
@@ -4311,9 +4310,11 @@ begin
   // Если есть - загружаем:
   if anim then
   begin
-    Assert(vilefire.IsValid(), 'TMonster.LoadState: no vilefire anim');
-    vilefire.LoadState(st, alpha, blending);
+    stub := TAnimState.Create(true, 2, 8);
+    stub.LoadState(st, alpha, blending);
+    stub.Invalidate;
   end;
+  FVileFireTime := gTime;
   // Анимации
   for i := ANIM_SLEEP to ANIM_PAIN do
   begin
index f9ac5dc08648eb151615af14be70b31991d30058..7e9482e6a3e7b43e82a94851c43d177756898e32 100644 (file)
@@ -221,6 +221,7 @@ implementation
 
     PunchAnim: TAnimInfo = (loop: false; delay: 1; frames: 4; back: false);
     FlagAnim: TAnimInfo = (loop: true; delay: 8; frames: 5; back: false);
+    VileFireAnim: TAnimInfo = (loop: true; delay:  2; frames: 8; back: false);
 
   type
     TBinHeapPanelDrawCmp = class
@@ -423,7 +424,7 @@ implementation
       for j := 0 to ANIM_LAST do
         for d := TDirection.D_LEFT to TDirection.D_RIGHT do
           r_Map_LoadMonsterAnim(i, j, d);
-    VileFire := r_Textures_LoadMultiFromFileAndInfo(GameWAD + ':TEXTURES/FIRE', 64, 128, 8, False, False);
+    VileFire := r_Textures_LoadMultiFromFileAndInfo(GameWAD + ':TEXTURES/FIRE', 64, 128, VileFireAnim.frames, VileFireAnim.back);
     // --------- player models --------- //
     if PlayerModelsArray <> nil then
     begin
@@ -689,12 +690,16 @@ implementation
   end;
 
   procedure r_Map_DrawMonsterAttack (constref mon: TMonster);
-    var o: TObj;
+    var o: TObj; count, frame: LongInt; tex: TGLTexture;
   begin
     if VileFire <> nil then
       if (mon.MonsterType = MONSTER_VILE) and (mon.MonsterState = MONSTATE_SHOOT) then
-        if mon.VileFireAnim.IsValid() and GetPos(mon.MonsterTargetUID, @o) then
-          r_Draw_MultiTextureRepeat(VileFire, mon.VileFireAnim, o.x + o.rect.x + (o.rect.width div 2) - VILEFIRE_DX, o.y + o.rect.y + o.rect.height - VILEFIRE_DY, VileFire.width, VileFire.height, False, 255, 255, 255, 255, false);
+        if (mon.VileFireTime <= gTime) and GetPos(mon.MonsterTargetUID, @o) then
+        begin
+          g_Anim_GetFrameByTime(VileFireAnim, (gTime - mon.VileFireTime) DIV GAME_TICK, count, frame);
+          tex := VileFire.GetTexture(frame);
+          r_Draw_TextureRepeat(tex, o.x + o.rect.x + (o.rect.width div 2) - VILEFIRE_DX, o.y + o.rect.y + o.rect.height - VILEFIRE_DY, tex.width, tex.height, False, 255, 255, 255, 255, false);
+        end;
   end;
 
   procedure r_Map_DrawMonster (constref mon: TMonster);