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, }); }