add playerdeadbody hook

This commit is contained in:
micycle 2023-05-08 20:42:42 -04:00 committed by yosh
parent 87c117b560
commit d540bee8c9
1 changed files with 60 additions and 3 deletions

View File

@ -64,6 +64,11 @@ namespace Celeste.Mod.AvaliSkin {
On.Celeste.Player.DashUpdate += onPlayerDashUpdate;
}
using (new DetourContext("AvaliSkinModule") {
After = { "FastPlayerDie" }
}) {
On.Celeste.PlayerDeadBody.Render += onPlayerDeadBodyRender;
}
IL.Celeste.DeathEffect.Draw += DeathEffectDrawHook;
On.Celeste.Payphone.ctor += onPayphoneConstructor;
On.Celeste.Lookout.ctor += onLookoutConstructor;
@ -105,6 +110,11 @@ namespace Celeste.Mod.AvaliSkin {
On.Celeste.Player.DashUpdate -= onPlayerDashUpdate;
}
using (new DetourContext("AvaliSkinModule") {
After = { "FastPlayerDie" }
}) {
On.Celeste.PlayerDeadBody.Render -= onPlayerDeadBodyRender;
}
IL.Celeste.DeathEffect.Draw -= DeathEffectDrawHook;
On.Celeste.Payphone.ctor -= onPayphoneConstructor;
On.Celeste.Lookout.ctor -= onLookoutConstructor;
@ -113,11 +123,13 @@ namespace Celeste.Mod.AvaliSkin {
}
// Checks if the enabled status of the sprite needs to be updated, and if
// so, then swaps out the sprite at runtime with the Avali spritebank.
private void trySpriteSwap(PlayerSprite sprite, bool enabled) {
DynamicData dd = DynamicData.For(sprite);
bool oldEnabled = false;
// TryGet crashes with value types (of course; obviously!)
// So we use a object type with the nullable bool... this is a bug in monomod?
// So we use a boxed type with the nullable bool... this is a bug in monomod?
if (dd.TryGet<bool?>("avaliskin_enabled", out bool? ddoldEnabled)) {
oldEnabled = (bool) ddoldEnabled;
}
@ -135,9 +147,20 @@ namespace Celeste.Mod.AvaliSkin {
}
dd.Set("avaliskin_enabled", (bool?) enabled);
// CreateOn doesn't preserve some of the properties that we need to keep here!
// Copy them over manually instead...
Vector2 pos = sprite.RenderPosition;
string currentAnimationID = sprite.CurrentAnimationID;
int CurrentAnimationFrame = sprite.CurrentAnimationFrame;
GFX.SpriteBank.CreateOn(sprite, spriteID);
sprite.RenderPosition = pos;
if (currentAnimationID != "") {
sprite.Play(currentAnimationID);
sprite.SetAnimationFrame(CurrentAnimationFrame);
}
}
}
@ -208,7 +231,10 @@ namespace Celeste.Mod.AvaliSkin {
// usually player playback entities and the such.
if (
self.Scene != null
&& (self.Entity == null || !(self.Entity is Player))
&& (
self.Entity == null ||
!(self.Entity is Player || self.Entity is PlayerDeadBody)
)
) {
if (PlayerConfig.IsEnabled(player)) {
trySpriteSwap(self, true);
@ -241,7 +267,7 @@ namespace Celeste.Mod.AvaliSkin {
if (
self.Scene != null && (
self.Entity == null
|| !(self.Entity is Player || self.Entity is Ghost)
|| !(self.Entity is Player || self.Entity is PlayerDeadBody || self.Entity is Ghost)
)
) {
onPlayerSpriteRenderMisc(orig, self);
@ -310,6 +336,37 @@ namespace Celeste.Mod.AvaliSkin {
}
public void onPlayerDeadBodyRender(On.Celeste.PlayerDeadBody.orig_Render orig, PlayerDeadBody self) {
DynamicData dd = DynamicData.For(self);
Player player = dd.Get<Player>("player");
PlayerSprite sprite = dd.Get<PlayerSprite>("sprite");
if (sprite.Scene != null && PlayerConfig.IsEnabled(player)) {
// swap out the body's spritebank if the enabled state changed
trySpriteSwap(sprite, true);
Color color = PlayerConfig.GetColor(player);
// apply the recolor effect to the body
spriteRecolor(color);
Draw.SpriteBatch.End();
Draw.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.None, RasterizerState.CullNone, FxRecolor, (self.Scene as Level).GameplayRenderer.Camera.Matrix);
// render the dead Avali :(
orig(self);
// ... and reset rendering to stop using the effect
Draw.SpriteBatch.End();
Draw.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.None, RasterizerState.CullNone, null, (self.Scene as Level).GameplayRenderer.Camera.Matrix);
} else if (self.Scene != null) {
trySpriteSwap(sprite, false);
orig(self);
} else {
orig(self);
}
}
private void DeathEffectDrawHook(ILContext il) {
// replace death particle, just like SkinModHelper
ILCursor cursor = new ILCursor(il);