-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathGravityHelperAPI.cs
More file actions
242 lines (183 loc) · 10.1 KB
/
GravityHelperAPI.cs
File metadata and controls
242 lines (183 loc) · 10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
// Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using Celeste.Mod.GravityHelper.Components;
using Celeste.Mod.GravityHelper.Extensions;
using Celeste.Mod.GravityHelper.ThirdParty;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Monocle;
using MonoMod.ModInterop;
// ReSharper disable UnusedMember.Global
namespace Celeste.Mod.GravityHelper;
internal static class GravityHelperAPI
{
[ModExportName("GravityHelper")]
internal static class Exports
{
public static void RegisterModSupportBlacklist(string modName) =>
ThirdPartyModSupport.BlacklistedMods.Add(modName);
public static string GravityTypeFromInt(int gravityType) => ((GravityType)gravityType).ToString();
public static int GravityTypeToInt(string name) =>
(int)(Enum.TryParse<GravityType>(name, out var value) ? value : GravityType.Normal);
public static int GetPlayerGravity() =>
(int)(GravityHelperModule.PlayerComponent?.CurrentGravity ?? GravityType.Normal);
public static int GetActorGravity(Actor actor) => (int)(actor?.GetGravity() ?? GravityType.Normal);
// TODO: make this support instant
public static void SetPlayerGravity(int gravityType, float momentumMultiplier) =>
GravityHelperModule.PlayerComponent?.SetGravity((GravityType)gravityType, momentumMultiplier);
// TODO: make this support instant
public static void SetActorGravity(Actor actor, int gravityType, float momentumMultiplier) =>
actor?.SetGravity((GravityType)gravityType, momentumMultiplier);
public static bool IsPlayerInverted() => GravityHelperModule.ShouldInvertPlayer;
public static bool IsActorInverted(Actor actor) => actor?.ShouldInvert() ?? false;
public static Vector2 GetAboveVector(Actor actor) =>
actor?.ShouldInvert() == true ? Vector2.UnitY : -Vector2.UnitY;
public static Vector2 GetBelowVector(Actor actor) =>
actor?.ShouldInvert() == true ? -Vector2.UnitY : Vector2.UnitY;
public static Vector2 GetTopCenter(Actor actor) =>
actor?.ShouldInvert() == true ? actor.BottomCenter : actor?.TopCenter ?? Vector2.Zero;
public static Vector2 GetBottomCenter(Actor actor) =>
actor?.ShouldInvert() == true ? actor.TopCenter : actor?.BottomCenter ?? Vector2.Zero;
public static Vector2 GetTopLeft(Actor actor) =>
actor?.ShouldInvert() == true ? actor.BottomLeft : actor?.TopLeft ?? Vector2.Zero;
public static Vector2 GetBottomLeft(Actor actor) =>
actor?.ShouldInvert() == true ? actor.TopLeft : actor?.BottomLeft ?? Vector2.Zero;
public static Vector2 GetTopRight(Actor actor) =>
actor?.ShouldInvert() == true ? actor.BottomRight : actor?.TopRight ?? Vector2.Zero;
public static Vector2 GetBottomRight(Actor actor) =>
actor?.ShouldInvert() == true ? actor.TopRight : actor?.BottomRight ?? Vector2.Zero;
public static Vector2 TransformVector(Vector2 vec)
{
if (!GravityHelperModule.ShouldInvertPlayer || IsControlSchemeRelative())
return vec;
return new Vector2(vec.X, -vec.Y);
}
public static Vector2 TransformFeatherVector(Vector2 vec)
{
if (!GravityHelperModule.ShouldInvertPlayer || IsFeatherControlSchemeRelative())
return vec;
return new Vector2(vec.X, -vec.Y);
}
public static Vector2 TransformVectorForActor(Vector2 vec, Actor actor)
{
if (actor is Player) return TransformVector(vec);
return new Vector2(vec.X, actor.ShouldInvert() ? -vec.Y : vec.Y);
}
public static bool IsControlSchemeRelative() => GravityHelperModule.Settings.ControlScheme ==
GravityHelperModuleSettings.ControlSchemeSetting.Relative;
public static bool IsFeatherControlSchemeRelative() => GravityHelperModule.Settings.FeatherControlScheme ==
GravityHelperModuleSettings.ControlSchemeSetting.Relative;
public static TalkComponent.TalkComponentUI CreateUpsideDownTalkComponentUI(TalkComponent talkComponent) =>
new UpsideDownTalkComponentUI(talkComponent);
// TODO: make this support instant
public static Component CreateGravityListener(Actor actor, Action<Entity, int, float> gravityChanged) =>
new GravityListener(actor, (e, a) =>
gravityChanged(e, (int)a.NewValue, a.MomentumMultiplier));
// TODO: make this support instant
public static Component CreatePlayerGravityListener(Action<Player, int, float> gravityChanged) =>
new PlayerGravityListener((e, a) =>
gravityChanged(e as Player, (int)a.NewValue, a.MomentumMultiplier));
public static void BeginForceInvertPlayerRender() => GravityHelperModule.ForceInvertPlayerRenderSemaphore++;
public static void EndForceInvertPlayerRender() => GravityHelperModule.ForceInvertPlayerRenderSemaphore--;
public static void BeginOverride() => GravityHelperModule.OverrideSemaphore++;
public static void EndOverride() => GravityHelperModule.OverrideSemaphore--;
public static void ExecuteOverride(Action action)
{
GravityHelperModule.OverrideSemaphore++;
action?.Invoke();
GravityHelperModule.OverrideSemaphore--;
}
public static IDisposable WithOverride()
{
GravityHelperModule.OverrideSemaphore++;
return new InvokeOnDispose(() => GravityHelperModule.OverrideSemaphore--);
}
public static void SetHoldableResetTime(Holdable holdable, float resetTime)
{
if (holdable?.Entity.Get<GravityHoldable>() is { } gravityHoldable)
{
gravityHoldable.ResetTime = resetTime;
}
}
public static void SetHoldableResetType(Holdable holdable, int gravityType)
{
if (holdable?.Entity.Get<GravityHoldable>() is { } gravityHoldable)
{
gravityHoldable.ResetType = (GravityType)gravityType;
}
}
public static Component CreateAccessibilityListener(Action onAccessibilityChange) =>
new AccessibilityListener(onAccessibilityChange);
public static Color GetColor(int gravityType) =>
(GravityHelperModule.Settings.GetColorScheme() ?? GravityColorScheme.Classic)[(GravityType)gravityType];
public static Color GetNormalColor() =>
(GravityHelperModule.Settings.GetColorScheme() ?? GravityColorScheme.Classic).NormalColor;
public static Color GetInvertedColor() =>
(GravityHelperModule.Settings.GetColorScheme() ?? GravityColorScheme.Classic).InvertedColor;
public static Color GetToggleColor() =>
(GravityHelperModule.Settings.GetColorScheme() ?? GravityColorScheme.Classic).ToggleColor;
public static bool BeginCustomTintShader(bool onlyForAccessibility = true)
{
if (onlyForAccessibility && GravityHelperModule.Settings.ColorSchemeType ==
GravityHelperModuleSettings.ColorSchemeSetting.Default)
return false;
if (!_effectLoaded)
{
_effectLoaded = true;
if (Everest.Content.TryGet("Effects/GravityHelper/CustomTintShader.cso", out var metadata))
{
_tintEffect = new Effect(Engine.Graphics.GraphicsDevice, metadata.Data);
}
else
{
_tintEffect = null;
Logger.Warn(nameof(GravityHelperModule), "Couldn't find custom tint shader");
}
}
if (_tintEffect == null) return false;
GameplayRenderer.End();
ApplyStandardParameters(_tintEffect);
Draw.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointWrap,
DepthStencilState.None, RasterizerState.CullNone, _tintEffect, GameplayRenderer.instance.Camera.Matrix);
return true;
}
public static void EndCustomTintShader()
{
Draw.SpriteBatch.End();
GameplayRenderer.Begin();
}
public static IDisposable WithCustomTintShader(bool onlyForAccessibility = true) =>
InternalCustomTintShader(onlyForAccessibility);
}
internal static void ClearTintEffect()
{
_tintEffect = null;
_effectLoaded = false;
}
private static Effect _tintEffect;
private static bool _effectLoaded;
internal static Effect ApplyStandardParameters(this Effect effect, Camera camera = null)
=> ApplyStandardParameters(effect, camera?.Matrix);
internal static Effect ApplyStandardParameters(this Effect effect, Matrix? camera)
{
if (Engine.Scene is not Level level) return null;
var parameters = effect.Parameters;
parameters["DeltaTime"]?.SetValue(Engine.DeltaTime);
parameters["Time"]?.SetValue(Engine.Scene.TimeActive);
parameters["Dimensions"]
?.SetValue(new Vector2(GameplayBuffers.Gameplay.Width, GameplayBuffers.Gameplay.Height));
parameters["CamPos"]?.SetValue(level.Camera.Position);
parameters["ColdCoreMode"]?.SetValue(level.CoreMode == Session.CoreModes.Cold);
Viewport viewport = Engine.Graphics.GraphicsDevice.Viewport;
Matrix projection = Matrix.CreateOrthographicOffCenter(0, viewport.Width, viewport.Height, 0, 0, 1);
parameters["TransformMatrix"]?.SetValue(projection);
parameters["ViewMatrix"]?.SetValue(camera ?? Matrix.Identity);
parameters["Photosensitive"]?.SetValue(Settings.Instance.DisableFlashes);
return effect;
}
internal static InvokeOnDispose InternalCustomTintShader(bool onlyForAccessibility = true) =>
Exports.BeginCustomTintShader(onlyForAccessibility)
? new InvokeOnDispose(Exports.EndCustomTintShader)
: new InvokeOnDispose();
}