diff --git a/Code/SpinOrb.cs b/Code/SpinOrb.cs index 605533a..27db677 100644 --- a/Code/SpinOrb.cs +++ b/Code/SpinOrb.cs @@ -1,4 +1,5 @@ -using System; +using FMOD; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -22,17 +23,19 @@ class SpinOrb : Entity private const float fastRotateSpeed = MathHelper.Pi * 3f; private const float slowRotateSpeed = MathHelper.Pi * 0.75f; private float currentRotateSpeed = normalRotateSpeed; - private const float rotateRadius = 12f; private const float launchSpeed = 350f; private const float maxUseDelay = 1.5f; - private const float rotationOffset = MathHelper.PiOver2; + private const float spriteRotationOffset = MathHelper.PiOver2; + + // if set to false, rotate clockwise (default) + private bool rotateCounterclockwise; List debris = new List(); private bool debrisShaken = false; private bool debrisReturned = false; //Size 10 & fix stars not spawning in correct area - private Vector2 pivotPoint; - private float currentRotateAngle = -MathHelper.Pi / 2; + private float initialAngle; + private float currentRotateAngle; private float useDelay = 0; private Player playerEntity; @@ -57,11 +60,35 @@ class SpinOrb : Entity public SpinOrb(EntityData data, Vector2 offset) : base(data.Position + offset) { + rotateCounterclockwise = data.Bool("rotateCounterclockwise", false); + // in degrees, 0° = right + float initialRotateAngleDegrees = data.Float("initialAngle", 270); + // convert to radians + initialAngle = initialRotateAngleDegrees * (MathHelper.Pi / 180f); + string spritePath = data.Attr("spritePath", ""); + Depth = -8500; Collider = new Circle(8.5f, -0.5f, 0f); Add(new PlayerCollider(OnPlayer, null, null)); Add(light = new VertexLight(Color.White, 1f, 16, 32)); - Add(sprite = CanyonModule.SpriteBank.Create("spinorb")); + + // backwards compat in case someone used sprites.xml to overwrite sprites previously + if (spritePath.Equals("")) + { + Add(sprite = CanyonModule.SpriteBank.Create("spinorb")); + } + else + { + if (!spritePath.EndsWith("/")) spritePath += "/"; + Add(sprite = new Sprite(GFX.Game, spritePath)); + sprite.Justify = new Vector2(0.5f, 0.5f); + sprite.Add("idle", "idle", 0.2f, 0); + sprite.Add("playerenter", "enter", 0.2f, new Chooser("active"), 0, 1, 2); + sprite.Add("active", "active", 0.2f, 0, 1, 2); + sprite.Play("idle"); + } + sprite.Rotation = initialAngle + spriteRotationOffset; + Add(dashListener = new DashListener()); dashListener.OnDash = OnPlayerDashed; } @@ -69,7 +96,6 @@ public SpinOrb(EntityData data, Vector2 offset) : base(data.Position + offset) public override void Added(Scene scene) { base.Added(scene); - pivotPoint = Position; //outline Image image = new Image(GFX.Game["objects/canyon/spinorb/outline"]); image.CenterOrigin(); @@ -81,6 +107,16 @@ public override void Added(Scene scene) scene.Add(outline); } + public override void Removed(Scene scene) + { + base.Removed(scene); + if (moveSfx != null) + { + moveSfx.stop(STOP_MODE.ALLOWFADEOUT); + moveSfx.release(); + } + } + public override void Awake(Scene scene) { base.Awake(scene); @@ -115,7 +151,7 @@ private void OnPlayer(Player player) player.Speed = Vector2.Zero; player.RefillDash(); player.RefillStamina(); - currentRotateAngle = -rotationOffset;//in radians + currentRotateAngle = initialAngle;//in radians playerEntity = player; } } @@ -168,8 +204,15 @@ public override void Update() { currentRotateSpeed = normalRotateSpeed; } - sprite.Rotation = currentRotateAngle + rotationOffset; - currentRotateAngle += currentRotateSpeed * Engine.DeltaTime; + sprite.Rotation = currentRotateAngle + spriteRotationOffset; + if (rotateCounterclockwise) + { + currentRotateAngle -= currentRotateSpeed * Engine.DeltaTime; + } + else + { + currentRotateAngle += currentRotateSpeed * Engine.DeltaTime; + } } else { @@ -253,8 +296,8 @@ private void OnPlayerDashed(Vector2 direction) StarBurst starBurst = Engine.Pooler.Create().Init(Center, Calc.AngleToVector(currentRotateAngle + i * MathHelper.Pi / 72, 1f)); Scene.Add(starBurst); } - currentRotateAngle = -rotationOffset; - sprite.Rotation = 0; + currentRotateAngle = initialAngle; + sprite.Rotation = initialAngle + spriteRotationOffset; Visible = false; Collidable = false; BreakParticles(); diff --git a/Loenn/entities/spinorb.lua b/Loenn/entities/spinorb.lua index 3eb3aae..62551dd 100644 --- a/Loenn/entities/spinorb.lua +++ b/Loenn/entities/spinorb.lua @@ -1,15 +1,37 @@ local utils = require("utils") +local drawableSprite = require("structs.drawable_sprite") local spinorb = {} spinorb.name = "canyon/spinorb" spinorb.depth = -9999 -spinorb.texture = "objects/canyon/spinorb/idle00" spinorb.justification = {0.5, 0.5} spinorb.placements = { - name = "SpinOrb" + name = "SpinOrb", + data = { + rotateCounterclockwise = false, + initialAngle = 270, + spritePath = "objects/canyon/spinorb/" + } } +function spinorb.sprite(room, entity) + basePath = entity.spritePath or "objects/canyon/spinorb" + if not basePath:match(".*/$") then + basePath = basePath .. "/" + end + + local texture = basePath .. "idle00" + local sprite = drawableSprite.fromTexture(texture, entity) + + sprite:setJustification(0.5, 0.5) + + local angleDegrees = entity.initialAngle or 270 + sprite.rotation = math.rad(angleDegrees + 90) + + return sprite +end + function spinorb.rectangle(room, entity) local x, y = entity.x or 0, entity.y or 0 return utils.rectangle(x - 9, y - 21, 17, 30) diff --git a/Loenn/lang/en_gb.lang b/Loenn/lang/en_gb.lang index b608306..b91f984 100644 --- a/Loenn/lang/en_gb.lang +++ b/Loenn/lang/en_gb.lang @@ -13,6 +13,9 @@ entities.canyon/pushblock.attributes.description.customDebrisFromTileset=The deb # Spin Orb entities.canyon/spinorb.placements.name.SpinOrb=Spin Orb (Canyon) +entities.canyon/spinorb.attributes.description.initialAngle=Starting angle of the spin orb (in degrees, 0°=right, 90°=down). +entities.canyon/spinorb.attributes.description.spritePath=Path for the folder with the textures of the spin orb, relative to Graphics/Atlases/Gameplay/.\nThe folder is expected to contain the textures active00, active01, active02, enter00, enter01, enter02 and idle00. +entities.canyon/spinorb.attributes.description.rotateCounterclockwise=When not set, the orb will rotate clockwise. When set, the orb will rotate counterclockwise. # Toggle Block entities.canyon/toggleblock.placements.name.ToggleBlock=Toggle Block (Canyon)