Browse Source

Fix magic effect animations in newer client versions

Kamil Chojnowski 1 year ago
parent
commit
a40130d79b
4 changed files with 62 additions and 10 deletions
  1. 30
    2
      src/client/animator.cpp
  2. 3
    0
      src/client/animator.h
  3. 29
    7
      src/client/effect.cpp
  4. 0
    1
      src/client/effect.h

+ 30
- 2
src/client/animator.cpp View File

@@ -123,6 +123,24 @@ int Animator::getPhase()
123 123
     return m_phase;
124 124
 }
125 125
 
126
+int Animator::getPhaseAt(ticks_t time)
127
+{
128
+    int index = 0;
129
+    ticks_t total = 0;
130
+
131
+    for(const auto &pair: m_phaseDurations) {
132
+        total += std::get<1>(pair);
133
+
134
+        if (time < total) {
135
+            return index;
136
+        }
137
+
138
+        ++index;
139
+    }
140
+
141
+    return std::min<int>(index, m_animationPhases - 1);
142
+}
143
+
126 144
 int Animator::getStartPhase()
127 145
 {
128 146
     if(m_startPhase > -1)
@@ -157,7 +175,7 @@ int Animator::getLoopPhase()
157 175
 
158 176
     if(m_loopCount == 0)
159 177
         return 0;
160
-        
178
+
161 179
     if(m_currentLoop < (m_loopCount - 1)) {
162 180
         m_currentLoop++;
163 181
         return 0;
@@ -182,7 +200,7 @@ void Animator::calculateSynchronous()
182 200
     int totalDuration = 0;
183 201
     for(int i = 0; i < m_animationPhases; i++)
184 202
         totalDuration += getPhaseDuration(i);
185
-    
203
+
186 204
     ticks_t ticks = g_clock.millis();
187 205
     int elapsedTicks = (int)(ticks % totalDuration);
188 206
     int totalTime = 0;
@@ -197,3 +215,13 @@ void Animator::calculateSynchronous()
197 215
     }
198 216
     m_lastPhaseTicks = ticks;
199 217
 }
218
+
219
+ticks_t Animator::getTotalDuration()
220
+{
221
+    ticks_t time = 0;
222
+    for (const auto &pair: m_phaseDurations) {
223
+        time += std::get<1>(pair);
224
+    }
225
+
226
+    return time;
227
+}

+ 3
- 0
src/client/animator.h View File

@@ -50,12 +50,15 @@ public:
50 50
 
51 51
     void setPhase(int phase);
52 52
     int getPhase();
53
+    int getPhaseAt(ticks_t time);
53 54
 
54 55
     int getStartPhase();
55 56
     int getAnimationPhases() { return m_animationPhases; }
56 57
     bool isAsync() { return m_async; }
57 58
     bool isComplete() { return m_isComplete; }
58 59
 
60
+    ticks_t getTotalDuration();
61
+
59 62
     void resetAnimation();
60 63
 
61 64
 private:

+ 29
- 7
src/client/effect.cpp View File

@@ -22,6 +22,7 @@
22 22
 
23 23
 #include "effect.h"
24 24
 #include "map.h"
25
+#include "game.h"
25 26
 #include <framework/core/eventdispatcher.h>
26 27
 
27 28
 void Effect::drawEffect(const Point& dest, float scaleFactor, bool animate, int offsetX, int offsetY, LightView *lightView)
@@ -30,8 +31,20 @@ void Effect::drawEffect(const Point& dest, float scaleFactor, bool animate, int
30 31
         return;
31 32
 
32 33
     int animationPhase = 0;
33
-    if(animate)
34
-        animationPhase = std::min<int>((int)(m_animationTimer.ticksElapsed() / m_phaseDuration), getAnimationPhases() - 1);
34
+    if(animate) {
35
+        if(g_game.getFeature(Otc::GameEnhancedAnimations)) {
36
+            // This requires a separate getPhaseAt method as using getPhase would make all magic effects use the same phase regardless of their appearance time
37
+            animationPhase = rawGetThingType()->getAnimator()->getPhaseAt(m_animationTimer.ticksElapsed());
38
+        } else {
39
+            // hack to fix some animation phases duration, currently there is no better solution
40
+            int ticks = EFFECT_TICKS_PER_FRAME;
41
+            if (m_id == 33) {
42
+                ticks <<= 2;
43
+            }
44
+
45
+            animationPhase = std::min<int>((int)(m_animationTimer.ticksElapsed() / ticks), getAnimationPhases() - 1);
46
+        }
47
+    }
35 48
 
36 49
     int xPattern = offsetX % getNumPatternX();
37 50
     if(xPattern < 0)
@@ -47,15 +60,24 @@ void Effect::drawEffect(const Point& dest, float scaleFactor, bool animate, int
47 60
 void Effect::onAppear()
48 61
 {
49 62
     m_animationTimer.restart();
50
-    m_phaseDuration = EFFECT_TICKS_PER_FRAME;
51 63
 
52
-    // hack to fix some animation phases duration, currently there is no better solution
53
-    if(m_id == 33)
54
-        m_phaseDuration <<= 2;
64
+    int duration = 0;
65
+    if(g_game.getFeature(Otc::GameEnhancedAnimations)) {
66
+        duration = getThingType()->getAnimator()->getTotalDuration();
67
+    } else {
68
+        duration = EFFECT_TICKS_PER_FRAME;
69
+
70
+        // hack to fix some animation phases duration, currently there is no better solution
71
+        if(m_id == 33) {
72
+            duration <<= 2;
73
+        }
74
+
75
+        duration *= getAnimationPhases();
76
+    }
55 77
 
56 78
     // schedule removal
57 79
     auto self = asEffect();
58
-    g_dispatcher.scheduleEvent([self]() { g_map.removeThing(self); }, m_phaseDuration * getAnimationPhases());
80
+    g_dispatcher.scheduleEvent([self]() { g_map.removeThing(self); }, duration);
59 81
 }
60 82
 
61 83
 void Effect::setId(uint32 id)

+ 0
- 1
src/client/effect.h View File

@@ -51,7 +51,6 @@ protected:
51 51
 
52 52
 private:
53 53
     Timer m_animationTimer;
54
-    uint m_phaseDuration;
55 54
     uint16 m_id;
56 55
 };
57 56
 

Loading…
Cancel
Save