Graal Pastebin
New PastePasted on September 11, 2012.
View the raw file
/**************************************************************\ #Title Pixel Perfect Tile Editor #Version 1.2 #Features - Relatively easy setup with simple configuration - Works with graal file browser rights system - Scrolls automatically when selecting large portions of the gui - Open, save, and delete tile clipboard files - Undo & redo (Note: history is cleared when the editor closes) - [Toggle] Fade inactive tilelayers - [Toggle] Level grid to separate tiles - [Toggle] Extra cursor info - [Toggle] External window - Create new levels - Flood fill - Automatically checks if there is an update available when the script is initialized - More #Installation 1. Create a new weapon script named -Development/TileEditor or whatever whatever is pleasing to you 2. Copy the entire text of this document into the script 3. Modify the configuration portion of the script to suit your server best 4. Give (npcserver) the required rights By default, this includes: rw access to TileEditor/Clipboard/ and subfolders, rw access to TileEditor/Data/ and subfolders, rw access to a levels folder (to create new levels), rw access to levels/images/tileeditor_icon_1-1.png , rw access to levels/images/tileeditor_bucket_1-1.png , rw access to levels/images/tileeditor_pencil_1-1.png 5. Give level designers necessary rights r and/or w access to TileEditor/Clipboard/ and/or subfolders, rw access to level files to use this program on 6. Add the weapon script to the level designers #Script Interface - The following clientside public functions are available: open() - triggers the request to open the editor close() - triggers the program to close isOpen() - returns true if the program is open #Directions Type /te into the chat bar to open the program Left click to select tiles, right click to paste the selection #Credits Scripted by Pixel \**************************************************************/ /*********************** Configuration ************************/ // Check for updates when the weapon script is initialized? // (recommended to know when future updates are released) const TE_CHECK_UPDATE = true; // Must the user be in the serveroptions staff list? // Set the value to true if you want to restrict the use of the // program to only staff. Otherwise set the value to false. const TE_ONLYSTAFF = true; // Must the user have rights to levels and files? // Set the value to true if you want to secure levels and files // using the default graal rights system (Strongly recommended). // Otherwise set the value to false const TE_NEEDRIGHTS = true; // Where should the clipboard files be stored? // (recommended to keep this as "TileEditor/Clipboard/") const TE_DIR_CLIPBOARD = "TileEditor/Clipboard/"; // Where should the program keep it's data files? // (recommended to keep this as "TileEditor/Data/") const TE_DIR_DATAFILES = "TileEditor/Data/"; // Should the program save images and icons to the server? // (recommended to keep this as true usually) const TE_WRITE_IMAGES = true; // Where should the program save it's images and icons? // This can vary depending on your server's folder options const TE_DIR_IMAGES = "levels/images/"; /**************************************************************/ /******************* Don't Touch Below Here *******************/ const TE_VERSION = "1.2.0"; const TE_ICON_DATA = "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAB3RJTUUH3AYDFREoSFzGywAAABd0RVh0U29mdHdhcmUAR0xEUE5HIHZlciAzLjRxhaThAAAACHRwTkdHTEQzAAAAAEqAKR8AAAAEZ0FNQQAAsY8L/GEFAAADAFBMVEUAAACAAAAAgACAgADAwMCAAIAAgIAAAIDA3MCmyvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+/CgoKSAgID/AAAA/wD//wAAAP//AP8A//////+6YMT6AAAAAWJLR0T/pQfyxQAAAHBJREFUeJxljjEOgDAMA93AENGJ/z8SMQVaJMghsdCTslh2bE29T0fEYa1ZuId6EklLPBmFf8TmUuZ7Xe+SLPu+6EqwEj2TQbAq1U3aXHJO76N8yGMKhJ1KqomNwj9idLOBLWwSVViJMmEQ7OtnC5sexROSefnyghYAAAAASUVORK5CYII="; const TE_BUCKET_DATA = "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAALISURBVDiNjZNLTFRnFMd/3537fXfuTUZa7IiBMDFprInxURIJ7Uqxm8b4SMowjPiANrG8FHXZaGVRVColJiAkoqs2jQbpgoUFN+7wEcXuuqNJIeMAGkoodx7eufdzYcYQY7UnOavzO/9z8j85QmvNuyKRjFcAvUAtkAXuAOdGbo4+AzDe2f0qLgEZYCewF/gA6C4Wzf8h0AhUSSmv+r4/HgRBG/AcaHnvBolkfA1AyZqS+x3tJ3batt0F2ECoyLxVIJGMGw0H648ppWYArgwMhbdu2SpajrWGpVRDq1nzYMe1DVKZwwXP3wUEgfePDjsfqprqKvF1U7No/uYoqVSK5eVltm3bbsRilV9OT0+/FjCUkn2bNm344vPaHdI2/rIqSubDvRe7jfbWNjEz8zdCGPT8eIH0XJpUKkXn8ZNhwEsk4yaA8eKFd6C6Zotxb2xI7/5ss+45fxHbtvF9n77LP7Hx441UVsYYn7iN67qEwzb79u4PQqFQZ9GDkGUptP2JfvLHVE5rzeLiIq7rYlkWpjSJRCKEQiZSSmZnZ6n7Km45jvNDIhkve22iMEtEOj039vjxIz8SieC6Lp0nTrHirjC/ME/TkSaUUhQHtHzbFlZKDa6+gij4nB6+fjXnOA6e5xH9KMqlnl7OfHeW8vIKlFJIKcnn81R9WmUEQbDHEEIUVv7NAPgjN27M5XK5c6O/3cqXlpbiui75fB6lFEopLMsiFotRVraOwaGBnBBizJDSHPn1l9u+Kc1RgCAI+icmxucy2QxCCDKZDFJKHMchGo0y9WTKb+toXXnw8MFpz/MOobUm2T5crrWmmPUNdbu/7zqTyWazemFhQfu+r5+mn+rOU8ezR5oO/VzfULe2yLK6cXU2Hk7+PnlvMlhaWtJXBvtzR5sP/1nfUFf9Jif+650Tyfh6acq7CEoLhUKX1vrayM3R4E3uJf0eQEfPmPQuAAAAAElFTkSuQmCC"; const TE_PENCIL_DATA = "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"; enum RPL { NONE, ERROR, REQUESTUSE, PLACETILES, LISTCLIPBOARDFOLDER, LOADCLIPBOARDFILE, SAVECLIPBOARDFILE, DELETECLIPBOARDFILE, CREATENEWLEVEL } /** * events */ function onCreated() { if (TE_CHECK_UPDATE) { temp.req = requesturl("http://forums.graalonline.com/forums/showthread.php?t=134267103"); waitfor(temp.req, "onReceiveData", 10); temp.position = temp.req.fulldata.pos("[VERSION]") + 9; temp.currentVersionString = temp.req.fulldata.substring(temp.position, temp.req.fulldata.pos("[/VERSION]") - position); if (TE_VERSION != temp.currentVersionString) TE_echo("A new version is available: " @ temp.currentVersionString); } if (!TE_WRITE_IMAGES) return; temp.filePath = TE_DIR_IMAGES @ "tileeditor_icon_1-1.png"; temp.files.loadfolder(temp.filePath, 0); if (temp.files.size() == 0) { temp.data = base64decode(TE_ICON_DATA); temp.data.savestring(temp.filePath, 0); temp.files = NULL; temp.files.loadfolder(temp.filePath, 0); if (temp.files.size() == 0) { TE_echo("prob: (npcserver) cannot write the icon image file as" SPC temp.filePath @ ". Ensure that both the configuration and the (npcserver)'s rights are correct"); } else { TE_echo("icon image saved to" SPC temp.filePath); } } temp.filePath = TE_DIR_IMAGES @ "tileeditor_bucket_1-1.png"; temp.files.loadfolder(temp.filePath, 0); if (temp.files.size() == 0) { temp.data = base64decode(TE_BUCKET_DATA); temp.data.savestring(temp.filePath, 0); temp.files = NULL; temp.files.loadfolder(temp.filePath, 0); if (temp.files.size() == 0) { TE_echo("prob: (npcserver) cannot write the bucket image file as" SPC temp.filePath @ ". Ensure that both the configuration and the (npcserver)'s rights are correct"); } else { TE_echo("bucket image saved to" SPC temp.filePath); } } temp.filePath = TE_DIR_IMAGES @ "tileeditor_pencil_1-1.png"; temp.files.loadfolder(temp.filePath, 0); if (temp.files.size() == 0) { temp.data = base64decode(TE_PENCIL_DATA); temp.data.savestring(temp.filePath, 0); temp.files = NULL; temp.files.loadfolder(temp.filePath, 0); if (temp.files.size() == 0) { TE_echo("prob: (npcserver) cannot write the pencil image file as" SPC temp.filePath @ ". Ensure that both the configuration and the (npcserver)'s rights are correct"); } else { TE_echo("pencil image saved to" SPC temp.filePath); } } } function onActionServerSide() { if (TE_ONLYSTAFF) { temp.staffList = serveroptions.staff.lower().tokenize(","); if (!(player.account.lower() in temp.staffList) && (player.communityname == "" || !(player.communityname.lower() in temp.staffList))) { TE_echo(format("%s tried to use the tile editor, but is not staff", player.account)); return; } } switch (params[0]) { case RPL.REQUESTUSE: { if (TE_NEEDRIGHTS && !player.hasright("w", player.level.name)) temp.allowUse = false; else temp.allowUse = true; player.triggerclient("gui", this.name, RPL.REQUESTUSE, temp.allowUse, TE_VERSION); break; } case RPL.PLACETILES: { if (TE_NEEDRIGHTS && !player.hasright("w", player.level.name)) { player.triggerclient("gui", this.name, RPL.ERROR, "You do not have rights to edit" SPC player.level.name); break; } if (params[1].size() == 0) break; temp.data = params; maxlooplimit = 100000; for (temp.y = 0; temp.y < temp.data[1].size(); temp.y++) { if (temp.data[4] == 0 && temp.data[1][temp.y].index(-1) != -1) { do { temp.ind = temp.data[1][temp.y].index(-1); temp.data[1][temp.y][temp.ind] = 0; } while (temp.data[1][temp.y].index(-1) != -1); } for (temp.x = 0; temp.x < temp.data[1][0].size(); temp.x++) { temp.tile = temp.data[1][temp.y][temp.x]; if (temp.tile == -2) continue; tilelayers[temp.data[4]].tiles[temp.x + temp.data[2], temp.y + temp.data[3]] = temp.tile; } } tilelayers[temp.data[4]].updateboard2(temp.data[2], temp.data[3], temp.data[1][0].size(), temp.data[1].size()); break; } case RPL.LOADCLIPBOARDFILE: { if (!fileexists(TE_DIR_CLIPBOARD @ params[1])) break; temp.obj = {}; temp.obj.loadlines(TE_DIR_CLIPBOARD @ params[1]); if (temp.obj.size() == 0) { player.triggerclient("gui", this.name, RPL.ERROR, "The (npcserver) lacks the rights to read the file"); return; } player.triggerclient("gui", this.name, RPL.LOADCLIPBOARDFILE, temp.obj, params[1], getfilemodtime(TE_DIR_CLIPBOARD @ params[1])); break; } case RPL.SAVECLIPBOARDFILE: { temp.fileBase = extractfilebase(params[2]); if (temp.fileBase == "") break; temp.filePath = TE_DIR_CLIPBOARD @ extractfilepath(params[2]); temp.filePath = temp.filePath @ temp.fileBase @ ".txt"; if (TE_NEEDRIGHTS && !player.hasright("w", temp.filePath)) { player.triggerclient("gui", this.name, RPL.ERROR, "You do not have rights for" SPC temp.filePath); return; } params[1].savelines(temp.filePath, 0); temp.files.loadfolder(temp.filePath, 0); if (temp.files.size() == 0) { player.triggerclient("gui", this.name, RPL.ERROR, "The (npcserver) lacks the rights to create the file"); return; } player.triggerclient("gui", this.name, RPL.SAVECLIPBOARDFILE, temp.filePath); break; } case RPL.DELETECLIPBOARDFILE: { temp.filePath = TE_DIR_CLIPBOARD @ params[1]; if (TE_NEEDRIGHTS && !player.hasright("w", temp.filePath)) { player.triggerclient("gui", this.name, RPL.ERROR, "You do not have rights for" SPC temp.filePath); return; } if (!fileexists(temp.filePath)) { player.triggerclient("gui", this.name, RPL.ERROR, temp.filePath SPC "does not exist"); return; } deletefile(temp.filePath); temp.files.loadfolder(temp.filePath, 0); if (temp.files.size() == 1) player.triggerclient("gui", this.name, RPL.ERROR, "The (npcserver) lacks the rights to delete the file"); } case RPL.LISTCLIPBOARDFOLDER: { temp.obj = {}; temp.obj.loadfolder(TE_DIR_CLIPBOARD @ "*", 1); if (TE_NEEDRIGHTS) { temp.list = {}; for (temp.o: temp.obj) { temp.filePath = TE_DIR_CLIPBOARD @ temp.o; if (player.hasright("r", temp.filePath)) temp.list.add(temp.o); } } else { temp.list = temp.obj; } player.triggerclient("gui", this.name, RPL.LISTCLIPBOARDFOLDER, temp.list); break; } case RPL.CREATENEWLEVEL: { temp.fileBase = extractfileBase(params[1]).lower(); temp.fileExt = extractfileext(params[1]).lower(); if (temp.fileBase == "" || temp.fileExt != ".nw") { player.triggerclient("gui", this.name, RPL.ERROR, "Invalid file name"); return; } temp.filePath = extractfilepath(params[1]).lower() @ temp.fileBase @ temp.fileExt; if (TE_NEEDRIGHTS && !player.hasright("w", temp.filePath)) { player.triggerclient("gui", this.name, RPL.ERROR, "You do not have rights for" SPC temp.filePath); return; } if (fileexists(temp.filePath) && !params[2]) { player.triggerclient("gui", this.name, RPL.ERROR, "That file already exists! Type the same thing in again to overwrite"); return; } temp.lines = { "GLEVNW01" }; temp.lines.savelines(temp.filePath, 0); temp.files.loadfolder(temp.filePath, 0); if (temp.files.size() == 0) { player.triggerclient("gui", this.name, RPL.ERROR, "The (npcserver) lacks the rights to create the file"); return; } player.triggerclient("gui", this.name, RPL.CREATENEWLEVEL, temp.filePath); break; } } } /** * functions */ function TE_echo(temp.text) { echo(this.name @ ":" SPC temp.text); } //#CLIENTSIDE enum RPL { NONE, ERROR, REQUESTUSE, PLACETILES, LISTCLIPBOARDFOLDER, LOADCLIPBOARDFILE, SAVECLIPBOARDFILE, DELETECLIPBOARDFILE, CREATENEWLEVEL } enum PASTEMODE { NONE, NORMAL, FILL } /** * events */ function onCreated() { if (GuiWindow_TileEditor.grid) updateGridEffect(); } function onPlayerEnters() { if (GuiWindow_TileEditor != NULL && GuiWindow_TileEditor.editingLevel != (isonmap ? player.gmap.name : player.level.name)) { onCloseEditor(); } } function onActionClientSide() { switch (params[0]) { case RPL.LISTCLIPBOARDFOLDER: { if (GuiWindow_TileEditor_FileOpen != NULL) { GuiTreeView_TileEditor_FileOpen.clearnodes(); for (temp.fileName: params[1]) { temp.fileExt = extractfileext(temp.fileName); if (temp.fileExt != ".txt" && temp.fileExt != "") continue; with (GuiTreeView_TileEditor_FileOpen.addnodebypath(temp.fileName, "/")) { image = selectedimage = temp.fileExt == "" ? 1 : 2; } } } if (GuiWindow_TileEditor_FileSave != NULL) { GuiTreeView_TileEditor_FileSave.clearnodes(); for (temp.fileName: params[1]) { temp.fileExt = extractfileext(temp.fileName); if (temp.fileExt != ".txt" && temp.fileExt != "") continue; with (GuiTreeView_TileEditor_FileSave.addnodebypath(temp.fileName, "/")) { image = selectedimage = temp.fileExt == "" ? 1 : 2; } } } break; } case RPL.LOADCLIPBOARDFILE: { temp.lines = {}; for (temp.line: params[1]) temp.lines.add(temp.line.tokenize()); temp.extent = { temp.lines[0].size(), temp.lines.size() }; if (GuiWindow_TileEditor_FileOpen != NULL) { GuiText_TileEditor_FileOpen_Title_Value.text = params[2]; GuiText_TileEditor_FileOpen_Extent_Value.text = temp.extent[0] @ "," SPC temp.extent[1]; GuiText_TileEditor_FileOpen_Created_Value.text = converttimetostring(params[3]); GuiStretch_TileEditor_FileOpen.clientwidth = GuiDrawingPanel_TileEditor_FileOpen_Preview.width = temp.extent[0] * 16; GuiStretch_TileEditor_FileOpen.clientheight = GuiDrawingPanel_TileEditor_FileOpen_Preview.height = temp.extent[1] * 16; GuiDrawingPanel_TileEditor_FileOpen_Preview.clearall(); for (temp.i = 0; temp.i < temp.extent[0]; temp.i++) { for (temp.j = 0; temp.j < temp.extent[1]; temp.j++) { temp.tileXY = getTileXY(temp.lines[temp.j][temp.i]); GuiDrawingPanel_TileEditor_FileOpen_Preview.drawimagerectangle( temp.i * 16, temp.j * 16, GuiWindow_TileEditor.tilesetImage, temp.tileXY[0], temp.tileXY[1], 16, 16 ); } GuiWindow_TileEditor_FileOpen.clipboard = temp.lines; } } if (GuiWindow_TileEditor_FileSave != NULL) { GuiText_TileEditor_FileSave_Title_Value.text = params[2]; GuiText_TileEditor_FileSave_Extent_Value.text = temp.extent[0] @ "," SPC temp.extent[1]; GuiText_TileEditor_FileSave_Created_Value.text = converttimetostring(params[3]); GuiStretch_TileEditor_FileSave.clientwidth = GuiDrawingPanel_TileEditor_FileSave_Preview.width = temp.extent[0] * 16; GuiStretch_TileEditor_FileSave.clientheight = GuiDrawingPanel_TileEditor_FileSave_Preview.height = temp.extent[1] * 16; GuiDrawingPanel_TileEditor_FileSave_Preview.clearall(); for (temp.i = 0; temp.i < temp.extent[0]; temp.i++) { for (temp.j = 0; temp.j < temp.extent[1]; temp.j++) { temp.tileXY = getTileXY(temp.lines[temp.j][temp.i]); GuiDrawingPanel_TileEditor_FileSave_Preview.drawimagerectangle( temp.i * 16, temp.j * 16, GuiWindow_TileEditor.tilesetImage, temp.tileXY[0], temp.tileXY[1], 16, 16 ); } } } break; } case RPL.SAVECLIPBOARDFILE: { shared.adminmessage(params[1] SPC "is saved"); break; } case RPL.ERROR: { if (params[1] != NULL) shared.adminmessage(params[1]); else shared.adminmessage("An unexpected error occurred"); break; } case RPL.CREATENEWLEVEL: { shared.adminmessage(params[1] SPC "is saved"); GuiWindow_TileEditor.newLevelOverwrite = NULL; break; } } } function ChatBar.onAction() { if (ChatBar.text.lower().trim() == "/te") onRequestUse(); } function GuiWindow_TileEditor.onResize(temp.newWidth, temp.newHeight) { if (GuiWindow_TileEditor.isexternal) { GuiMenu_TileEditor.x = 0; GuiMenu_TileEditor.y = 0; GuiMenu_TileEditor.width = temp.newWidth; GuiScroll_TileEditor.x = 0; GuiScroll_TileEditor.y = 20; GuiScroll_TileEditor.width = temp.newWidth; GuiScroll_TileEditor.height = temp.newHeight - 20; } else { GuiMenu_TileEditor.width = temp.newWidth - 12; GuiScroll_TileEditor.width = temp.newWidth - 12; GuiScroll_TileEditor.height = temp.newHeight - 50; } } function GuiWindow_TileEditor.onCloseQuery() { onCloseEditor(); } function GuiMenu_TileEditor.onSelect(temp.menuName, temp.entryId, temp.entryText, temp.entryIndex) { temp.menu = GuiMenu_TileEditor.findmenu(temp.menuName); switch (temp.menuName) { case "File": { switch (temp.entryId) { case 0: { with (GuiWindow_TileEditor) { new GuiTextEditCtrl("GuiTextEdit_TileEditor_NewLevel") { profile = GuiBlueTextEditProfile; x = GuiWindow_TileEditor.wasExternal ? 0 : 6; y = GuiWindow_TileEditor.wasExternal ? 20 : 44; width = GuiWindow_TileEditor.width - x * 2; height = 20; text = "levels/new.nw"; makefirstresponder(true); setselection(0, text.length()); } } break; } case 1: { showFileOpenGui(); break; } case 2: { showFileSaveGui(); break; } case 3: { onCloseEditor(); break; } } break; } case "Edit": { switch (temp.entryId) { case 0: { editorUndo(); break; } case 1: { editorRedo(); break; } } break; } case "View": { switch (temp.entryId) { case 0: { GuiWindow_TileEditor.fadeLayers = !GuiWindow_TileEditor.fadeLayers; if (GuiWindow_TileEditor.fadeLayers) temp.menu.setrowbyid(0, "*Fade inactive layers"); else temp.menu.setrowbyid(0, "Fade inactive layers"); updateFadeEffect(); break; } case 1: { GuiWindow_TileEditor.grid = !GuiWindow_TileEditor.grid; if (GuiWindow_TileEditor.grid) temp.menu.setrowbyid(1, "*Grid"); else temp.menu.setrowbyid(1, "Grid"); updateGridEffect(); break; } case 2: { GuiWindow_TileEditor.extraCursorInfo = !GuiWindow_TileEditor.extraCursorInfo; if (GuiWindow_TileEditor.extraCursorInfo) { temp.menu.setrowbyid(2, "*Extra cursor info"); } else { hideimgs(200, 204); temp.menu.setrowbyid(2, "Extra cursor info"); } break; } } break; } case "Tileset": { switch (temp.entryId) { case 0: { with (GuiWindow_TileEditor) { new GuiTextEditCtrl("GuiTextEdit_TileEditor_Tileset") { profile = GuiBlueTextEditProfile; x = GuiWindow_TileEditor.wasExternal ? 0 : 6; y = GuiWindow_TileEditor.wasExternal ? 20 : 44; width = GuiWindow_TileEditor.width - x * 2; height = 20; text = "pics1.png"; makefirstresponder(true); setselection(0, text.length()); } } break; } case 1: { with (GuiDrawingPanel_TileEditor) { clearall(); GuiWindow_TileEditor.tilesetImage = "TILES"; drawimage(0, 0, GuiWindow_TileEditor.tilesetImage); } break; } } break; } case "Layer": { temp.menu.setrowbyid(GuiWindow_TileEditor.editingLayer, GuiWindow_TileEditor.editingLayer + 1); temp.menu.setrowbyid(temp.entryId, "*" @ (temp.entryId + 1)); GuiWindow_TileEditor.editingLayer = temp.entryId; GuiWindow_TileEditor.text = " Tile Editor v" @ GuiWindow_TileEditor.version SPC "(Layer" SPC GuiWindow_TileEditor.editingLayer + 1 @ ")"; updateFadeEffect(); break; } case "Options": { switch (temp.entryId) { case 0: { GuiWindow_TileEditor.isexternal = !GuiWindow_TileEditor.isexternal; GuiWindow_TileEditor.wasExternal = true; if (GuiWindow_TileEditor.isexternal) temp.menu.setrowbyid(0, "*External"); else temp.menu.setrowbyid(0, "External"); GuiWindow_TileEditor.trigger("onResize", GuiWindow_TileEditor.width, GuiWindow_TileEditor.height); break; } case 1: { openurl("http://forums.graalonline.com/forums/showthread.php?t=134267103"); break; } } break; } } } function GuiButton_TileEditor_PasteMode.onAction() { if (GuiWindow_TileEditor.pasteMode == PASTEMODE.NORMAL) { GuiWindow_TileEditor.pasteMode = PASTEMODE.FILL; GuiShowImg_TileEditor_PasteMode.image = "tileeditor_pencil_1-1.png"; } elseif (GuiWindow_TileEditor.pasteMode == PASTEMODE.FILL) { GuiWindow_TileEditor.pasteMode = PASTEMODE.NORMAL; GuiShowImg_TileEditor_PasteMode.image = "tileeditor_bucket_1-1.png"; } } function GuiWindow_TileEditor.onHide() { if (GuiWindow_TileEditor.isexternal && !GuiWindow_TileEditor.visible) onCloseEditor(); } function GuiTextEdit_TileEditor_NewLevel.onAction() { temp.text = GuiTextEdit_TileEditor_NewLevel.text; triggerserver("gui", this.name, RPL.CREATENEWLEVEL, temp.text, (temp.text.lower() == GuiWindow_TileEditor.newLevelOverwrite)); GuiWindow_TileEditor.newLevelOverwrite = temp.text.lower(); GuiTextEdit_TileEditor_NewLevel.destroy(); } function GuiTextEdit_TileEditor_Tileset.onAction() { with (GuiDrawingPanel_TileEditor) { clearall(); drawimage(0, 0, GuiTextEdit_TileEditor_Tileset.text); } GuiWindow_TileEditor.tilesetImage = GuiTextEdit_TileEditor_Tileset.text; GuiTextEdit_TileEditor_Tileset.destroy(); } function GuiDrawingPanel_TileEditor.onMouseDown(temp.keyMod, temp.xMouse, temp.yMouse, temp.clickCount) { GuiDrawingPanel_TileEditor.mouseWasDown = true; GuiDrawingPanel_TileEditor.mouselock(0); temp.coords = GuiDrawingPanel_TileEditor.globaltolocalcoord({temp.xMouse, temp.yMouse}); GuiWindow_TileEditor.tileSelectStart = GuiWindow_TileEditor.tileSelectEnd = {temp.coords[0] - temp.coords[0] % 16, temp.coords[1] - temp.coords[1] % 16}; drawGuiSelect(); } function GuiDrawingPanel_TileEditor.onMouseUp(temp.keyMod, temp.xMouse, temp.yMouse, temp.clickCount) { if (!GuiDrawingPanel_TileEditor.mouseWasDown) return; GuiDrawingPanel_TileEditor.mouseWasDown = false; if (Gui_TileEditor_Select != NULL) Gui_TileEditor_Select.destroy(); setClipboardFromGui(); GraalControl.makefirstresponder(true); } function GuiDrawingPanel_TileEditor.onMouseDragged(temp.keyMod, temp.xMouse, temp.yMouse, temp.clickCount) { temp.coords = GuiDrawingPanel_TileEditor.globaltolocalcoord({temp.xMouse, temp.yMouse}); temp.scrollcoords = GuiWindow_TileEditor.globaltolocalcoord({temp.xMouse, temp.yMouse}); if (temp.scrollcoords[0] < GuiScroll_TileEditor.x + 32) temp.scrollx = temp.scrollcoords[0] - GuiScroll_TileEditor.x - 32; elseif (temp.scrollcoords[0] > GuiScroll_TileEditor.x + GuiScroll_TileEditor.width - 64) temp.scrollx = temp.scrollcoords[0] - GuiScroll_TileEditor.x - GuiScroll_TileEditor.width + 64; if (temp.scrollcoords[1] < GuiScroll_TileEditor.y + 32) temp.scrolly = temp.scrollcoords[1] - GuiScroll_TileEditor.y - 32; elseif (temp.scrollcoords[1] > GuiScroll_TileEditor.y + GuiScroll_TileEditor.height - 64) temp.scrolly = temp.scrollcoords[1] - GuiScroll_TileEditor.y - GuiScroll_TileEditor.height + 64; if (temp.scrollx != NULL || temp.scrolly != NULL) GuiScroll_TileEditor.scrolldelta(int(temp.scrollx / 8.0), int(temp.scrolly / 8.0)); GuiWindow_TileEditor.tileSelectEnd = {temp.coords[0] - temp.coords[0] % 16, temp.coords[1] - temp.coords[1] % 16}; drawGuiSelect(); } function GuiTreeView_TileEditor_FileOpen.onSelect(temp.node, temp.nodeSlashPath, temp.nodeDotPath) { if (!temp.node.ends(".txt")) return; triggerserver("gui", this.name, RPL.LOADCLIPBOARDFILE, temp.nodeSlashPath); GuiTreeView_TileEditor_FileOpen.selectedSlashPath = temp.nodeSlashPath; } function GuiButton_TileEditor_FileOpen_Delete.onAction() { temp.filePath = GuiTreeView_TileEditor_FileOpen.selectedSlashPath; if (temp.filePath != NULL) triggerserver("gui", this.name, RPL.DELETECLIPBOARDFILE, temp.filePath); } function GuiButton_TileEditor_FileOpen_Open.onAction() { if (GuiWindow_TileEditor_FileOpen.clipboard == NULL) return; GuiWindow_TileEditor.clipboard = GuiWindow_TileEditor_FileOpen.clipboard; drawClipboardPreview(); GuiWindow_TileEditor_FileOpen.destroy(); } function GuiButton_TileEditor_FileOpen_Cancel.onAction() { GuiWindow_TileEditor_FileOpen.destroy(); } function GuiTreeView_TileEditor_FileSave.onSelect(temp.node, temp.nodeSlashPath, temp.nodeDotPath) { if (!temp.node.ends(".txt")) return; triggerserver("gui", this.name, RPL.LOADCLIPBOARDFILE, temp.nodeSlashPath); GuiTextEdit_TileEditor_FileSave_FilePath.text = temp.nodeSlashPath; } function GuiButton_TileEditor_FileSave_Delete.onAction() { temp.filePath = GuiTextEdit_TileEditor_FileSave_FilePath.text; if (temp.filePath != NULL) triggerserver("gui", this.name, RPL.DELETECLIPBOARDFILE, temp.filePath); } function GuiButton_TileEditor_FileSave_Save.onAction() { temp.filePath = GuiTextEdit_TileEditor_FileSave_FilePath.text; if (temp.filePath.length() == 0) return; triggerserver("gui", this.name, RPL.SAVECLIPBOARDFILE, GuiWindow_TileEditor.clipboard, temp.filePath); GuiWindow_TileEditor_FileSave.destroy(); } function GuiButton_TileEditor_FileSave_Cancel.onAction() { GuiWindow_TileEditor_FileSave.destroy(); } function GraalControl.onMouseDown(temp.keyMod, temp.xMouse, temp.yMouse, temp.clickCount) { if (GuiShowImg_TileEditor_ClipboardPreview != NULL) GuiShowImg_TileEditor_ClipboardPreview.destroy(); if (GuiWindow_TileEditor == NULL) return; GuiWindow_TileEditor.tileSelectStart = GuiWindow_TileEditor.tileSelectEnd = {int(mousex), int(mousey)}; drawSelect(); if (!GuiWindow_TileEditor.isexternal) GuiWindow_TileEditor.visible = false; } function GraalControl.onRightMouseDown(temp.keyMod, temp.xMouse, temp.yMouse, temp.clickCount) { if (GuiWindow_TileEditor == NULL || GuiShowImg_TileEditor_ClipboardPreview == NULL || GuiWindow_TileEditor.clipboard == NULL) return; GuiShowImg_TileEditor_ClipboardPreview.blue = 1.0; GuiDrawingPanel_TileEditor_ClipboardPreview.flickering = false; temp.mx = int(mousex); temp.my = int(mousey); if (GuiWindow_TileEditor.pasteMode == PASTEMODE.NORMAL) { temp.historyObject = { temp.mx, temp.my, GuiWindow_TileEditor.editingLayer, NULL, GuiWindow_TileEditor.clipboard }; for (temp.y = 0; temp.y < GuiWindow_TileEditor.clipboard.size(); temp.y++) { temp.row = {}; for (temp.x = 0; temp.x < GuiWindow_TileEditor.clipboard[0].size(); temp.x++) { if (GuiWindow_TileEditor.editingLayer == 0) temp.tile = tiles[temp.x + temp.mx, temp.y + temp.my]; else temp.tile = tilelayers[GuiWindow_TileEditor.editingLayer].tiles[temp.x + temp.mx, temp.y + temp.my]; temp.row.add(temp.tile); } temp.historyObject[3].add(temp.row); } if (GuiWindow_TileEditor.history == NULL) GuiWindow_TileEditor.history = {}; GuiWindow_TileEditor.history = GuiWindow_TileEditor.history.subarray(GuiWindow_TileEditor.historyIndex); GuiWindow_TileEditor.historyIndex = 0; GuiWindow_TileEditor.history.insert(0, temp.historyObject); triggerserver("gui", this.name, RPL.PLACETILES, GuiWindow_TileEditor.clipboard, temp.mx, temp.my, GuiWindow_TileEditor.editingLayer); } elseif (GuiWindow_TileEditor.pasteMode == PASTEMODE.FILL) { if (GuiWindow_TileEditor.editingLayer == 0) { temp.floodedArea = getFloodedAreaZero(temp.mx, temp.my); } else { temp.tileLayer = tilelayers[GuiWindow_TileEditor.editingLayer]; temp.floodedArea = getFloodedAreaLayer(temp.tileLayer, temp.mx, temp.my); } temp.pasteX = temp.floodedArea[0]; temp.pasteY = temp.floodedArea[1]; temp.sizeY = temp.floodedArea[3] - temp.pasteY + 1; temp.sizeX = temp.floodedArea[2] - temp.pasteX + 1; temp.pasteData = new [temp.sizeY][temp.sizeX]; temp.historyData = {}; maxlooplimit = 100000; for (temp.y = 0; temp.y < temp.sizeY; temp.y++) { temp.row = {}; for (temp.x = 0; temp.x < temp.sizeX; temp.x++) { if ((@{temp.pasteX + temp.x, temp.pasteY + temp.y}) in temp.floodedArea) { temp.pasteData[temp.y][temp.x] = GuiWindow_TileEditor.clipboard[(temp.pasteY - temp.my + temp.y) % GuiWindow_TileEditor.clipboard.size()][(temp.pasteX - temp.mx + temp.x) % GuiWindow_TileEditor.clipboard[0].size()]; } else { temp.pasteData[temp.y][temp.x] = -2; } if (GuiWindow_TileEditor.editingLayer == 0) temp.row.add(tiles[temp.pasteX + temp.x, temp.pasteY + temp.y]); else temp.row.add(temp.tileLayer.tiles[temp.pasteX + temp.x, temp.pasteY + temp.y]); } temp.historyData.add(temp.row); } temp.historyObject = { temp.pasteX, temp.pasteY, GuiWindow_TileEditor.editingLayer, temp.historyData, temp.pasteData }; if (GuiWindow_TileEditor.history == NULL) GuiWindow_TileEditor.history = {}; GuiWindow_TileEditor.history = GuiWindow_TileEditor.history.subarray(GuiWindow_TileEditor.historyIndex); GuiWindow_TileEditor.historyIndex = 0; GuiWindow_TileEditor.history.insert(0, temp.historyObject); triggerserver("gui", this.name, RPL.PLACETILES, temp.pasteData, temp.pasteX, temp.pasteY, GuiWindow_TileEditor.editingLayer); } } function GraalControl.onRightMouseUp(temp.keyMod, temp.xMouse, temp.yMouse, temp.clickCount) { if (GuiWindow_TileEditor == NULL || GuiShowImg_TileEditor_ClipboardPreview == NULL) return; GuiShowImg_TileEditor_ClipboardPreview.blue = 0.0; GuiDrawingPanel_TileEditor_ClipboardPreview.flickering = true; GuiShowImg_TileEditor_ClipboardPreview.x = screenx(int(mousex), 0) - 2; GuiShowImg_TileEditor_ClipboardPreview.y = screeny(0, int(mousey)) - 2; } function GraalControl.onMouseDragged(temp.keyMod, temp.xMouse, temp.yMouse, temp.clickCount) { if (GuiWindow_TileEditor == NULL) return; GuiWindow_TileEditor.tileSelectEnd = {int(mousex), int(mousey)}; drawSelect(); } function GraalControl.onMouseUp(temp.keyMod, temp.xMouse, temp.yMouse, temp.clickCount) { hideimgs(200, 204); if (GuiWindow_TileEditor == NULL) return; setClipboardFromLevel(); GuiWindow_TileEditor.visible = true; } function GraalControl.onMouseMove(temp.keyMod, temp.xMouse, temp.yMouse, temp.clickCount) { if (GuiShowImg_TileEditor_ClipboardPreview == NULL) return; temp.mx = int(mousex); temp.my = int(mousey); GuiShowImg_TileEditor_ClipboardPreview.x = screenx(temp.mx, 0) - 2; GuiShowImg_TileEditor_ClipboardPreview.y = screeny(0, temp.my) - 2; with (findimg(201)) { layer = 0; image = GuiWindow_TileEditor.pasteMode == PASTEMODE.FILL ? "tileeditor_bucket_1-1.png" : "tileeditor_pencil_1-1.png"; x = temp.mx; y = temp.my - 1.5; } if (!GuiWindow_TileEditor.extraCursorInfo) return; with (findimg(202)) { layer = 0; text = temp.mx @ ", " @ temp.my; zoom = 0.6; x = temp.mx - 1.5 - gettextwidth(zoom, "", "", text) / 32; y = temp.my; } temp.tw = GuiWindow_TileEditor.clipboard[0].size(); temp.th = GuiWindow_TileEditor.clipboard.size(); temp.tex = temp.mx + tw; temp.tey = temp.my + th; with (findimg(203)) { layer = 0; text = (temp.tex - 1) @ ", " @ (temp.tey - 1); x = temp.tex + 0.5; y = temp.tey - 1; zoom = 0.6; } with (findimg(204)) { layer = 0; text = "(" @ temp.tw @ ", " @ temp.th @ ")"; zoom = 0.6; x = temp.mx + temp.tw / 2 - gettextwidth(zoom, "", "", text) / 32; y = temp.tey + 0.5; } } function GraalControl.onKeyDown(temp.keyCode, temp.keyText, temp.scanCode) { if (GuiWindow_TileEditor == NULL) return; if (timevar2 - GuiWindow_TileEditor.lastUndoOrRedoTime < 0.2) return; switch (temp.keyCode) { case 602: { // undo editorUndo(); break; } case 601: { // redo editorRedo(); break; } default: { return; } } GuiWindow_TileEditor.lastUndoOrRedoTime = timevar2; } function GuiTextEdit_TileEditor_Tileset.onLoseFirstResponder() { sleep(0.1); GuiTextEdit_TileEditor_Tileset.destroy(); } function GuiTextEdit_TileEditor_NewLevel.onLoseFirstResponder() { sleep(0.1); GuiTextEdit_TileEditor_NewLevel.destroy(); } function onCloseEditor() { GraalControl.cursor = "default"; GuiWindow_TileEditor.fadeLayers = false; updateFadeEffect(); GuiWindow_TileEditor.grid = false; updateGridEffect(); if (GuiShowImg_TileEditor_ClipboardPreview != NULL) GuiShowImg_TileEditor_ClipboardPreview.destroy(); if (GuiWindow_TileEditor_FileOpen != NULL) GuiWindow_TileEditor_FileOpen.destroy(); if (GuiWindow_TileEditor_FileSave != NULL) GuiWindow_TileEditor_FileSave.destroy(); GuiWindow_TileEditor.destroy(); hideimgs(200, 204); } function onRequestUse() { triggerserver("gui", this.name, RPL.REQUESTUSE); do { temp.time = timevar2; waitfor(this, "onActionClientSide", 15.0); if (timevar2 - temp.time > 15.0) { shared.adminmessage("Your request to use the editor timed out"); return; } } while (params[0] != RPL.REQUESTUSE); if (params[1]) showGui(params[2]); else shared.adminmessage("You do not have rights to edit this level"); } /** * functions */ function showGui(temp.version) { if (GuiWindow_TileEditor != NULL) GuiWindow_TileEditor.destroy(); new GuiWindowCtrl("GuiWindow_TileEditor") { profile = GuiBlueWindowProfile; canminimize = canmaximize = false; closequery = true; width = 304; height = 304; x = screenwidth - width; text = " Tile Editor v" @ temp.version SPC "(Layer 1)"; this.version = temp.version; this.tilesetImage = "TILES"; this.editingLayer = 0; this.editingLevel = isonmap ? player.gmap.name : player.level.name; this.pasteMode = PASTEMODE.NORMAL; new GuiShowImgCtrl("GuiShowImg_TileEditor_Icon") { useownprofile = true; profile.modal = false; x = 8; y = 4; width = 16; height = 16; image = "tileeditor_icon_1-1.png"; } new GuiMenuCtrl("GuiMenu_TileEditor") { profile = GuiBlueTextEditProfile; x = 6; y = 24; width = 304 - x * 2; height = 20; clearmenus(); with (addmenu("File")) { profile = GuiBluePopUpMenuProfile; textprofile = GuiBlueTextListProfile; addrow(0, "New Level").hint = "Create a new Graal level at the specified filepath"; addrow(1, "Open").hint = "Open a clipboard file saved on the server"; addrow(2, "Save").hint = "Save the current selection as a clipboard file on the server"; addrow(3, "Exit"); } with (addmenu("Edit")) { profile = GuiBluePopUpMenuProfile; textprofile = GuiBlueTextListProfile; temp.ctrlKey = getplatform() == "mac" ? "CMD" : "CTRL"; addrow(0, "Undo").hint = "Undo the previous tile paste (" @ temp.ctrlKey @ "+Z)"; addrow(1, "Redo").hint = "Redo the previous undone paste (" @ temp.ctrlKey @ "+Y)"; } with (addmenu("View")) { profile = GuiBluePopUpMenuProfile; textprofile = GuiBlueTextListProfile; addrow(0, "Fade inactive layers").hint = "Fades the inactive tilelayers, so you can focus on the layer you need to edit"; addrow(1, "Grid").hint = "Forms a grid to measure and be more precise with tile placement"; addrow(2, "Extra cursor info").hint = "Displays coordinates and selection size at the cursor"; } with (addmenu("Tileset")) { profile = GuiBluePopUpMenuProfile; textprofile = GuiBlueTextListProfile; addrow(0, "Use image").hint = "Show an image to select from, rather than tiledefs"; addrow(1, "Use tiledefs").hint = "Show the current tiledefs to select from"; } with (addmenu("Layer")) { profile = GuiBluePopUpMenuProfile; textprofile = GuiBlueTextListProfile; for (temp.i = 0; temp.i < tilelayercount; temp.i++) addrow(temp.i, temp.i + 1).hint = "Change the current editing layer to" SPC (temp.i + 1); setrowbyid(0, "*1"); } with (addmenu("Options")) { profile = GuiBluePopUpMenuProfile; textprofile = GuiBlueTextListProfile; temp.obj = addrow(0, "External"); temp.obj.hint = "Toggle between using an internal window and an external window"; GuiWindow_TileEditor.externalToggleMenuRowObj = temp.obj; addrow(1, "Help").hint = "Open an internet browser window/tab to the graalonline forum thread"; } new GuiButtonCtrl("GuiButton_TileEditor_PasteMode") { profile = GuiBlueButtonProfile; x = 248; y = 0; width = 40; height = 20; text = ""; new GuiShowImgCtrl("GuiShowImg_TileEditor_PasteMode") { useownprofile = true; profile.modal = false; image = "tileeditor_bucket_1-1.png"; x = 12; y = 2; } } } new GuiScrollCtrl("GuiScroll_TileEditor") { profile = GuiBlueScrollProfile; x = 6; y = 44; width = 304 - x * 2; height = 304 - y - 6; hScrollBar = "alwaysOn"; vScrollBar = "alwaysOn"; new GuiDrawingPanel("GuiDrawingPanel_TileEditor") { width = 2048; height = 512; clearall(); drawimage(0, 0, GuiWindow_TileEditor.tilesetImage); cursor = "crosshair"; } } } GraalControl.cursor = "crosshair"; } function drawGuiSelect() { if (GuiWindow_TileEditor.tileSelectStart[0] <= GuiWindow_TileEditor.tileSelectEnd[0]) { temp.tsx = GuiWindow_TileEditor.tileSelectStart[0]; temp.tex = GuiWindow_TileEditor.tileSelectEnd[0] + 16; } else { temp.tsx = GuiWindow_TileEditor.tileSelectEnd[0]; temp.tex = GuiWindow_TileEditor.tileSelectStart[0] + 16; } if (GuiWindow_TileEditor.tileSelectStart[1] <= GuiWindow_TileEditor.tileSelectEnd[1]) { temp.tsy = GuiWindow_TileEditor.tileSelectStart[1]; temp.tey = GuiWindow_TileEditor.tileSelectEnd[1] + 16; } else { temp.tsy = GuiWindow_TileEditor.tileSelectEnd[1]; temp.tey = GuiWindow_TileEditor.tileSelectStart[1] + 16; } if (Gui_TileEditor_Select != NULL) { Gui_TileEditor_Select.x = temp.tsx; Gui_TileEditor_Select.y = temp.tsy; Gui_TileEditor_Select.width = temp.tex - temp.tsx; Gui_TileEditor_Select.height = temp.tey - temp.tsy; return; } with (GuiDrawingPanel_TileEditor) { new GuiControl("Gui_TileEditor_Select") { useownprofile = true; profile.cankeyfocus = profile.modal = false; profile.border = 3; x = temp.tsx; y = temp.tsy; width = temp.tex - temp.tsx; height = temp.tey - temp.tsy; red = green = blue = 0.0; } } } function drawSelect() { if (GuiWindow_TileEditor.tileSelectStart[0] <= GuiWindow_TileEditor.tileSelectEnd[0]) { temp.tsx = GuiWindow_TileEditor.tileSelectStart[0]; temp.tex = GuiWindow_TileEditor.tileSelectEnd[0] + 1.0; } else { temp.tsx = GuiWindow_TileEditor.tileSelectEnd[0]; temp.tex = GuiWindow_TileEditor.tileSelectStart[0] + 1.0; } if (GuiWindow_TileEditor.tileSelectStart[1] <= GuiWindow_TileEditor.tileSelectEnd[1]) { temp.tsy = GuiWindow_TileEditor.tileSelectStart[1]; temp.tey = GuiWindow_TileEditor.tileSelectEnd[1] + 1.0; } else { temp.tsy = GuiWindow_TileEditor.tileSelectEnd[1]; temp.tey = GuiWindow_TileEditor.tileSelectStart[1] + 1.0; } with (findimg(200)) { layer = 0; polygon = { temp.tsx, temp.tsy, temp.tex, temp.tsy, temp.tex, temp.tey, temp.tsx, temp.tey }; red = 0.0; green = 0.0; blue = 0.0; alpha = 0.6; } with (findimg(201)) { layer = 0; image = GuiWindow_TileEditor.pasteMode == PASTEMODE.FILL ? "tileeditor_bucket_1-1.png" : "tileeditor_pencil_1-1.png"; x = temp.tsx; y = temp.tsy - 1.5; } with (findimg(202)) { layer = 0; text = temp.tsx @ ", " @ temp.tsy; zoom = 0.6; x = temp.tsx - 1.5 - gettextwidth(zoom, "", "", text) / 32; y = temp.tsy; } with (findimg(203)) { layer = 0; text = (temp.tex - 1) @ ", " @ (temp.tey - 1); x = temp.tex + 0.5; y = temp.tey - 1; zoom = 0.6; } with (findimg(204)) { layer = 0; text = "(" @ (temp.tex - temp.tsx) @ ", " @ (temp.tey - temp.tsy) @ ")"; zoom = 0.6; x = temp.tsx + (temp.tex - temp.tsx) / 2 - gettextwidth(zoom, "", "", text) / 32; y = temp.tey + 0.5; } } function showFileOpenGui() { if (GuiWindow_TileEditor_FileSave != NULL) GuiWindow_TileEditor_FileSave.destroy(); if (GuiWindow_TileEditor_FileOpen != NULL) GuiWindow_TileEditor_FileOpen.destroy(); new GuiWindowCtrl("GuiWindow_TileEditor_FileOpen") { profile = GuiBlueWindowProfile; destroyonhide = true; canresize = canminimize = canmaximize = false; width = 304; height = 304; x = screenwidth / 2 - width / 2; y = screenheight / 2 - height / 2; text = "Open"; new GuiScrollCtrl("GuiScroll_TileEditor_FileOpen_Preview_Image") { x = 6; y = 24; profile = GuiBlueScrollProfile; width = 88; height = 88; hScrollBar = "alwaysOff"; vScrollBar = "alwaysOff"; new GuiStretchCtrl("GuiStretch_TileEditor_FileOpen") { width = 84; height = 84; new GuiDrawingPanel("GuiDrawingPanel_TileEditor_FileOpen_Preview") { clearall(); } } } new GuiScrollCtrl("GuiScroll_TileEditor_FileOpen_Preview_Text") { profile = GuiBlueScrollProfile; x = 92; y = 24; width = 304 - x - 6; height = 88; hScrollBar = "dynamic"; vScrollBar = "dynamic"; new GuiTextCtrl("GuiText_TileEditor_FileOpen_Title") { profile = GuiBlueTextProfile; x = 4; height = 20; text = "Title:"; } new GuiTextCtrl("GuiText_TileEditor_FileOpen_Title_Value") { profile = GuiBlueTextProfile; x = 56; height = 20; text = "N / A"; } new GuiTextCtrl("GuiText_TileEditor_FileOpen_Extent") { profile = GuiBlueTextProfile; x = 4; y = 18; height = 20; text = "Extent:"; } new GuiTextCtrl("GuiText_TileEditor_FileOpen_Extent_Value") { profile = GuiBlueTextProfile; x = 56; y = 18; height = 20; text = @{"N / A", "N / A"}; } new GuiTextCtrl("GuiText_TileEditor_FileOpen_Created") { profile = GuiBlueTextProfile; x = 4; y = 36; height = 20; text = "Created:"; } new GuiTextCtrl("GuiText_TileEditor_FileOpen_Created_Value") { profile = GuiBlueTextProfile; x = 56; y = 36; height = 20; text = "N / A"; } } new GuiScrollCtrl("GuiScroll_TileEditor_FileOpen_Browse") { profile = GuiBlueScrollProfile; x = 6; y = 112; width = 304 - x * 2; height = 160; hScrollBar = "dynamic"; vScrollBar = "dynamic"; new GuiTreeViewCtrl("GuiTreeView_TileEditor_FileOpen") { profile = GuiBlueTreeViewProfile; width = 132; fitparentwidth = true; } } new GuiButtonCtrl("GuiButton_TileEditor_FileOpen_Delete") { profile = GuiBlueButtonProfile; x = 6; y = 273; width = 70; height = 24; text = "Delete"; } new GuiButtonCtrl("GuiButton_TileEditor_FileOpen_Open") { profile = GuiBlueButtonProfile; x = 98; y = 273; width = 100; height = 24; text = "Open"; } new GuiButtonCtrl("GuiButton_TileEditor_FileOpen_Cancel") { profile = GuiBlueButtonProfile; x = 198; y = 273; width = 100; height = 24; text = "Cancel"; } } triggerserver("gui", this.name, RPL.LISTCLIPBOARDFOLDER); } function showFileSaveGui() { if (GuiWindow_TileEditor_FileOpen != NULL) GuiWindow_TileEditor_FileOpen.destroy(); if (GuiWindow_TileEditor_FileSave != NULL) GuiWindow_TileEditor_FileSave.destroy(); new GuiWindowCtrl("GuiWindow_TileEditor_FileSave") { profile = GuiBlueWindowProfile; destroyonhide = true; canresize = canminimize = canmaximize = false; width = 304; height = 304; x = screenwidth / 2 - width / 2; y = screenheight / 2 - height / 2; text = "Save"; new GuiScrollCtrl("GuiScroll_TileEditor_FileSave_Preview_Image") { x = 6; y = 24; profile = GuiBlueScrollProfile; width = 88; height = 88; hScrollBar = "alwaysOff"; vScrollBar = "alwaysOff"; new GuiStretchCtrl("GuiStretch_TileEditor_FileSave") { width = 84; height = 84; new GuiDrawingPanel("GuiDrawingPanel_TileEditor_FileSave_Preview") { clearall(); } } } new GuiScrollCtrl("GuiScroll_TileEditor_FileSave_Preview_Text") { profile = GuiBlueScrollProfile; x = 92; y = 24; width = 304 - x - 6; height = 88; hScrollBar = "dynamic"; vScrollBar = "dynamic"; new GuiTextCtrl("GuiText_TileEditor_FileSave_Title") { profile = GuiBlueTextProfile; x = 4; height = 20; text = "Title:"; } new GuiTextCtrl("GuiText_TileEditor_FileSave_Title_Value") { profile = GuiBlueTextProfile; x = 56; height = 20; text = "N / A"; } new GuiTextCtrl("GuiText_TileEditor_FileSave_Extent") { profile = GuiBlueTextProfile; x = 4; y = 18; height = 20; text = "Extent:"; } new GuiTextCtrl("GuiText_TileEditor_FileSave_Extent_Value") { profile = GuiBlueTextProfile; x = 56; y = 18; height = 20; text = @{"N / A", "N / A"}; } new GuiTextCtrl("GuiText_TileEditor_FileSave_Created") { profile = GuiBlueTextProfile; x = 4; y = 36; height = 20; text = "Created:"; } new GuiTextCtrl("GuiText_TileEditor_FileSave_Created_Value") { profile = GuiBlueTextProfile; x = 56; y = 36; height = 20; text = "N / A"; } } new GuiScrollCtrl("GuiScroll_TileEditor_FileSave_Browse") { profile = GuiBlueScrollProfile; x = 6; y = 112; width = 304 - x * 2; height = 141; hScrollBar = "dynamic"; vScrollBar = "dynamic"; new GuiTreeViewCtrl("GuiTreeView_TileEditor_FileSave") { profile = GuiBlueTreeViewProfile; width = 132; fitparentwidth = true; } } new GuiTextEditCtrl("GuiTextEdit_TileEditor_FileSave_FilePath") { profile = GuiBlueTextEditProfile; x = 6; y = 253; width = 304 - x * 2; height = 20; } new GuiButtonCtrl("GuiButton_TileEditor_FileSave_Delete") { profile = GuiBlueButtonProfile; x = 6; y = 273; width = 70; height = 24; text = "Delete"; } new GuiButtonCtrl("GuiButton_TileEditor_FileSave_Save") { profile = GuiBlueButtonProfile; x = 98; y = 273; width = 100; height = 24; text = "Save"; } new GuiButtonCtrl("GuiButton_TileEditor_FileSave_Cancel") { profile = GuiBlueButtonProfile; x = 198; y = 273; width = 100; height = 24; text = "Cancel"; } } triggerserver("gui", this.name, RPL.LISTCLIPBOARDFOLDER); } function setClipboardFromLevel() { if (GuiWindow_TileEditor.tileSelectStart[0] <= GuiWindow_TileEditor.tileSelectEnd[0]) { temp.tsx = GuiWindow_TileEditor.tileSelectStart[0]; temp.tex = GuiWindow_TileEditor.tileSelectEnd[0] + 1; } else { temp.tsx = GuiWindow_TileEditor.tileSelectEnd[0]; temp.tex = GuiWindow_TileEditor.tileSelectStart[0] + 1; } if (GuiWindow_TileEditor.tileSelectStart[1] <= GuiWindow_TileEditor.tileSelectEnd[1]) { temp.tsy = GuiWindow_TileEditor.tileSelectStart[1]; temp.tey = GuiWindow_TileEditor.tileSelectEnd[1] + 1; } else { temp.tsy = GuiWindow_TileEditor.tileSelectEnd[1]; temp.tey = GuiWindow_TileEditor.tileSelectStart[1] + 1; } GuiWindow_TileEditor.clipboard = {}; for (temp.y = temp.tsy; temp.y < temp.tey; temp.y++) { temp.arr = {}; for (temp.x = temp.tsx; temp.x < temp.tex; temp.x++) { if (GuiWindow_TileEditor.editingLayer == 0) temp.tile = tiles[temp.x, temp.y]; else temp.tile = tilelayers[GuiWindow_TileEditor.editingLayer].tiles[temp.x, temp.y]; temp.arr.add(temp.tile); } GuiWindow_TileEditor.clipboard.add(temp.arr); } drawClipboardPreview(); } function setClipboardFromGui() { if (GuiWindow_TileEditor.tileSelectStart[0] < 0) GuiWindow_TileEditor.tileSelectStart[0] = 0; elseif(GuiWindow_TileEditor.tileSelectStart[0] >= GuiDrawingPanel_TileEditor.width) GuiWindow_TileEditor.tileSelectStart[0] = GuiDrawingPanel_TileEditor.width - 16; if (GuiWindow_TileEditor.tileSelectStart[1] < 0) GuiWindow_TileEditor.tileSelectStart[1] = 0; elseif(GuiWindow_TileEditor.tileSelectStart[1] >= GuiDrawingPanel_TileEditor.height) GuiWindow_TileEditor.tileSelectStart[1] = GuiDrawingPanel_TileEditor.height - 16; if (GuiWindow_TileEditor.tileSelectEnd[0] < 0) GuiWindow_TileEditor.tileSelectEnd[0] = 0; elseif(GuiWindow_TileEditor.tileSelectEnd[0] >= GuiDrawingPanel_TileEditor.width) GuiWindow_TileEditor.tileSelectEnd[0] = GuiDrawingPanel_TileEditor.width - 16; if (GuiWindow_TileEditor.tileSelectEnd[1] < 0) GuiWindow_TileEditor.tileSelectEnd[1] = 0; elseif(GuiWindow_TileEditor.tileSelectEnd[1] >= GuiDrawingPanel_TileEditor.height) GuiWindow_TileEditor.tileSelectEnd[1] = GuiDrawingPanel_TileEditor.height - 16; if (GuiWindow_TileEditor.tileSelectStart[0] <= GuiWindow_TileEditor.tileSelectEnd[0]) { temp.tsx = GuiWindow_TileEditor.tileSelectStart[0]; temp.tex = GuiWindow_TileEditor.tileSelectEnd[0] + 16; } else { temp.tsx = GuiWindow_TileEditor.tileSelectEnd[0]; temp.tex = GuiWindow_TileEditor.tileSelectStart[0] + 16; } if (GuiWindow_TileEditor.tileSelectStart[1] <= GuiWindow_TileEditor.tileSelectEnd[1]) { temp.tsy = GuiWindow_TileEditor.tileSelectStart[1]; temp.tey = GuiWindow_TileEditor.tileSelectEnd[1] + 16; } else { temp.tsy = GuiWindow_TileEditor.tileSelectEnd[1]; temp.tey = GuiWindow_TileEditor.tileSelectStart[1] + 16; } GuiWindow_TileEditor.clipboard = {}; for (temp.y = temp.tsy; temp.y < temp.tey; temp.y += 16) { temp.arr = {}; for (temp.x = temp.tsx; temp.x < temp.tex; temp.x += 16) temp.arr.add(getXYTile(temp.x, temp.y)); GuiWindow_TileEditor.clipboard.add(temp.arr); } drawClipboardPreview(); } function drawClipboardPreview() { if (GuiShowImg_TileEditor_ClipboardPreview != NULL) GuiShowImg_TileEditor_ClipboardPreview.destroy(); new GuiShowImgCtrl("GuiShowImg_TileEditor_ClipboardPreview") { useownprofile = true; profile.cankeyfocus = profile.modal = false; x = screenx(int(mousex), 0) - 2; y = screeny(0, int(mousey)) - 2; width = GuiWindow_TileEditor.clipboard[0].size() * 16 + 4; height = GuiWindow_TileEditor.clipboard.size() * 16 + 4; polygon = { 0, 0, width, 0, width, height, 0, height }; red = green = blue = 0.0; alpha = 0.6; new GuiDrawingPanel("GuiDrawingPanel_TileEditor_ClipboardPreview") { useownprofile = true; profile.cankeyfocus = profile.modal = false; x = y = 2; width = GuiWindow_TileEditor.clipboard[0].size() * 16; height = GuiWindow_TileEditor.clipboard.size() * 16; clearall(); for (temp.y = 0; temp.y < GuiWindow_TileEditor.clipboard.size(); temp.y++) { for (temp.x = 0; temp.x < GuiWindow_TileEditor.clipboard[0].size(); temp.x++) { temp.xy = getTileXY(GuiWindow_TileEditor.clipboard[temp.y][temp.x]); drawimagerectangle(temp.x * 16, temp.y * 16, GuiWindow_TileEditor.tilesetImage, temp.xy[0], temp.xy[1], 16, 16); } } flickering = true; alpha = 0.5; } } GuiShowImg_TileEditor_ClipboardPreview.pushtoback(); } function getFloodedAreaZero(temp.x, temp.y) { temp.tile = tiles[temp.x, temp.y]; temp.a = {temp.x, temp.y, temp.x, temp.y}; temp.q = {{temp.x, temp.y}}; temp.tileMap = new [height][width]; maxlooplimit = 100000; temp.minX = temp.x - 64; if (temp.minX < 0) temp.minX = 0; temp.minY = temp.y - 64; if (temp.minY < 0) temp.minY = 0; temp.maxX = temp.x + 64; if (temp.maxX >= width) temp.maxX = width - 1; temp.maxY = temp.y + 64; if (temp.maxY >= height) temp.maxY = height - 1; while (temp.q.size() != 0) { temp.n = temp.q[0]; temp.q.delete(0); temp.x = temp.n[0]; temp.y = temp.n[1]; if (tiles[temp.x, temp.y] == temp.tile && !temp.tileMap[temp.y][temp.x]) { temp.tileMap[temp.y][temp.x] = true; temp.a.add(temp.n); if (temp.a.size() == 4100) break; if (temp.x < temp.a[0]) temp.a[0] = temp.x; elseif (temp.x > temp.a[2]) temp.a[2] = temp.x; if (temp.y < temp.a[1]) temp.a[1] = temp.y; elseif (temp.y > temp.a[3]) temp.a[3] = temp.y; if (temp.y > temp.minY) temp.q.add({temp.x, temp.y - 1}); if (temp.x > temp.minX) temp.q.add({temp.x - 1, temp.y}); if (temp.y < temp.maxY) temp.q.add({temp.x, temp.y + 1}); if (temp.x < temp.maxX) temp.q.add({temp.x + 1, temp.y}); } } return temp.a; } function getFloodedAreaLayer(temp.tileLayer, temp.x, temp.y) { temp.tile = temp.tileLayer.tiles[temp.x, temp.y]; temp.a = {temp.x, temp.y, temp.x, temp.y}; temp.q = {{temp.x, temp.y}}; temp.tileMap = new [height][width]; maxlooplimit = 100000; temp.minX = temp.x - 64; if (temp.minX < 0) temp.minX = 0; temp.minY = temp.y - 64; if (temp.minY < 0) temp.minY = 0; temp.maxX = temp.x + 64; if (temp.maxX >= width) temp.maxX = width - 1; temp.maxY = temp.y + 64; if (temp.maxY >= height) temp.maxY = height - 1; while (temp.q.size() != 0) { temp.n = temp.q[0]; temp.q.delete(0); temp.x = temp.n[0]; temp.y = temp.n[1]; if (temp.tileLayer.tiles[temp.x, temp.y] == temp.tile && !temp.tileMap[temp.y][temp.x]) { temp.tileMap[temp.y][temp.x] = true; temp.a.add(temp.n); if (temp.a.size() == 4100) break; if (temp.x < temp.a[0]) temp.a[0] = temp.x; elseif (temp.x > temp.a[2]) temp.a[2] = temp.x; if (temp.y < temp.a[1]) temp.a[1] = temp.y; elseif (temp.y > temp.a[3]) temp.a[3] = temp.y; if (temp.y > temp.minY) temp.q.add({temp.x, temp.y - 1}); if (temp.x > temp.minX) temp.q.add({temp.x - 1, temp.y}); if (temp.y < temp.maxY) temp.q.add({temp.x, temp.y + 1}); if (temp.x < temp.maxX) temp.q.add({temp.x + 1, temp.y}); } } return temp.a; } function editorUndo() { if (GuiWindow_TileEditor == NULL) return; if (GuiWindow_TileEditor.historyIndex == GuiWindow_TileEditor.history.size()) { shared.adminmessage("nothing to undo"); return; } triggerserver( "gui", this.name, RPL.PLACETILES, GuiWindow_TileEditor.history[GuiWindow_TileEditor.historyIndex][3], GuiWindow_TileEditor.history[GuiWindow_TileEditor.historyIndex][0], GuiWindow_TileEditor.history[GuiWindow_TileEditor.historyIndex][1], GuiWindow_TileEditor.history[GuiWindow_TileEditor.historyIndex][2] ); GuiWindow_TileEditor.historyIndex++; } function editorRedo() { if (GuiWindow_TileEditor == NULL) return; if (GuiWindow_TileEditor.historyIndex == 0) { shared.adminmessage("nothing to redo"); return; } GuiWindow_TileEditor.historyIndex--; triggerserver( "gui", this.name, RPL.PLACETILES, GuiWindow_TileEditor.history[GuiWindow_TileEditor.historyIndex][4], GuiWindow_TileEditor.history[GuiWindow_TileEditor.historyIndex][0], GuiWindow_TileEditor.history[GuiWindow_TileEditor.historyIndex][1], GuiWindow_TileEditor.history[GuiWindow_TileEditor.historyIndex][2] ); } function updateFadeEffect() { if (GuiWindow_TileEditor.fadeLayers) { for (temp.i = 0; temp.i < tilelayercount; temp.i++) { if (temp.i == GuiWindow_TileEditor.editingLayer) { tilelayers[temp.i].red = tilelayers[temp.i].green = tilelayers[temp.i].blue = tilelayers[temp.i].alpha = 1.0; } else { tilelayers[temp.i].red = tilelayers[temp.i].green = tilelayers[temp.i].blue = 0.25; if (temp.i != 0) tilelayers[temp.i].alpha = 0.25; } } } else { for (temp.i = 0; temp.i < tilelayercount; temp.i++) { tilelayers[temp.i].red = tilelayers[temp.i].green = tilelayers[temp.i].blue = tilelayers[temp.i].alpha = 1.0; } } } function updateGridEffect() { if (this.gridImageCount != NULL) { hideimgs(300, 300 + this.gridImageCount); this.gridImageCount = NULL; } if (GuiWindow_TileEditor.grid) { temp.w = width; temp.h = height; for (temp.y = 0; temp.y < temp.h; temp.y++) { with (findimg(300 + temp.i++)) { layer = 3; polygon = { 0, temp.y, temp.w, temp.y, temp.w, temp.y + 1 / 16, 0, temp.y + 1 / 16 }; alpha = 0.5; } } for (temp.x = 0; temp.x < temp.w; temp.x++) { with (findimg(300 + temp.i++)) { layer = 3; polygon = { temp.x, 0, temp.x, temp.h, temp.x + 1 / 16, temp.h, temp.x + 1 / 16, 0 }; alpha = 0.5; } } this.gridImageCount = temp.i; } } function getTileXY(temp.tile) { return { int(temp.tile % 16.0) * 16 + int(temp.tile / 512.0) * 256, (int(temp.tile / 16.0) * 16) % 512 }; } function getXYTile(temp.x, temp.y) { return int(temp.x / 16.0) % 16 + int(temp.x / 256.0) * 512 + int(temp.y / 16.0) * 16 % 512; } public function close() { trigger("onCloseEditor"); } public function open() { trigger("onRequestUse"); } public function isOpen() { return (GuiWindow_TileEditor != NULL); }