@@ -14,9 +14,20 @@ namespace TerrariaOverhaul.Common.Camera;
14
14
[ Autoload ( Side = ModSide . Client ) ]
15
15
public sealed class ScreenShakeSystem : ModSystem
16
16
{
17
+ private struct ScreenShakeInstance
18
+ {
19
+ public float StartTime ;
20
+ public float EndTime ;
21
+ public Vector2 ? Position ;
22
+ public ScreenShake Style ;
23
+
24
+ public float TimeLeft => MathF . Max ( 0f , EndTime - TimeSystem . RenderTime ) ;
25
+ public float Progress => Style . LengthInSeconds > 0f ? MathHelper . Clamp ( ( TimeSystem . RenderTime - StartTime ) / Style . LengthInSeconds , 0f , 1f ) : 1f ;
26
+ }
27
+
17
28
public static readonly RangeConfigEntry < float > ScreenShakeStrength = new ( ConfigSide . ClientOnly , "Camera" , nameof ( ScreenShakeStrength ) , 0f , 1f , ( ) => 1f ) ;
18
29
19
- private static readonly List < ScreenShake > screenShakes = new ( ) ;
30
+ private static readonly List < ScreenShakeInstance > screenShakes = new ( ) ;
20
31
21
32
private static FastNoiseLite ? noise ;
22
33
@@ -138,21 +149,22 @@ public static float GetPowerAtPoint(Vector2 point)
138
149
139
150
float power = 0f ;
140
151
141
- foreach ( var shake in EnumerateScreenShakes ( ) ) {
142
- float progress = shake . Progress ;
152
+ foreach ( ref var instance in EnumerateScreenShakes ( ) ) {
153
+ ref readonly var style = ref instance . Style ;
154
+ float progress = instance . Progress ;
143
155
144
156
float intensity ;
145
157
146
- if ( shake . PowerGradient != null ) {
147
- intensity = MathHelper . Clamp ( shake . PowerGradient . GetValue ( progress ) , 0f , 1f ) ;
158
+ if ( style . PowerGradient != null ) {
159
+ intensity = MathHelper . Clamp ( style . PowerGradient . GetValue ( progress ) , 0f , 1f ) ;
148
160
} else {
149
- intensity = MathHelper . Clamp ( shake . Power , 0f , 1f ) ;
161
+ intensity = MathHelper . Clamp ( style . Power , 0f , 1f ) ;
150
162
intensity *= MathF . Pow ( 1f - progress , 2f ) ;
151
163
}
152
164
153
- if ( shake . Position . HasValue ) {
154
- float distance = Vector2 . Distance ( shake . Position . Value , point ) ;
155
- float distanceFactor = 1f - Math . Min ( 1f , distance / shake . Range ) ;
165
+ if ( instance . Position . HasValue ) {
166
+ float distance = Vector2 . Distance ( instance . Position . Value , point ) ;
167
+ float distanceFactor = 1f - Math . Min ( 1f , distance / style . Range ) ;
156
168
157
169
intensity *= MathF . Pow ( distanceFactor , 2f ) ; // Exponential
158
170
}
@@ -164,38 +176,32 @@ public static float GetPowerAtPoint(Vector2 point)
164
176
return MathHelper . Clamp ( power * ScreenShakeStrength . Value , 0f , 1f ) ;
165
177
}
166
178
167
- public static void New ( float power , float time , Vector2 ? position = null , float range = ScreenShake . DefaultRange , string ? uniqueId = null )
168
- => New ( new ScreenShake ( power , time , position , range , uniqueId ) ) ;
169
-
170
- public static void New ( Gradient < float > powerGradient , float time , Vector2 ? position = null , float range = ScreenShake . DefaultRange , string ? uniqueId = null )
171
- => New ( new ScreenShake ( powerGradient , time , position , range , uniqueId ) ) ;
172
-
173
- public static void New ( ScreenShake screenShake )
179
+ public static void New ( ScreenShake style , Vector2 ? position )
174
180
{
175
181
if ( Main . dedServ ) {
176
182
return ;
177
183
}
178
184
179
- screenShake . Power = Math . Min ( screenShake . Power , 1f ) ;
180
- //screenShake.Length = MathF.Pow(screenShake.Power * 0.6f, 2f);
181
- screenShake . startTime = TimeSystem . RenderTime ;
182
- screenShake . endTime = screenShake . startTime + screenShake . Length ;
185
+ style . Power = MathUtils . Clamp01 ( style . Power ) ;
183
186
184
- if ( screenShake . UniqueId == null ) {
185
- screenShakes . Add ( screenShake ) ;
186
- return ;
187
- }
187
+ ScreenShakeInstance instance ;
188
+
189
+ instance . Style = style ;
190
+ instance . Position = position ;
191
+ instance . StartTime = TimeSystem . RenderTime ;
192
+ instance . EndTime = instance . StartTime + style . LengthInSeconds ;
188
193
189
- int index = screenShakes . FindIndex ( s => s . UniqueId == screenShake . UniqueId ) ;
194
+ string ? uniqueId = style . UniqueId ;
190
195
191
- if ( index >= 0 ) {
192
- screenShakes [ index ] = screenShake ;
193
- } else {
194
- screenShakes . Add ( screenShake ) ;
196
+ if ( uniqueId != null && screenShakes . FindIndex ( i => i . Style . UniqueId == uniqueId ) is ( >= 0 and int index ) ) {
197
+ screenShakes [ index ] = instance ;
198
+ return ;
195
199
}
200
+
201
+ screenShakes . Add ( instance ) ;
196
202
}
197
203
198
- private static Span < ScreenShake > EnumerateScreenShakes ( )
204
+ private static Span < ScreenShakeInstance > EnumerateScreenShakes ( )
199
205
{
200
206
screenShakes . RemoveAll ( s => s . TimeLeft <= 0f ) ;
201
207
0 commit comments