using System; using System.Collections.Generic; using System.Linq; using System.Text; using VBXSE; using WOMGeneral; namespace WorldOfMinimalism { public class SpriteWindow : Window { //Ugly hardcoded locations and stuff - I use 'Ludum Dare' as excuse private const int CHECKBOX_WIDTH = 9; private const int CHECKBOX_HEIGHT = 9; private const int CHECKBOX_SOLID_X = 131; private const int CHECKBOX_SOLID_Y = 16; private const int CHECKBOX_SOLID_NUMBER = 0; private const int BUTTON_AMOUNT = 4; private const int BUTTON_WIDTH = 47; private const int BUTTON_HEIGHT = 12; private const int BUTTON_COLOR_X = 131; private const int BUTTON_COLOR_Y = 30; private const int BUTTON_COLOR_NUMBER = 0; private const int BUTTON_COPY_X = 131; private const int BUTTON_COPY_Y = 48; private const int BUTTON_COPY_NUMBER = 1; private const int BUTTON_PASTE_X = 131; private const int BUTTON_PASTE_Y = 61; private const int BUTTON_PASTE_NUMBER = 2; private const int BUTTON_CLEAR_X = 131; private const int BUTTON_CLEAR_Y = 79; private const int BUTTON_CLEAR_NUMBER = 3; public int pixelWidth = 8; public int pixelHeight = 8; public bool[,] pixels = new bool[16, 16]; public bool solid = false; public int colorPalette = 0; public Sprite[,] pixelSprites = new Sprite[16, 16]; public List checkBoxes = new List(); public Address editingAddress = null; private int lastClickResult = -1; //Store whether last pixel change click toggled black or white for Hold private Main main = null; public SpriteWindow(Main main, Address address = null) { this.main = main; this.id = "sprite"; //Load original sprite this.editingAddress = address; if (address != null) { Tile originalTile = main.GetTile(address); this.colorPalette = originalTile.colorPalette; this.pixels = originalTile.pixels; this.solid = originalTile.solid; } //Basic setup this.x = 15; this.y = 10; this.innerX = 1; this.innerY = 15; this.frame = SpriteEngine.CreateSprite("spritewindow"); this.frame.SetPosition(x, y); this.frame.positionLocked = true; this.width = frame.GetImage().Width; this.height = frame.GetImage().Height; this.innerWidth = 16 * pixelWidth; this.innerHeight = 16 * pixelHeight; //Add pixel sprites for (int ix = 0; ix < 16; ix++) { for (int iy = 0; iy < 16; iy++) { pixelSprites[ix, iy] = SpriteEngine.CreateMultiSprite(new string[] { "pixel_black", "pixel_white", "pixel_blue", "pixel_green", "pixel_red", "pixel_yellow", "pixel_brown", "pixel_purple", "pixel_orange" }, this.x + this.innerX + ix * pixelWidth, this.y + this.innerY + iy * pixelHeight, 1f); pixelSprites[ix, iy].depth = -200; pixelSprites[ix, iy].positionLocked = true; } } UpdatePixels(); //Add checkboxes Sprite checkBox = SpriteEngine.CreateMultiSprite(new string[] { "check_off", "check_on" }, this.x + CHECKBOX_SOLID_X, this.y + CHECKBOX_SOLID_Y, 1f); checkBox.depth = -200; checkBox.positionLocked = true; checkBoxes.Add(checkBox); UpdateCheckboxes(); } public override void OnClick(int x, int y) { TogglePixel(GetTileX(x), GetTileY(y)); base.OnClick(x, y); } public override void OnHold(int x, int y) { int oldX = GetTileX(lastInnerX); int oldY = GetTileY(lastInnerY); int newX = GetTileX(x); int newY = GetTileY(y); if (oldX != newX || oldY != newY) { if (lastClickResult != -1) //Window has just been opened, no drawing has happened yet { TogglePixel(newX, newY, lastClickResult); } } base.OnHold(x, y); } public override bool OnFrameClick(int x, int y) { bool handled = false; for (int i = 0; i < checkBoxes.Count; i++) { if (!handled) { switch (i) { case CHECKBOX_SOLID_NUMBER: if (Util.InRange(x, y, CHECKBOX_SOLID_X, CHECKBOX_SOLID_Y, CHECKBOX_WIDTH, CHECKBOX_HEIGHT)) { solid = !solid; handled = true; UpdateCheckboxes(); } break; } } } if (!handled) { for (int i = 0; i < BUTTON_AMOUNT; i++) { if (!handled) { switch (i) { case BUTTON_COLOR_NUMBER: if (Util.InRange(x, y, BUTTON_COLOR_X, BUTTON_COLOR_Y, BUTTON_WIDTH, BUTTON_HEIGHT)) { colorPalette++; if (colorPalette >= Main.MAXCOLOR) colorPalette = 0; UpdatePixels(); handled = true; } break; case BUTTON_COPY_NUMBER: if (Util.InRange(x, y, BUTTON_COPY_X, BUTTON_COPY_Y, BUTTON_WIDTH, BUTTON_HEIGHT)) { main.copiedSprite = pixels; main.copiedColorPalette = colorPalette; main.copiedSolidness = solid; handled = true; } break; case BUTTON_PASTE_NUMBER: if (Util.InRange(x, y, BUTTON_PASTE_X, BUTTON_PASTE_Y, BUTTON_WIDTH, BUTTON_HEIGHT)) { if (main.copiedSprite != null) { this.pixels = (bool[,]) main.copiedSprite.Clone(); this.colorPalette = main.copiedColorPalette; this.solid = main.copiedSolidness; this.UpdateCheckboxes(); UpdatePixels(); } handled = true; } break; case BUTTON_CLEAR_NUMBER: if (Util.InRange(x, y, BUTTON_CLEAR_X, BUTTON_CLEAR_Y, BUTTON_WIDTH, BUTTON_HEIGHT)) { this.pixels = new bool[16, 16]; this.colorPalette = 0; this.solid = false; this.UpdateCheckboxes(); UpdatePixels(); handled = true; } break; } } } } return handled; } public override void OnClose() { //Commit changes Tile toModify = main.GetTile(editingAddress); toModify.colorPalette = colorPalette; toModify.SetSprite(pixels); toModify.solid = solid; main.client.ChangeTile(editingAddress, toModify.Serialize()); //Erase pixels for (int ix = 0; ix < 16; ix++) { for (int iy = 0; iy < 16; iy++) { SpriteEngine.EraseGObject(pixelSprites[ix, iy]); } } //Erase checkboxes for (int i = 0; i < checkBoxes.Count; i++) { SpriteEngine.EraseGObject(checkBoxes[i]); } checkBoxes.Clear(); base.OnClose(); } public override void Move(int diffX, int diffY) { for (int iy = 0; iy < 16; iy++) { for (int ix = 0; ix < 16; ix++) { Sprite thatSprite = pixelSprites[ix, iy]; thatSprite.SetPosition(thatSprite.position.X + diffX, thatSprite.position.Y + diffY); } } for (int i = 0; i < checkBoxes.Count; i++) { checkBoxes[i].SetPosition(checkBoxes[i].position.X + diffX, checkBoxes[i].position.Y + diffY); } base.Move(diffX, diffY); } public void TogglePixel(int tileX, int tileY, int toggleOnlyTo = -1) { //Get target color bool result = !pixels[tileX, tileY]; //Then set it internally if (toggleOnlyTo == -1) pixels[tileX, tileY] = result; else if (toggleOnlyTo == 0 && !result) pixels[tileX, tileY] = result; else if (toggleOnlyTo == 1 && result) pixels[tileX, tileY] = result; //Then adjust the sprite Sprite thatSprite = pixelSprites[tileX, tileY]; if (result) //White { if(!(toggleOnlyTo == 0)) thatSprite.currentImage = 1 + colorPalette; if (toggleOnlyTo == -1) lastClickResult = 1; } else //Black { if(!(toggleOnlyTo == 1)) thatSprite.currentImage = 0; if (toggleOnlyTo == -1) lastClickResult = 0; } } //Update the pixels - for if the palette is switched public void UpdatePixels() { for (int iy = 0; iy < 16; iy++) { for (int ix = 0; ix < 16; ix++) { if (pixels[ix, iy]) { pixelSprites[ix, iy].currentImage = 1 + colorPalette; } else { pixelSprites[ix, iy].currentImage = 0; } } } } //Verify statuses of bools and adjust checkboxes accordingly public void UpdateCheckboxes() { for (int i = 0; i < checkBoxes.Count; i++) { bool isTrue = false; switch (i) { case CHECKBOX_SOLID_NUMBER: isTrue = solid; break; } if (isTrue) checkBoxes[i].currentImage = 1; else checkBoxes[i].currentImage = 0; } } public int GetTileX(int offsetX) { return (int)Math.Floor((float)offsetX / pixelWidth); } public int GetTileY(int offsetY) { return (int)Math.Floor((float)offsetY / pixelHeight); } } }