예제 #1
0
        public MoveSwapBlock(EntityData data, Vector2 offset)
            : base(data.Position + offset, data.Width, data.Height, data.Nodes[0] + offset, Themes.Normal)
        {
            swapBlockData = new DynData <SwapBlock>(this);
            Theme         = Themes.Moon; // base() gets Normal for the block texture, then we set to Moon to remove the path background

            doesReturn   = data.Bool("returns", true);
            freezeOnSwap = data.Bool("freezeOnSwap", true);

            // Replaces SwapBlock.OnDash with MoveSwapBlock.OnDash if this block doesn't return
            DashListener     listener    = Get <DashListener>();
            Action <Vector2> orig_OnDash = listener.OnDash;

            listener.OnDash = (dir) => {
                if (State == MovementState.Breaking)
                {
                    return;
                }
                else if (doesReturn)
                {
                    orig_OnDash(dir);
                }
                else
                {
                    OnDash(dir);
                }
            };

            // We use some local variable to temporarily store private SwapBlock fields for less reflection
            start      = Position;
            end        = data.Nodes[0] + offset;
            difference = end - start;

            // Structs are value types
            startingRect = swapBlockData.Get <Rectangle>("moveRect");

            swapBlockData["maxForwardSpeed"] = maxForwardSpeed = 360f * data.Float("swapSpeedMultiplier", 1f) / Vector2.Distance(start, end);
            startPosition = Position;

            // Replace/Add SwapBlock textures
            middleCardinal  = GFX.Game["objects/CommunalHelper/moveSwapBlock/midBlockCardinal"];
            middleDiagonal  = GFX.Game["objects/CommunalHelper/moveSwapBlock/midBlockDiagonal"];
            Add(middleArrow = new Image(middleCardinal));
            middleArrow.CenterOrigin();

            Remove(swapBlockData.Get <Sprite>("middleGreen"), swapBlockData.Get <Sprite>("middleRed"));
            swapBlockData["middleGreen"] = middleGreen = CommunalHelperModule.SpriteBank.Create("swapBlockLight");
            swapBlockData["middleRed"]   = middleRed = CommunalHelperModule.SpriteBank.Create("swapBlockLightRed");
            Add(middleGreen, middleRed);

            Add(middleOrange = new Image(GFX.Game["objects/CommunalHelper/moveSwapBlock/midBlockOrange"]));
            middleOrange.CenterOrigin();

            canSteer         = data.Bool("canSteer", false);
            maxMoveSpeed     = data.Float("moveSpeed", 60f);
            moveAcceleration = data.Float("moveAcceleration", Accel);
            MoveDirection    = data.Enum("direction", Directions.Left);
            homeAngle        = targetAngle = angle = MoveDirection.Angle();
            angleSteerSign   = angle > 0f ? -1 : 1;

            int      tilesX               = (int)Width / 8;
            int      tilesY               = (int)Height / 8;
            MTexture buttonTexture        = GFX.Game["objects/moveBlock/button"];
            MTexture buttonPressedTexture = GFX.Game["objects/CommunalHelper/moveSwapBlock/buttonPressed"];

            if (canSteer && (MoveDirection == Directions.Left || MoveDirection == Directions.Right))
            {
                for (int x = 0; x < tilesX; x++)
                {
                    int offsetX = (x != 0) ? ((x < tilesX - 1) ? 1 : 2) : 0;
                    AddImage(buttonTexture.GetSubtexture(offsetX * 8, 0, 8, 8), new Vector2(x * 8, -4f), 0f, new Vector2(1f, 1f), topButton);
                    AddImage(buttonPressedTexture.GetSubtexture(offsetX * 8, 0, 8, 8), new Vector2(x * 8, -4f), 0f, new Vector2(1f, 1f), topButton);
                }
            }
            else if (canSteer && (MoveDirection == Directions.Up || MoveDirection == Directions.Down))
            {
                for (int y = 0; y < tilesY; y++)
                {
                    int offsetY = (y != 0) ? ((y < tilesY - 1) ? 1 : 2) : 0;
                    AddImage(buttonTexture.GetSubtexture(offsetY * 8, 0, 8, 8), new Vector2(-4f, y * 8), (float)Math.PI / 2f, new Vector2(1f, -1f), leftButton);
                    AddImage(buttonPressedTexture.GetSubtexture(offsetY * 8, 0, 8, 8), new Vector2(-4f, y * 8), (float)Math.PI / 2f, new Vector2(1f, -1f), leftButton);
                    AddImage(buttonTexture.GetSubtexture(offsetY * 8, 0, 8, 8), new Vector2((tilesX - 1) * 8 + 4, y * 8), (float)Math.PI / 2f, new Vector2(1f, 1f), rightButton);
                    AddImage(buttonPressedTexture.GetSubtexture(offsetY * 8, 0, 8, 8), new Vector2((tilesX - 1) * 8 + 4, y * 8), (float)Math.PI / 2f, new Vector2(1f, 1f), rightButton);
                }
            }
            UpdateColors();

            debrisTextures = new Chooser <MTexture>();
            foreach (MTexture debris in GFX.Game.GetAtlasSubtextures("objects/CommunalHelper/moveSwapBlock/debris"))
            {
                debrisTextures.Add(debris, 1);
            }
            debrisTextures.Add(GFX.Game["objects/CommunalHelper/moveSwapBlock/debrisRed00"], 0.3f);
            debrisTextures.Add(GFX.Game["objects/CommunalHelper/moveSwapBlock/debrisGreen00"], 0.05f);

            Add(moveBlockSfx = new SoundSource());
            Add(new Coroutine(Controller()));

            Add(new MoveBlockRedirectable(new DynamicData(this))
            {
                Get_Speed       = () => moveSpeed,
                Get_TargetSpeed = () => targetMoveSpeed,
                Get_MoveSfx     = () => moveBlockSfx,
                Get_Direction   = () => MoveDirection,
                Set_Direction   = dir => MoveDirection = dir,
            });
        }