diff --git a/Code/Entities/Lilly.cs b/Code/Entities/Lilly.cs index 357b73b..16b4564 100644 --- a/Code/Entities/Lilly.cs +++ b/Code/Entities/Lilly.cs @@ -54,15 +54,15 @@ public void UpdateArm(float move) public const float ArmSpeed = 240; public const float ArmSpeedRetract = 112; - public static readonly Color IdleColor = Calc.HexToColor("0061ff"); - public static readonly Color ClimbedOnColor = Calc.HexToColor("ff38f1"); - public static readonly Color DashColor = Calc.HexToColor("ff0033"); - public static readonly Color RetractColor = Calc.HexToColor("4800ff"); - public static readonly Color IdleAltColor = Calc.HexToColor("00d0ff"); - public static readonly Color ClimbedOnAltColor = Calc.HexToColor("f432ff"); - public static readonly Color HorrifiedColor = Calc.HexToColor("bc51ff"); - - private Color colorTo = IdleColor, colorFrom = IdleColor; + private readonly Color idleColor = Calc.HexToColor("0061ff"); + private readonly Color climbedOnColor = Calc.HexToColor("ff38f1"); + private readonly Color dashColor = Calc.HexToColor("ff0033"); + private readonly Color retractColor = Calc.HexToColor("4800ff"); + private readonly Color idleAltColor = Calc.HexToColor("00d0ff"); + private readonly Color climbedOnAltColor = Calc.HexToColor("f432ff"); + private readonly Color horrifiedColor = Calc.HexToColor("bc51ff"); + + private Color colorTo = Calc.HexToColor("0061ff"), colorFrom = Calc.HexToColor("0061ff"); // IdleColor private float colorLerp = 1f; public enum FaceState @@ -108,13 +108,17 @@ public enum FaceState private readonly List rightStaticMovers = new(); public Lilly(EntityData data, Vector2 offset) - : this(data.Position + offset, data.Height, data.Int("maxLength")) { } + : this(data.Position + offset, data.Height, data.Int("maxLength"), data.Attr("spriteDir", "").Trim().TrimEnd('/'), + data.HexColor("idleColor", Calc.HexToColor("0061ff")), data.HexColor("climbedOnColor", Calc.HexToColor("ff38f1")), data.HexColor("dashColor", Calc.HexToColor("ff0033")), data.HexColor("retractColor", Calc.HexToColor("4800ff")), + data.HexColor("idleAltColor", Calc.HexToColor("00d0ff")), data.HexColor("climbedOnAltColor", Calc.HexToColor("f432ff")), data.HexColor("horrifiedColor", Calc.HexToColor("bc51ff"))) + { } - public Lilly(Vector2 position, int height, int maxLength) + public Lilly(Vector2 position, int height, int maxLength, string spriteDir, + Color idleColor, Color climbedOnColor, Color dashColor, Color retractColor, Color idleAltColor, Color climbedOnAltColor, Color horrifiedColor) : base(position, 24, height, true) { this.SurfaceSoundIndex = SurfaceIndex.CassetteBlock; - this.arm = GFX.Game.GetAtlasSubtextures("objects/VortexHelper/squareBumperNew/arm"); + this.arm = GFX.Game.GetAtlasSubtextures(string.IsNullOrEmpty(spriteDir) ? "objects/VortexHelper/squareBumperNew/arm" : spriteDir + "/arm"); this.maxLength = Math.Abs(maxLength); @@ -125,11 +129,22 @@ public Lilly(Vector2 position, int height, int maxLength) Position = middle }); - this.face = VortexHelperModule.LillySpriteBank.Create("lillyFace"); + this.idleColor = idleColor; + this.climbedOnColor = climbedOnColor; + this.dashColor = dashColor; + this.retractColor = retractColor; + this.idleAltColor = idleAltColor; + this.climbedOnAltColor = climbedOnAltColor; + this.horrifiedColor = horrifiedColor; + this.colorFrom = this.colorTo = this.idleColor; + + this.face = string.IsNullOrEmpty(spriteDir) ? VortexHelperModule.LillySpriteBank.Create("lillyFace") : BuildCustomFaceSprite(spriteDir); this.face.Position = middle + Vector2.UnitY; - this.face.Color = IdleColor; + this.face.Color = this.idleColor; Add(this.face); + if (!string.IsNullOrEmpty(spriteDir)) InitializeTextures(spriteDir); + this.OnDashCollide = OnDashed; Add(this.bloom = new BloomPoint(.65f, 16f) @@ -139,6 +154,40 @@ public Lilly(Vector2 position, int height, int maxLength) }); } + private static Sprite BuildCustomFaceSprite(string path) + { + Sprite faceSprite = new Sprite(GFX.Game, path + "/"); + + // + faceSprite.AddLoop("idle", "face", 0f, 0); + // + faceSprite.Add("idle_climb", "face", 0.08f, 1, 2, 3); + // + faceSprite.Add("climb_idle", "face", 0.08f, "idle", 2, 1, 0); + + // + faceSprite.Add("dashed", "face", 0.5f, "dash", 4); + // + faceSprite.AddLoop("dash", "face", 0.08f, 5, 6); + + // + faceSprite.Add("retract", "face", 0.08f, 7, 8, 9); + // + faceSprite.Add("end_retract", "face", 0.08f, "idle_alt", 10, 11, 12); + + // + faceSprite.AddLoop("idle_alt", "face", 0.08f, 12); + // + faceSprite.AddLoop("climb_alt", "face", 0.08f, 13); + + // + faceSprite.Add("horrified", "face", 0.06f, 14, 15, 16, 15, 16, 15, 16, 15, 16, 15, 16, 15, 16, 17, 18, 0); + + faceSprite.JustifyOrigin(0.5f, 0.5f); + faceSprite.Play("idle"); + return faceSprite; + } + private DashCollisionResults OnDashed(Player player, Vector2 dir) { if (this.Activated) @@ -154,7 +203,7 @@ private IEnumerator DashedSequence() // Dashed in, shaking. this.faceState = FaceState.Dash; this.face.Play("dashed", true); - ChangeColor(DashColor); + ChangeColor(dashColor); StartShaking(0.375f); Audio.Play(CustomSFX.game_lilly_dashed, this.Center); yield return 0.5f; @@ -236,7 +285,7 @@ private IEnumerator DashedSequence() this.faceState = FaceState.Retract; this.face.Play("retract"); this.sfx.Play(CustomSFX.game_lilly_conveyor, "end", 0f); - ChangeColor(RetractColor); + ChangeColor(retractColor); float retractFactor = 0f; while (rightArmExtended || leftArmExtended) @@ -293,7 +342,7 @@ private IEnumerator DashedSequence() this.sfx.Param("end", 1f); this.faceState = FaceState.IdleAlt; this.face.Play("end_retract"); - ChangeColor(IdleAltColor); + ChangeColor(idleAltColor); this.armsExtended = false; RemoveArms(rightArmEnd, rightArm); @@ -333,7 +382,7 @@ private void UpdateFace() { this.faceState = FaceState.Horrified; this.face.Play("horrified"); - ChangeColor(HorrifiedColor); + ChangeColor(horrifiedColor); } if (this.Activated || this.faceState == FaceState.Horrified) @@ -344,25 +393,25 @@ private void UpdateFace() { this.faceState = FaceState.ClimbedOn; this.face.Play("idle_climb"); - ChangeColor(ClimbedOnColor); + ChangeColor(climbedOnColor); } else if (!ridden && this.faceState == FaceState.ClimbedOn) { this.faceState = FaceState.Idle; this.face.Play("climb_idle"); - ChangeColor(IdleColor); + ChangeColor(idleColor); } else if (ridden && this.faceState == FaceState.IdleAlt) { this.faceState = FaceState.ClimbedOnAlt; this.face.Play("climb_alt"); - ChangeColor(ClimbedOnAltColor); + ChangeColor(climbedOnAltColor); } else if (!ridden && this.faceState == FaceState.ClimbedOnAlt) { this.faceState = FaceState.IdleAlt; this.face.Play("idle_alt"); - ChangeColor(IdleAltColor); + ChangeColor(idleAltColor); } } @@ -465,13 +514,13 @@ public override void Render() this.Position = pos; } - public static void InitializeTextures() + public static void InitializeTextures(string path = "objects/VortexHelper/squareBumperNew") { - MTexture block00 = GFX.Game["objects/VortexHelper/squareBumperNew/block00"]; - MTexture block01 = GFX.Game["objects/VortexHelper/squareBumperNew/block01"]; - MTexture active_block00 = GFX.Game["objects/VortexHelper/squareBumperNew/active_block00"]; - MTexture active_block01 = GFX.Game["objects/VortexHelper/squareBumperNew/active_block01"]; - MTexture armend = GFX.Game["objects/VortexHelper/squareBumperNew/armend"]; + MTexture block00 = GFX.Game[path + "/block00"]; + MTexture block01 = GFX.Game[path + "/block01"]; + MTexture active_block00 = GFX.Game[path + "/active_block00"]; + MTexture active_block01 = GFX.Game[path + "/active_block01"]; + MTexture armend = GFX.Game[path + "/armend"]; for (int j = 0; j < 4; j++) { diff --git a/Loenn/entities/lilly.lua b/Loenn/entities/lilly.lua index b070bb6..3240d15 100644 --- a/Loenn/entities/lilly.lua +++ b/Loenn/entities/lilly.lua @@ -3,14 +3,42 @@ local drawableSprite = require "structs.drawable_sprite" local lilly = {} lilly.name = "VortexHelper/Lilly" -lilly.minimumSize = {24, 24} -lilly.canResize = {false, true} +lilly.minimumSize = { 24, 24 } +lilly.canResize = { false, true } lilly.fieldInformation = { maxLength = { fieldType = "integer", minimumValue = 0 - } + }, + idleColor = { + fieldType = "color" + }, + climbedOnColor = { + fieldType = "color" + }, + dashColor = { + fieldType = "color" + }, + retractColor = { + fieldType = "color" + }, + idleAltColor = { + fieldType = "color" + }, + climbedOnAltColor = { + fieldType = "color" + }, + horrifiedColor = { + fieldType = "color" + }, +} + +lilly.fieldOrder = { + "x", "y", "width", "height", + "maxLength", "spritesDir", + "idleColor", "climbedOnColor", "dashColor", "retractColor", + "idleAltColor", "climbedOnAltColor", "horrifiedColor" } lilly.placements = { @@ -19,16 +47,34 @@ lilly.placements = { data = { width = 24, height = 24, - maxLength = 64 + maxLength = 64, + spriteDir = "", + idleColor = "0061ff", + climbedOnColor = "ff38f1", + dashColor = "ff0033", + retractColor = "4800ff", + idleAltColor = "00d0ff", + climbedOnAltColor = "f432ff", + horrifiedColor = "bc51ff", } } } -local block = "objects/VortexHelper/squareBumperNew/block00" -local face = "objects/VortexHelper/squareBumperNew/face12" -local armend = "objects/VortexHelper/squareBumperNew/armend" -local arm = "objects/VortexHelper/squareBumperNew/arm00" -local color = {0.0, 208 / 255, 1.0, 1.0} +local defaultSpriteDir = "objects/VortexHelper/squareBumperNew" + +local block, face, armend, arm +local color + +local function reloadSprites(entity) + local spriteDir = (entity.spriteDir ~= "" and entity.spriteDir) and entity.spriteDir or defaultSpriteDir + + block = spriteDir .. "/block00" + face = spriteDir .. "/face12" + armend = spriteDir .. "/armend" + arm = spriteDir .. "/arm00" + + color = entity.idleColor or { 0.0, 208 / 255, 1.0, 1.0 } +end local function addBlockSprites(sprites, entity, h, armLength) for i = 0, h - 1 do @@ -75,6 +121,7 @@ function lilly.sprite(room, entity) local tileHeight = math.floor(height / 8) local armLength = entity.maxLength or 64 + reloadSprites(entity) local sprites = {} x = 16 + armLength diff --git a/Loenn/lang/en_gb.lang b/Loenn/lang/en_gb.lang index 0096185..cd6422f 100644 --- a/Loenn/lang/en_gb.lang +++ b/Loenn/lang/en_gb.lang @@ -62,6 +62,8 @@ entities.VortexHelper/FloorBooster.attributes.description.notAttached=If ticked, # Lilly entities.VortexHelper/Lilly.placements.name.lilly=Lilly entities.VortexHelper/Lilly.attributes.description.maxLength=The maximum distance at which this Lilly's arms can extend. +entities.VortexHelper/Lilly.attributes.description.spriteDir=Custom sprite path for this Lilly that leads to custom frames.\nThe frame count and image names must match the ones from the original skin.\nFor instance: face00.png, face01.png, face02.png, ..., arm00.png, arm01.png, etc.\nThe sprites must be located somewhere in the Gameplay atlas (somewhere in Graphics/Atlases/Gameplay/).\n\nExample: objects/myMap/myCustomLilly\n..should be valid if there exists files whose paths are Graphics/Atlases/Gameplay/objects/myMap/myCustomLilly/face00.png, etc. + # Puffer Barrier entities.VortexHelper/PufferBarrier.placements.name.puffer_barrier=Puffer Barrier