Skip to content

Commit

Permalink
Merge branch 'dev' into beta
Browse files Browse the repository at this point in the history
  • Loading branch information
maddie480 committed Jun 16, 2024
2 parents 8be6bbe + d6d5239 commit 283dd69
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 22 deletions.
12 changes: 10 additions & 2 deletions Celeste.Mod.mm/Mod/Everest/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,16 @@ public static BinaryPacker.Element SetAttr(this BinaryPacker.Element el, string
public static int AttrInt(this BinaryPacker.Element el, string name, int defaultValue = 0) {
if (el.Attributes == null || !el.Attributes.TryGetValue(name, out object obj))
return defaultValue;
if (obj is int)
return (int) obj;
if (obj is int v)
return v;
return int.Parse(obj.ToString(), CultureInfo.InvariantCulture);
}

public static int? AttrNullableInt(this BinaryPacker.Element el, string name) {
if (el.Attributes == null || !el.Attributes.TryGetValue(name, out object obj))
return null;
if (obj is int v)
return v;
return int.Parse(obj.ToString(), CultureInfo.InvariantCulture);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public override void Parse(XmlAttributeCollection xml) {
}

public override void ApplyTo(Decal decal) {
if (_depth is { } depth)
if (_depth is { } depth && !((patch_Decal)decal).DepthSetByPlacement)
decal.Depth = depth;
}
}
}
31 changes: 20 additions & 11 deletions Celeste.Mod.mm/Mod/UI/TextMenuExt.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Celeste.Mod;
using Celeste.Mod.Core;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Monocle;
Expand Down Expand Up @@ -1500,7 +1499,7 @@ public string Text {
public float StrokeSize { get; set; } = 2f;
public Color StrokeColor { get; set; } = Color.Black;
public Color PlaceHolderTextColor { get; set; } = Color.LightGray * 0.75f;
public Color SearchBarColor { get; set; } = Color.DarkSlateGray * 0.8f;
public Color TextBoxColor { get; set; } = Color.DarkSlateGray * 0.8f;
public Vector2 TextScale { get; set; } = Vector2.One * DEFAULT_TEXT_SCALE;
public Vector2 TextPadding { get; set; } = new Vector2(ActiveFont.Measure(' ').X * DEFAULT_TEXT_SCALE, ActiveFont.LineHeight * DEFAULT_TEXT_SCALE / 6);
public float WidthScale { get; set; } = 1;
Expand Down Expand Up @@ -1550,7 +1549,7 @@ public override float Height() {
public override void Render(Vector2 position, bool highlighted) {
Vector2 textPosition = new(position.X + TextPadding.X, position.Y + (Height() / 2));

Draw.Rect(position, Width, Height(), SearchBarColor);
Draw.Rect(position, Width, Height(), TextBoxColor);

if (Text.Length <= 0 && !string.IsNullOrEmpty(PlaceholderText)) {
Vector2 placeholderSize = ActiveFont.Measure(PlaceholderText) * TextScale;
Expand Down Expand Up @@ -1681,6 +1680,16 @@ public override void Update() {

// We need to disable all other inputs if the textBox consumed that an input,
MInput.Disabled = TextBoxConsumedInput;
if (TextBoxConsumedInput) {
// Because we can only control the value of MInput.Disable for the duration of the paused menu Update
// we have to consume all the button presses to emulate disabling MInput for the rest of the Update call
foreach (VirtualInput input in patch_MInput.VirtualInputs) {
if (input is VirtualButton button) {
button.ConsumePress();
}
}
}


// ensure the player never enters free cam while typing, so to cover the case our Update() gets called we consume the input
// and if we get called afterwards we set ToggleMountainFreeCam to false before the next Render() call to MountainRenderer
Expand Down Expand Up @@ -1715,30 +1724,30 @@ public static bool WrappingLinearSearch<T>(List<T> items, Func<T, bool> predicat
public class Modal : patch_Item {
public Color BoxBorderColor { get; set; } = Color.White;
public Color BoxBackgroundColor { get; set; } = Color.Black * 0.8f;
public readonly TextMenu.Item Item;
public int BorderThickness { get; set; } = 2;
private readonly float? absoluteY;
private readonly float? absoluteX;
private readonly TextMenu.Item item;

public Modal(TextMenu.Item item, float? absoluteX, float? absoluteY) {
AboveAll = true;
Visible = false;
IncludeWidthInMeasurement = false;
this.absoluteY = absoluteY;
this.absoluteX = absoluteX;
this.item = item;
Item = item;
}

public override void Added() {
base.Added();
item.Container = Container;
item.Added();
Item.Container = Container;
Item.Added();
}

public override void Update() {
base.Update();
item.OnUpdate?.Invoke();
item.Update();
Item.OnUpdate?.Invoke();
Item.Update();
}

public override bool AlwaysRender => true;
Expand All @@ -1754,10 +1763,10 @@ public override float Height() {
public override void Render(Vector2 position, bool highlighted) {
Vector2 renderPosition = new(absoluteX ?? position.X, absoluteY ?? position.Y);
for (int i = 1; i <= BorderThickness; i++) {
Draw.HollowRect(renderPosition.X - i, renderPosition.Y - i, item.Width + (2 * i), item.Height() + (2 * i), BoxBorderColor * Container.Alpha);
Draw.HollowRect(renderPosition.X - i, renderPosition.Y - i, Item.Width + (2 * i), Item.Height() + (2 * i), BoxBorderColor * Container.Alpha);
}

item.Render(renderPosition, highlighted);
Item.Render(renderPosition, highlighted);
}
}

Expand Down
10 changes: 9 additions & 1 deletion Celeste.Mod.mm/Patches/Decal.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#pragma warning disable CS0626 // Method, operator, or accessor is marked external and has no attributes on it
#pragma warning disable CS0626 // Method, operator, or accessor is marked external and has no attributes on it
#pragma warning disable CS0414 // The field is assigned but its value is never used

using Celeste.Mod;
Expand Down Expand Up @@ -36,6 +36,8 @@ public Vector2 Scale {

public Color Color;

public bool DepthSetByPlacement;

private bool scaredAnimal;

private float hideRange;
Expand Down Expand Up @@ -281,7 +283,13 @@ public override void Awake(Scene scene) {

public extern void orig_Added(Scene scene);
public override void Added(Scene scene) {
int depth = Depth;

orig_Added(scene);

if (DepthSetByPlacement)
Depth = depth;

// Handle the Decal Registry
string text = Name.ToLower();
if (text.StartsWith("decals/", StringComparison.Ordinal)) {
Expand Down
9 changes: 9 additions & 0 deletions Celeste.Mod.mm/Patches/DecalData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ class patch_DecalData : DecalData {

public float Rotation;
public string ColorHex;
public int? Depth;

public int GetDepth(int fallback) {
return Depth ?? fallback;
}

public bool HasDepth() {
return Depth.HasValue;
}

}
}
28 changes: 26 additions & 2 deletions Celeste.Mod.mm/Patches/Level.cs
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ namespace MonoMod {
class PatchLevelLoaderAttribute : Attribute { }

/// <summary>
/// Patch level loading method to copy decal rotation and color from <see cref="Celeste.DecalData" /> instances into newly created <see cref="Celeste.Decal" /> entities.
/// Patch level loading method to copy decal rotation, color, and depth from <see cref="Celeste.DecalData" /> instances into newly created <see cref="Celeste.Decal" /> entities.
/// </summary>
[MonoModCustomMethodAttribute(nameof(MonoModRules.PatchLevelLoaderDecalCreation))]
class PatchLevelLoaderDecalCreationAttribute : Attribute { }
Expand Down Expand Up @@ -806,6 +806,12 @@ public static void PatchLevelLoaderDecalCreation(ILContext context, CustomAttrib

FieldDefinition f_DecalData_Rotation = t_DecalData.FindField("Rotation");
FieldDefinition f_DecalData_ColorHex = t_DecalData.FindField("ColorHex");
FieldDefinition f_DecalData_Depth = t_DecalData.FindField("Depth");

FieldDefinition f_Decal_DepthSetByPlacement = t_Decal.FindField("DepthSetByPlacement");

MethodDefinition m_DecalData_HasDepth = t_DecalData.FindMethod("HasDepth");
MethodDefinition m_DecalData_GetDepth = t_DecalData.FindMethod("GetDepth");

MethodDefinition m_Decal_ctor = t_Decal.FindMethod("System.Void .ctor(System.String,Microsoft.Xna.Framework.Vector2,Microsoft.Xna.Framework.Vector2,System.Int32,System.Single,System.String)");

Expand All @@ -819,15 +825,33 @@ public static void PatchLevelLoaderDecalCreation(ILContext context, CustomAttrib
instr => instr.MatchLdfld("Celeste.DecalData", "Scale"),
instr => instr.MatchLdcI4(Celeste.Depths.FGDecals)
|| instr.MatchLdcI4(Celeste.Depths.BGDecals))) {
// load the rotation from the DecalData
// load the depth from the DecalData, with the Celeste.Depths.??Decals value as a default
cursor.Index--;
cursor.Emit(OpCodes.Ldloc_S, (byte) loc_decaldata);
cursor.Index++;
cursor.Emit(OpCodes.Call, m_DecalData_GetDepth);

// load the rotation and color from the DecalData
cursor.Emit(OpCodes.Ldloc_S, (byte) loc_decaldata);
cursor.Emit(OpCodes.Ldfld, f_DecalData_Rotation);
cursor.Emit(OpCodes.Ldloc_S, (byte) loc_decaldata);
cursor.Emit(OpCodes.Ldfld, f_DecalData_ColorHex);

// and replace the Decal constructor to accept it
cursor.Emit(OpCodes.Newobj, m_Decal_ctor);
cursor.Remove();

// if the depth was set in the DecalData...
ILLabel after_set = cursor.DefineLabel();
cursor.Emit(OpCodes.Ldloc_S, (byte) loc_decaldata);
cursor.Emit(OpCodes.Call, m_DecalData_HasDepth);
cursor.Emit(OpCodes.Brfalse_S, after_set);
// store that information in the Decal
cursor.Emit(OpCodes.Dup);
cursor.Emit(OpCodes.Ldc_I4_1);
cursor.Emit(OpCodes.Stfld, f_Decal_DepthSetByPlacement);
cursor.MarkLabel(after_set);

matches++;
}
if (matches != 2) {
Expand Down
33 changes: 29 additions & 4 deletions Celeste.Mod.mm/Patches/LevelData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,16 @@ we found
public static void PatchLevelDataDecalLoader(ILContext context, CustomAttribute attrib) {
TypeDefinition t_DecalData = MonoModRule.Modder.FindType("Celeste.DecalData").Resolve();
TypeDefinition t_BinaryPackerElement = MonoModRule.Modder.FindType("Celeste.BinaryPacker/Element").Resolve();
TypeDefinition t_Extensions = MonoModRule.Modder.FindType("Celeste.Mod.Extensions").Resolve();

MethodDefinition m_BinaryPackerElementAttr = t_BinaryPackerElement.FindMethod("Attr");
MethodDefinition m_BinaryPackerElementAttrFloat = t_BinaryPackerElement.FindMethod("AttrFloat");
MethodDefinition m_BinaryPackerElementHasAttr = t_BinaryPackerElement.FindMethod("HasAttr");
MethodDefinition m_BinaryPackerElementAttr = t_BinaryPackerElement.FindMethod("Attr");
MethodDefinition m_BinaryPackerElementAttrFloat = t_BinaryPackerElement.FindMethod("AttrFloat");
MethodDefinition m_BinaryPackerElementAttrNullableInt = t_Extensions.FindMethod("AttrNullableInt");

FieldDefinition f_DecalDataRotation = t_DecalData.FindField("Rotation");
FieldDefinition f_DecalDataColorHex = t_DecalData.FindField("ColorHex");
FieldDefinition f_DecalDataDepth = t_DecalData.FindField("Depth");

ILCursor cursor = new ILCursor(context);

Expand All @@ -186,14 +190,16 @@ public static void PatchLevelDataDecalLoader(ILContext context, CustomAttribute
// we are trying to add:
// decaldata.Rotation = element.AttrFloat("rotation", 0.0f);
// decaldata.ColorHex = element.AttrString("color", "");
// if (element.HasAttr("depth"))
// decaldata.Depth = element.AttrNullableInt("depth");

// copy the reference to the DecalData
cursor.Emit(OpCodes.Dup);
// load the rotation from the BinaryPacker.Element, with a default of 0.0f
cursor.Emit(OpCodes.Ldloc, loc_element);
cursor.Emit(OpCodes.Ldstr, "rotation");
cursor.Emit(OpCodes.Ldc_R4, 0.0f);
cursor.Emit(OpCodes.Callvirt, m_BinaryPackerElementAttrFloat);
cursor.Emit(OpCodes.Call, m_BinaryPackerElementAttrFloat);
// put the rotation into the DecalData
cursor.Emit(OpCodes.Stfld, f_DecalDataRotation);

Expand All @@ -203,10 +209,29 @@ public static void PatchLevelDataDecalLoader(ILContext context, CustomAttribute
cursor.Emit(OpCodes.Ldloc, loc_element);
cursor.Emit(OpCodes.Ldstr, "color");
cursor.Emit(OpCodes.Ldstr, "");
cursor.Emit(OpCodes.Callvirt, m_BinaryPackerElementAttr);
cursor.Emit(OpCodes.Call, m_BinaryPackerElementAttr);
// put the color into the DecalData
cursor.Emit(OpCodes.Stfld, f_DecalDataColorHex);

// find out if there is a depth field in the BinaryPacker.Element
cursor.Emit(OpCodes.Ldloc, loc_element);
cursor.Emit(OpCodes.Ldstr, "depth");
cursor.Emit(OpCodes.Call, m_BinaryPackerElementHasAttr);
// if not, skip to after setting it
ILLabel after_attr_depth = cursor.DefineLabel();
cursor.Emit(OpCodes.Brfalse_S, after_attr_depth);

// copy the reference to the DecalData again
cursor.Emit(OpCodes.Dup);
// load the depth from the BinaryPacker.Element
cursor.Emit(OpCodes.Ldloc, loc_element);
cursor.Emit(OpCodes.Ldstr, "depth");
cursor.Emit(OpCodes.Call, m_BinaryPackerElementAttrNullableInt);
// put the depth into the DecalData
cursor.Emit(OpCodes.Stfld, f_DecalDataDepth);

cursor.MarkLabel(after_attr_depth);

matches++;
}
if (matches != 2) {
Expand Down

0 comments on commit 283dd69

Please sign in to comment.