diff --git a/Code/Entities/BoomBox.cs b/Code/Entities/BoomBox.cs index c517143..a0ce432 100644 --- a/Code/Entities/BoomBox.cs +++ b/Code/Entities/BoomBox.cs @@ -36,7 +36,7 @@ public class BoomBox : Solid { private Coroutine _sequence; private bool _steamAnger = false; - public BoomBox(Vector2 position, string activationId, float initialDelay, bool startActive) + public BoomBox(Vector2 position, string activationId, float initialDelay, bool startActive, string spriteDir) : base(position, 24, 24, false) { Add(Activator = new FactoryActivator()); Activator.StartOn = startActive; @@ -50,14 +50,16 @@ public BoomBox(Vector2 position, string activationId, float initialDelay, bool s _initialDelay = initialDelay; - Add(_sprite = new Sprite(GFX.Game, "objects/FactoryHelper/boomBox/")); + string spritePath = string.IsNullOrEmpty(spriteDir) ? "objects/FactoryHelper/boomBox/" : spriteDir + "/"; + + Add(_sprite = new Sprite(GFX.Game, spritePath)); _sprite.Add("idle", "idle", 0.2f, "idle"); _sprite.Add("activating", "activating", 0.2f, "activating"); _sprite.Add("active", "active", 0.15f, "active"); _sprite.Add("angry", "angry", 0.05f, "angry"); _sprite.Add("resetting", "resetting", 0.15f, "active"); - Add(_boomSprite = new Sprite(GFX.Game, "objects/FactoryHelper/boomBox/")); + Add(_boomSprite = new Sprite(GFX.Game, spritePath)); _boomSprite.Add("boom", "boom", 0.04f); _boomSprite.Color = Color.White * 0.5f; _boomSprite.Visible = false; @@ -71,7 +73,7 @@ public BoomBox(Vector2 position, string activationId, float initialDelay, bool s } public BoomBox(EntityData data, Vector2 offest) - : this(data.Position + offest, data.Attr("activationId", ""), data.Float("initialDelay", 0f), data.Bool("startActive", false)) { + : this(data.Position + offest, data.Attr("activationId", ""), data.Float("initialDelay", 0f), data.Bool("startActive", false), data.Attr("spriteDir", "")) { } public FactoryActivator Activator { get; } diff --git a/Code/Entities/BoomBoxZip.cs b/Code/Entities/BoomBoxZip.cs index abac6b8..7b68854 100644 --- a/Code/Entities/BoomBoxZip.cs +++ b/Code/Entities/BoomBoxZip.cs @@ -8,50 +8,60 @@ namespace FactoryHelper.Entities { [CustomEntity("FactoryHelper/BoomBoxZip")] public class BoomBoxZip : BoomBox { - public float percent; - public Vector2 start, target; - private ZipMoverPathRenderer pathRenderer; + private float _percent; + private Vector2 _start, _target; + private ZipMoverPathRenderer _pathRenderer; - public BoomBoxZip(EntityData data, Vector2 offset) - : this(data.Position + offset, data.Attr("activationId", ""), data.Float("initialDelay", 0f), data.Bool("startActive", false), data.Nodes[0] + offset) { - } + private readonly string _spriteDir; + private readonly Color _ropeColor, _ropeLightColor, _sparkParticleColor; + + public BoomBoxZip(EntityData data, Vector2 offset) + : this(data.Position + offset, data.Attr("activationId", ""), data.Float("initialDelay", 0f), data.Bool("startActive", false), data.Nodes[0] + offset, + data.Attr("spriteDir", ""), data.HexColor("ropeColor", Calc.HexToColor("4d3c22")), data.HexColor("ropeLightColor", Calc.HexToColor("766c49")), data.HexColor("sparkParticleColor", Calc.HexToColor("fff538"))) { } - public BoomBoxZip(Vector2 position, string activationId, float initialDelay, bool startActive, Vector2 target) - : base(position, activationId, initialDelay, startActive) { + public BoomBoxZip(Vector2 position, string activationId, float initialDelay, bool startActive, Vector2 target, string spriteDir, Color ropeColor, Color ropeLightColor, Color sparkParticleColor) + : base(position, activationId, initialDelay, startActive, spriteDir) { Add(new Coroutine(ZipMoverSequence())); - this.start = this.Position; - this.target = target; + _start = position; + _target = target; + + _spriteDir = string.IsNullOrEmpty(spriteDir) ? "objects/FactoryHelper/boomBox" : spriteDir; + _ropeColor = ropeColor; + _ropeLightColor = ropeLightColor; + _sparkParticleColor = sparkParticleColor; } public override void Added(Scene scene) { base.Added(scene); - scene.Add(pathRenderer = new ZipMoverPathRenderer(this)); + scene.Add(_pathRenderer = new ZipMoverPathRenderer(this)); } private IEnumerator ZipMoverSequence() { - start = Position; + _start = Position; while (true) { if (!HasPlayerRider()) { yield return null; continue; } + Input.Rumble(RumbleStrength.Medium, RumbleLength.Short); StartShaking(0.1f); yield return 0.1f; StopPlayerRunIntoAnimation = false; - float at2 = 0f; - while (at2 < 1f) { + + float at = 0f; + while (at < 1f) { yield return null; - at2 = Calc.Approach(at2, 1f, 2f * Engine.DeltaTime); - percent = Ease.SineIn(at2); - Vector2 vector = Vector2.Lerp(start, target, percent); - ScrapeParticlesCheck(vector); + at = Calc.Approach(at, 1f, 2f * Engine.DeltaTime); + _percent = Ease.SineIn(at); + Vector2 position = Vector2.Lerp(_start, _target, _percent); + ScrapeParticlesCheck(position); if (Scene.OnInterval(0.1f)) { - pathRenderer.CreateSparks(); + _pathRenderer.CreateSparks(); } - MoveTo(vector); - _boomCollider.Position = vector + new Vector2(Width / 2, Height / 2); + MoveTo(position); + _boomCollider.Position = position + new Vector2(Width / 2, Height / 2); } StartShaking(0.2f); @@ -60,12 +70,13 @@ private IEnumerator ZipMoverSequence() { StopPlayerRunIntoAnimation = true; yield return 0.5f; StopPlayerRunIntoAnimation = false; - at2 = 0f; - while (at2 < 1f) { + + at = 0f; + while (at < 1f) { yield return null; - at2 = Calc.Approach(at2, 1f, 0.5f * Engine.DeltaTime); - percent = 1f - Ease.SineIn(at2); - Vector2 position = Vector2.Lerp(target, start, Ease.SineIn(at2)); + at = Calc.Approach(at, 1f, 0.5f * Engine.DeltaTime); + _percent = 1f - Ease.SineIn(at); + Vector2 position = Vector2.Lerp(_target, _start, Ease.SineIn(at)); MoveTo(position); _boomCollider.Position = position + new Vector2(Width / 2, Height / 2); } @@ -77,101 +88,95 @@ private IEnumerator ZipMoverSequence() { } private void ScrapeParticlesCheck(Vector2 to) { - if (!base.Scene.OnInterval(0.03f)) { + if (!Scene.OnInterval(0.03f)) { return; } - bool flag = to.Y != base.ExactPosition.Y; - bool flag2 = to.X != base.ExactPosition.X; - if (flag && !flag2) { - int num = Math.Sign(to.Y - base.ExactPosition.Y); - Vector2 value = (num != 1) ? base.TopLeft : base.BottomLeft; - int num2 = 4; - if (num == 1) { - num2 = Math.Min((int)base.Height - 12, 20); + bool movingY = to.Y != ExactPosition.Y; + bool movingX = to.X != ExactPosition.X; + if (movingY && !movingX) { + int movingDir = Math.Sign(to.Y - ExactPosition.Y); + Vector2 checkFrom = movingDir == 1 ? BottomLeft : TopLeft; + + int particlesStart = 4; + if (movingDir == 1) { + particlesStart = Math.Min((int)Height - 12, 20); } - int num3 = (int)base.Height; - if (num == -1) { - num3 = Math.Max(16, (int)base.Height - 16); + int particlesEnd = (int)Height; + if (movingDir == -1) { + particlesEnd = Math.Max(16, (int)Height - 16); } - if (base.Scene.CollideCheck(value + new Vector2(-2f, num * -2))) { - for (int i = num2; i < num3; i += 8) { - SceneAs().ParticlesFG.Emit(ZipMover.P_Scrape, base.TopLeft + new Vector2(0f, (float)i + (float)num * 2f), (num == 1) ? (-(float)Math.PI / 4f) : ((float)Math.PI / 4f)); + if (Scene.CollideCheck(checkFrom + new Vector2(-2f, movingDir * -2))) { + for (int i = particlesStart; i < particlesEnd; i += 8) { + SceneAs().ParticlesFG.Emit(ZipMover.P_Scrape, TopLeft + new Vector2(0f, i + movingDir * 2f), (movingDir == 1) ? (-MathF.PI / 4f) : (MathF.PI / 4f)); } } - if (base.Scene.CollideCheck(value + new Vector2(base.Width + 2f, num * -2))) { - for (int j = num2; j < num3; j += 8) { - SceneAs().ParticlesFG.Emit(ZipMover.P_Scrape, base.TopRight + new Vector2(-1f, (float)j + (float)num * 2f), (num == 1) ? ((float)Math.PI * -3f / 4f) : ((float)Math.PI * 3f / 4f)); + if (Scene.CollideCheck(checkFrom + new Vector2(Width + 2f, movingDir * -2))) { + for (int i = particlesStart; i < particlesEnd; i += 8) { + SceneAs().ParticlesFG.Emit(ZipMover.P_Scrape, TopRight + new Vector2(-1f, i + movingDir * 2f), (movingDir == 1) ? (MathF.PI * -3f / 4f) : (MathF.PI * 3f / 4f)); } } - } else { - if (!flag2 || flag) { - return; - } + } else if (movingX && !movingY) { + int movingDir = Math.Sign(to.X - ExactPosition.X); + Vector2 checkFrom = movingDir == 1 ? TopRight : TopLeft; - int num4 = Math.Sign(to.X - base.ExactPosition.X); - Vector2 value2 = (num4 != 1) ? base.TopLeft : base.TopRight; - int num5 = 4; - if (num4 == 1) { - num5 = Math.Min((int)base.Width - 12, 20); + int particlesStart = 4; + if (movingDir == 1) { + particlesStart = Math.Min((int)Width - 12, 20); } - int num6 = (int)base.Width; - if (num4 == -1) { - num6 = Math.Max(16, (int)base.Width - 16); + int particlesEnd = (int)Width; + if (movingDir == -1) { + particlesEnd = Math.Max(16, (int)Width - 16); } - if (base.Scene.CollideCheck(value2 + new Vector2(num4 * -2, -2f))) { - for (int k = num5; k < num6; k += 8) { - SceneAs().ParticlesFG.Emit(ZipMover.P_Scrape, base.TopLeft + new Vector2((float)k + (float)num4 * 2f, -1f), (num4 == 1) ? ((float)Math.PI * 3f / 4f) : ((float)Math.PI / 4f)); + if (Scene.CollideCheck(checkFrom + new Vector2(movingDir * -2, -2f))) { + for (int i = particlesStart; i < particlesEnd; i += 8) { + SceneAs().ParticlesFG.Emit(ZipMover.P_Scrape, TopLeft + new Vector2(i + movingDir * 2f, -1f), (movingDir == 1) ? (MathF.PI * 3f / 4f) : (MathF.PI / 4f)); } } - if (base.Scene.CollideCheck(value2 + new Vector2(num4 * -2, base.Height + 2f))) { - for (int l = num5; l < num6; l += 8) { - SceneAs().ParticlesFG.Emit(ZipMover.P_Scrape, base.BottomLeft + new Vector2((float)l + (float)num4 * 2f, 0f), (num4 == 1) ? ((float)Math.PI * -3f / 4f) : (-(float)Math.PI / 4f)); + if (Scene.CollideCheck(checkFrom + new Vector2(movingDir * -2, Height + 2f))) { + for (int i = particlesStart; i < particlesEnd; i += 8) { + SceneAs().ParticlesFG.Emit(ZipMover.P_Scrape, BottomLeft + new Vector2(i + movingDir * 2f, 0f), (movingDir == 1) ? (MathF.PI * -3f / 4f) : (-MathF.PI / 4f)); } } } } private class ZipMoverPathRenderer : Entity { - private static readonly Color ropeColor = Calc.HexToColor("4d3c22"); - private static readonly Color ropeLightColor = Calc.HexToColor("766c49"); - - public BoomBoxZip zipMover; + private readonly BoomBoxZip _zipMover; - private MTexture cog; - private Vector2 from; - private Vector2 to; - private Vector2 sparkAdd; - private float sparkDirFromA; - private float sparkDirFromB; - private float sparkDirToA; - private float sparkDirToB; + private readonly MTexture _cogTexture; + private readonly Vector2 _from, _to; + private readonly Vector2 _sparkAdd; + private readonly float _sparkDirFromA, _sparkDirFromB; + private readonly float _sparkDirToA, _sparkDirToB; public ZipMoverPathRenderer(BoomBoxZip zipMover) { - base.Depth = 5000; - this.zipMover = zipMover; - from = this.zipMover.start + new Vector2(this.zipMover.Width / 2f, this.zipMover.Height / 2f); - to = this.zipMover.target + new Vector2(this.zipMover.Width / 2f, this.zipMover.Height / 2f); - sparkAdd = (from - to).SafeNormalize(5f).Perpendicular(); - float num = (from - to).Angle(); - sparkDirFromA = num + (float)Math.PI / 8f; - sparkDirFromB = num - (float)Math.PI / 8f; - sparkDirToA = num + (float)Math.PI - (float)Math.PI / 8f; - sparkDirToB = num + (float)Math.PI + (float)Math.PI / 8f; - cog = GFX.Game["objects/zipmover/cog"]; + Depth = 5000; + _zipMover = zipMover; + _from = _zipMover._start + new Vector2(_zipMover.Width / 2f, _zipMover.Height / 2f); + _to = _zipMover._target + new Vector2(_zipMover.Width / 2f, _zipMover.Height / 2f); + _sparkAdd = (_from - _to).SafeNormalize(5f).Perpendicular(); + float backwards = (_from - _to).Angle(); + _sparkDirFromA = backwards + MathF.PI / 8f; + _sparkDirFromB = backwards - MathF.PI / 8f; + _sparkDirToA = backwards + MathF.PI - MathF.PI / 8f; + _sparkDirToB = backwards + MathF.PI + MathF.PI / 8f; + string customCogSprite = zipMover._spriteDir + "/zipMoverCog"; + _cogTexture = GFX.Game[GFX.Game.Has(customCogSprite) ? customCogSprite : "objects/zipmover/cog"]; } public void CreateSparks() { - SceneAs().ParticlesBG.Emit(ZipMover.P_Sparks, from + sparkAdd + Calc.Random.Range(-Vector2.One, Vector2.One), sparkDirFromA); - SceneAs().ParticlesBG.Emit(ZipMover.P_Sparks, from - sparkAdd + Calc.Random.Range(-Vector2.One, Vector2.One), sparkDirFromB); - SceneAs().ParticlesBG.Emit(ZipMover.P_Sparks, to + sparkAdd + Calc.Random.Range(-Vector2.One, Vector2.One), sparkDirToA); - SceneAs().ParticlesBG.Emit(ZipMover.P_Sparks, to - sparkAdd + Calc.Random.Range(-Vector2.One, Vector2.One), sparkDirToB); + Color sparkParticleColor = _zipMover._sparkParticleColor; + SceneAs().ParticlesBG.Emit(ZipMover.P_Sparks, _from + _sparkAdd + Calc.Random.Range(-Vector2.One, Vector2.One), sparkParticleColor, _sparkDirFromA); + SceneAs().ParticlesBG.Emit(ZipMover.P_Sparks, _from - _sparkAdd + Calc.Random.Range(-Vector2.One, Vector2.One), sparkParticleColor, _sparkDirFromB); + SceneAs().ParticlesBG.Emit(ZipMover.P_Sparks, _to + _sparkAdd + Calc.Random.Range(-Vector2.One, Vector2.One), sparkParticleColor, _sparkDirToA); + SceneAs().ParticlesBG.Emit(ZipMover.P_Sparks, _to - _sparkAdd + Calc.Random.Range(-Vector2.One, Vector2.One), sparkParticleColor, _sparkDirToB); } public override void Render() { @@ -180,21 +185,22 @@ public override void Render() { } private void DrawCogs(Vector2 offset, Color? colorOverride = null) { - Vector2 vector = (to - from).SafeNormalize(); - Vector2 value = vector.Perpendicular() * 3f; - Vector2 value2 = -vector.Perpendicular() * 4f; - float rotation = zipMover.percent * (float)Math.PI * 2f; - Draw.Line(from + value + offset, to + value + offset, colorOverride.HasValue ? colorOverride.Value : ropeColor); - Draw.Line(from + value2 + offset, to + value2 + offset, colorOverride.HasValue ? colorOverride.Value : ropeColor); - for (float num = 4f - zipMover.percent * (float)Math.PI * 8f % 4f; num < (to - from).Length(); num += 4f) { - Vector2 value3 = from + value + vector.Perpendicular() + vector * num; - Vector2 value4 = to + value2 - vector * num; - Draw.Line(value3 + offset, value3 + vector * 2f + offset, colorOverride.HasValue ? colorOverride.Value : ropeLightColor); - Draw.Line(value4 + offset, value4 - vector * 2f + offset, colorOverride.HasValue ? colorOverride.Value : ropeLightColor); + Vector2 direction = (_to - _from).SafeNormalize(); + Vector2 rightRopeOffset = direction.Perpendicular() * 3f; + Vector2 leftRopeOffset = -direction.Perpendicular() * 4f; + + Draw.Line(_from + rightRopeOffset + offset, _to + rightRopeOffset + offset, colorOverride ?? _zipMover._ropeColor); + Draw.Line(_from + leftRopeOffset + offset, _to + leftRopeOffset + offset, colorOverride ?? _zipMover._ropeColor); + for (float num = 4f - _zipMover._percent * MathF.PI * 8f % 4f; num < (_to - _from).Length(); num += 4f) { + Vector2 rightSmallRopePos = _from + rightRopeOffset + direction.Perpendicular() + direction * num; + Vector2 leftSmallRopePos = _to + leftRopeOffset - direction * num; + Draw.Line(rightSmallRopePos + offset, rightSmallRopePos + direction * 2f + offset, colorOverride ?? _zipMover._ropeLightColor); + Draw.Line(leftSmallRopePos + offset, leftSmallRopePos - direction * 2f + offset, colorOverride ?? _zipMover._ropeLightColor); } - cog.DrawCentered(from + offset, colorOverride.HasValue ? colorOverride.Value : Color.White, 1f, rotation); - cog.DrawCentered(to + offset, colorOverride.HasValue ? colorOverride.Value : Color.White, 1f, rotation); + float cogRotation = _zipMover._percent * MathF.PI * 2f; + _cogTexture.DrawCentered(_from + offset, colorOverride ?? Color.White, 1f, cogRotation); + _cogTexture.DrawCentered(_to + offset, colorOverride ?? Color.White, 1f, cogRotation); } } } diff --git a/Loenn/entities/boom_box.lua b/Loenn/entities/boom_box.lua index 664e517..620c90e 100644 --- a/Loenn/entities/boom_box.lua +++ b/Loenn/entities/boom_box.lua @@ -13,15 +13,14 @@ boomBox.placements = { data = { activationId = "", initialDelay = 0.0, - startActive = true + startActive = true, + spriteDir = "" } } -local inactiveTexture = "objects/FactoryHelper/boomBox/idle00" -local activeTexture = "objects/FactoryHelper/boomBox/active00" - function boomBox.texture(room, entity) - return entity.startActive and activeTexture or inactiveTexture + local spriteDir = (entity.spriteDir or "") == "" and "objects/FactoryHelper/boomBox" or entity.spriteDir + return spriteDir .. (entity.startActive and "/active00" or "/idle00") end boomBox.justification = {0.0, 0.0} diff --git a/Loenn/entities/boom_box_zip.lua b/Loenn/entities/boom_box_zip.lua index c6f0b1c..ee16dcd 100644 --- a/Loenn/entities/boom_box_zip.lua +++ b/Loenn/entities/boom_box_zip.lua @@ -15,6 +15,15 @@ boomBoxZip.ignoredFields = {"_name", "_id", "width"} boomBoxZip.fieldInformation = { initialDelay = { minimumValue = 0.0 + }, + ropeColor = { + fieldType = "color" + }, + ropeLightColor = { + fieldType = "color" + }, + sparkParticleColor = { + fieldType = "color" } } @@ -24,19 +33,20 @@ boomBoxZip.placements = { width = 24, activationId = "", initialDelay = 0.0, - startActive = true + startActive = true, + spriteDir = "", + ropeColor = "4d3c22", + ropeLightColor = "766c49", + sparkParticleColor = "fff538" } } -local inactiveTexture = "objects/FactoryHelper/boomBox/idle00" -local activeTexture = "objects/FactoryHelper/boomBox/active00" -local cogTexture = "objects/zipmover/cog" -local ropeColor = {77 / 255, 60 / 255, 34 / 255} +local function addNodeSprites(sprites, entity, centerX, centerY, centerNodeX, centerNodeY, spriteDir) + local ropeColor = utils.getColor(entity.ropeColor) or {77 / 255, 60 / 255, 34 / 255} -local function addNodeSprites(sprites, entity, centerX, centerY, centerNodeX, centerNodeY) - local nodeCogSprite = drawableSprite.fromTexture(cogTexture, entity) - nodeCogSprite:setPosition(centerNodeX, centerNodeY) - nodeCogSprite:setJustification(0.5, 0.5) + local cogSprite = drawableSprite.fromTexture(spriteDir .. "/zipMoverCog", entity) or drawableSprite.fromTexture("objects/zipmover/cog", entity) + cogSprite:setPosition(centerNodeX, centerNodeY) + cogSprite:setJustification(0.5, 0.5) local points = {centerX, centerY, centerNodeX, centerNodeY} local leftLine = drawableLine.fromPoints(points, ropeColor, 1) @@ -56,43 +66,45 @@ local function addNodeSprites(sprites, entity, centerX, centerY, centerNodeX, ce table.insert(sprites, sprite) end - table.insert(sprites, nodeCogSprite) + table.insert(sprites, cogSprite) end function boomBoxZip.sprite(room, entity) local sprites = {} - + local x, y = entity.x or 0, entity.y or 0 local nodes = entity.nodes or {{x = 0, y = 0}} - + local spriteDir = (entity.spriteDir or "") == "" and "objects/FactoryHelper/boomBox" or entity.spriteDir + -- Draw cog + rope local halfWidth = 12 local centerX = x + halfWidth local centerY = y + halfWidth local centerNodeX = nodes[1].x + halfWidth local centerNodeY = nodes[1].y + halfWidth - addNodeSprites(sprites, entity, centerX, centerY, centerNodeX, centerNodeY) + addNodeSprites(sprites, entity, centerX, centerY, centerNodeX, centerNodeY, spriteDir) -- Draw boom box - local boomBoxTex = entity.startActive and activeTexture or inactiveTexture + local boomBoxTex = spriteDir .. (entity.startActive and "/active00" or "/idle00") local boomBoxSprite = drawableSprite.fromTexture(boomBoxTex, entity) boomBoxSprite:setPosition(centerX, centerY) boomBoxSprite:setJustification(0.5, 0.5) table.insert(sprites, boomBoxSprite) - + return sprites end function boomBoxZip.selection(room, entity) local x, y = entity.x or 0, entity.y or 0 local nodes = entity.nodes or {{x = 0, y = 0}} - + local halfWidth = 12 local centerX = x + halfWidth local centerY = y + halfWidth local centerNodeX = nodes[1].x + halfWidth local centerNodeY = nodes[1].y + halfWidth + local cogTexture = "objects/zipmover/cog" local cogSprite = drawableSprite.fromTexture(cogTexture, entity) local cogWidth, cogHeight = cogSprite.meta.width, cogSprite.meta.height diff --git a/Loenn/lang/en_gb.lang b/Loenn/lang/en_gb.lang index dca5d0e..e93b583 100644 --- a/Loenn/lang/en_gb.lang +++ b/Loenn/lang/en_gb.lang @@ -13,12 +13,17 @@ entities.FactoryHelper/BoomBox.placements.name.active=Boom Box entities.FactoryHelper/BoomBox.attributes.description.activationId=String value of the entity's activator ID. When a factory activator with this ID is turned on, the entity will toggle state. entities.FactoryHelper/BoomBox.attributes.description.initialDelay=The time it takes before the box starts turning on in seconds after activated. entities.FactoryHelper/BoomBox.attributes.description.startActive=If `true` the boom box will initially be active. +entities.FactoryHelper/BoomBox.attributes.description.spriteDir=The directory to look in for boom box sprites, relative to "Graphics/Atlases/Gameplay/".\nThe directory must contain "idle", "activating", "active", "angry", and "resetting" animations for the block, and a "boom" animation for the explosion.\nIf left empty, the default sprites in "objects/FactoryHelper/boomBox" will be used. # Boom Box Zip entities.FactoryHelper/BoomBoxZip.placements.name.active=Boom Box Zip entities.FactoryHelper/BoomBoxZip.attributes.description.activationId=String value of the entity's activator ID. When a factory activator with this ID is turned on, the entity will toggle state. entities.FactoryHelper/BoomBoxZip.attributes.description.initialDelay=The time it takes before the box starts turning on in seconds after activated. entities.FactoryHelper/BoomBoxZip.attributes.description.startActive=If `true` the boom box will initially be active. +entities.FactoryHelper/BoomBoxZip.attributes.description.spriteDir=The directory to look in for boom box sprites, relative to "Graphics/Atlases/Gameplay/".\nThe directory must contain "idle", "activating", "active", "angry", and "resetting" animations for the block, and a "boom" animation for the explosion.\nIf a "zipMoverCog" texture is also present in the directory, it will be used for the zip mover cogs instead of the vanilla texture.\nIf left empty, the default sprites in "objects/FactoryHelper/boomBox" will be used. +entities.FactoryHelper/BoomBoxZip.attributes.description.ropeColor=The color to use for the darker parts of the zip mover rope.\nDefault value is "4d3c22". +entities.FactoryHelper/BoomBoxZip.attributes.description.ropeLightColor=The color to use for the lighter parts of the zip mover rope.\nDefault value is "766c49". +entities.FactoryHelper/BoomBoxZip.attributes.description.sparkParticleColor=The color to use for the spark particles that appear on the zip mover cogs while the box is moving forwards.\nDefault value is "fff538". # Conveyor entities.FactoryHelper/Conveyor.placements.name.start_left=Conveyor (Left)