Graal Pastebin
New PastePasted on April 17, 2011.
View the raw file
//#CLIENTSIDE const ZOOM_MIN = 1; const ZOOM_DEFAULT = 1; const ZOOM_MAX = 5; const NAME_ZOOM_IN = "+"; const NAME_ZOOM_OUT = "-"; const NAME_HORIZONTAL = "Horizontal"; const NAME_VERTICAL = "Vertical"; const BLOCK_HORIZONTAL = 8; const BLOCK_VERTICAL = 11; const COLOR_WALL = "0,0,50"; const COLOR_FLOOR = "200,200,255"; const EXPORT_FLOOR = "."; const EXPORT_WALL = "X"; const GUI_PADDING = 5; function ChatBar.onAction() { if (ChatBar.text == ":dungeon") { ChatBar.text = ""; ChatBar.visible = false; sleep(0.05); // give the chat bar a frame to hide first this.drawWindow(); } } function drawWindow() { if (DungeonEditor_Window != null) { DungeonEditor_Window.destroy(); } new GuiWindowCtrl("DungeonEditor_Window") { profile = GuiBlueWindowProfile; clientRelative = canClose = canMinimize = canMaximize = canResize = true; isExternal = false; clientWidth = 300; clientHeight = 300; minExtent = {280, 200}; x = (GraalControl.width / 2) - (width / 2); y = (GraalControl.height / 2) - (height / 2); text = "Dungeon Editor"; temp.currentY = GUI_PADDING; temp.blockTypes = { {NAME_HORIZONTAL, BLOCK_HORIZONTAL}, {NAME_VERTICAL, BLOCK_VERTICAL} }; temp.i = 0; for (temp.blockType : blockTypes) { new GuiTextEditCtrl("DungeonEditor_Block_" @ blockType[0] @ "_Count") { DungeonEditor_Window.blockCounts.add(this); profile = GuiBlueTextEditProfile; useOwnProfile = true; profile.fontSize = 18; profile.align = "center"; width = 40; height = 30; alpha = 0.8; x = 110 + (GUI_PADDING * 2); y = currentY; this.blockTypeID = i; thiso.catchEvent(this, "onTextChanged", "onBlockSizeChanged"); } new GuiTextCtrl("DungeonEditor_Block_" @ blockType[0] @ "_Label") { useOwnProfile = true; // fix: align doesn't work with GuiBlueTextProfile, why? profile.fontColor = GuiBlueTextProfile.fontColor; profile.justify = "right"; profile.modal = false; x = GUI_PADDING; y = currentY; width = 110; height = profile.getTextHeight(); currentY += height; text = blockType[0] @ " blocks:"; } new GuiTextCtrl("DungeonEditor_Block_" @ blockType[0] @ "_Label_Size") { useOwnProfile = true; // fix: align doesn't work with GuiBlueTextProfile, why? profile.fontColor = GuiBlueTextProfile.fontColor; profile.justify = "right"; profile.modal = false; profile.fontSize = 12; x = GUI_PADDING; y = currentY; width = 110; height = profile.getTextHeight(); currentY += height; text = "(" @ blockType[1] @ " tiles each)"; } currentY += GUI_PADDING; i ++; } new GuiMLTextCtrl("DungeonEditor_MapSize") { profile = GuiBlueMLTextProfile; x = 150 + (GUI_PADDING * 3); y = GUI_PADDING; //((currentY - GUI_PADDING) / 2) - profile.getTextHeight(); width = DungeonEditor_Window.clientWidth - x - GUI_PADDING; text = "<center><b>Map size:</b>\n4x4 levels"; horizSizing = "width"; } temp.zoomOptions = {NAME_ZOOM_OUT, NAME_ZOOM_IN}; temp.zoomY = currentY - 24 - GUI_PADDING; //(GUI_PADDING * 2) + ((DungeonEditor_MapSize.profile.getTextHeight() + 1) * 2); temp.i = 0; for (temp.zoomOption : zoomOptions) { new GuiButtonCtrl("DungeonEditor_Zoom_" @ i) { DungeonEditor_Window.zoomButtons.add(this); profile = GuiBlueButtonProfile; width = 24; height = width; x = DungeonEditor_Window.clientWidth - (GUI_PADDING * ((1 - i) + 1)) - (((1 - i) + 1) * width); y = zoomY; text = zoomOption; horizSizing = "left"; this.zoomAction = (i == 0 ? (- 1) : 1); thiso.catchEvent(this, "onAction", "onChangeZoom"); } i ++; } temp.firstZoomButton = DungeonEditor_Window.zoomButtons[0]; new GuiTextCtrl("DungeonEditor_Zoom_Label") { useOwnProfile = true; // fix: align doesn't work with GuiBlueTextProfile, why? profile.fontColor = GuiBlueTextProfile.fontColor; profile.justify = "right"; profile.modal = false; profile.fontStyle = "b"; x = GUI_PADDING; y = zoomY + 4; width = firstZoomButton.x - x - GUI_PADDING; height = profile.getTextHeight(); horizSizing = "width"; text = "Zoom:"; } // currentY += firstZoomButton.y + currentY; temp.buttonHeight = 28; new GuiScrollCtrl("DungeonEditor_BlockScroll") { profile = GuiBlueScrollProfile; useOwnProfile = true; profile.border = 1; x = GUI_PADDING; y = currentY; width = DungeonEditor_Window.clientWidth - (x * 2); height = DungeonEditor_Window.clientHeight - y - (GUI_PADDING * 2) - buttonHeight; horizSizing = "width"; vertSizing = "height"; vScrollBar = hScrollBar = "dynamic"; } // button row new GuiButtonCtrl("DungeonEditor_ExternalToggle") { profile = GuiBlueButtonProfile; width = buttonHeight; height = buttonHeight; x = GUI_PADDING; y = DungeonEditor_Window.clientHeight - GUI_PADDING - height; hint = "Toggle between internal and external display."; text = ""; vertSizing = "top"; } new GuiButtonCtrl("DungeonEditor_Load") { profile = GuiBlueButtonProfile; width = 120; height = buttonHeight; temp.prevButton = DungeonEditor_ExternalToggle; x = prevButton.x + prevButton.width + GUI_PADDING; y = DungeonEditor_Window.clientHeight - GUI_PADDING - height; hint = "Load a map from an existing Dungeon.txt file."; text = "Load Dungeon"; vertSizing = "top"; } new GuiButtonCtrl("DungeonEditor_Save") { profile = GuiBlueButtonProfile; height = buttonHeight; temp.prevButton = DungeonEditor_Load; x = prevButton.x + prevButton.width + GUI_PADDING; y = DungeonEditor_Window.clientHeight - GUI_PADDING - height; width = DungeonEditor_Window.clientWidth - x - GUI_PADDING; hint = "Export the dungeon you've created into Dungeon.txt format."; text = "Save Dungeon"; horizSizing = "width"; vertSizing = "top"; } } this.setZoom(ZOOM_DEFAULT); this.setBlocks(32, 23); } function DungeonEditor_Save.onAction() { temp.exportedText = ""; for (temp.blockRow : DungeonEditor_BlockScroll.blockRows) { for (temp.block : blockRow) { exportedText @= block.isFloor ? EXPORT_FLOOR : EXPORT_WALL; } exportedText @= "\n"; } exportedText = exportedText.substring(0, exportedText.length() - 1); this.drawSaveWindow(exportedText); } function DungeonEditor_Load.onAction() { this.drawLoadWindow(); } function setZoom(zoomLevel) { this.zoomLevel = zoomLevel; DungeonEditor_Window.zoomButtons[0].active = zoomLevel > ZOOM_MIN; DungeonEditor_Window.zoomButtons[1].active = zoomLevel < ZOOM_MAX; temp.by = 0; for (temp.blockRow : DungeonEditor_BlockScroll.blockRows) { temp.bx = 0; for (temp.block : blockRow) { block.x = this.getBlockX(bx); block.y = this.getBlockY(by); block.width = this.getBlockWidth(); block.height = this.getBlockHeight(); bx ++; } by ++; } } function onBlockSizeChanged(sizeEdit) { if (sizeEdit.text == "") { return; } temp.blockTypeID = sizeEdit.blockTypeID; temp.newDim = min(100, max(1, abs(int(sizeEdit.text)))); if (newDim != sizeEdit.text) { return sizeEdit.text = newDim; } if (this.blockSize[blockTypeID] == newDim) { return; } temp.newSize = this.blockSize; newSize[blockTypeID] = newDim; this.setBlocks(newSize[0], newSize[1]); sizeEdit.makeFirstResponder(true); } function ceil(num) { if (int(num) != num) { return int(num) + 1; } return num; } function updateMapSize() { temp.mapWidth = ceil((this.blockSize[0] * BLOCK_HORIZONTAL) / 64); temp.mapHeight = ceil((this.blockSize[1] * BLOCK_VERTICAL) / 64); DungeonEditor_MapSize.text = "<center><b>Map size:</b>\n" @ mapWidth @ "x" @ mapHeight @ " levels"; } function setBlocks(horizBlocks, vertBlocks) { this.blockSize = {horizBlocks, vertBlocks}; temp.horizEdit = DungeonEditor_Window.blockCounts[0]; temp.vertEdit = DungeonEditor_Window.blockCounts[1]; if (horizEdit.text != horizBlocks) { horizEdit.text = horizBlocks; } if (vertEdit.text != vertBlocks) { vertEdit.text = vertBlocks; } this.updateMapSize(); with (DungeonEditor_BlockScroll) { if (this.blockRows.size() > 0) { // already has blocks in it, chop some off if needed // chop from the right if (this.blockRows[0].size() > horizBlocks) { temp.rowCount = 0; for (temp.blockRow : this.blockRows) { for (temp.i = (blockRow.size() - 1); i > (horizBlocks - 1); i --) { blockRow[i].destroy(); this.blockRows[rowCount].delete(i); } rowCount ++; } } else if (this.blockRows[0].size() < horizBlocks) { // need to add columns temp.rowCount = 0; for (temp.blockRow : this.blockRows) { for (temp.i = blockRow.size(); i < horizBlocks; i ++) { temp.block = newBlock(i, rowCount); this.blockRows[rowCount].add(block); } rowCount ++; } } // chop from the bottom if (this.blockRows.size() > vertBlocks) { for (temp.i = (this.blockRows.size() - 1); i > (vertBlocks - 1); i --) { temp.blockRow = this.blockRows[i]; for (temp.block : blockRow) { block.destroy(); } this.blockRows.delete(i); } } else if (this.blockRows.size() < vertBlocks) { // need to add rows for (temp.i = this.blockRows.size(); i < vertBlocks; i ++) { this.blockRows.add(newBlockRow(i, horizBlocks)); } } } else { // doesn't have blocks yet, make some for (temp.blockRow = 0; blockRow < vertBlocks; blockRow ++) { this.blockRows.add(newBlockRow(blockRow, horizBlocks)); } } thiso.colorBlocks(); } } function newBlockRow(blockRow, horizBlocks) { temp.row = null; for (temp.blockColumn = 0; blockColumn < horizBlocks; blockColumn ++) { row.add(newBlock(blockColumn, blockRow)); } return row; } function newBlock(bx, by) { temp.block = null; new GuiControl("DungeonEditor_Block_" @ bx @ "_" @ by) { block = this; useOwnProfile = true; profile.opaque = true; profile.fillColor = {0, 0, 0}; profile.modal = true; minExtent = {0, 0}; width = thiso.getBlockWidth(); height = thiso.getBlockHeight(); x = thiso.getBlockX(bx); y = thiso.getBlockY(by); this.isFloor = false; cursor = "pointer"; thiso.catchEvent(this, "onMouseDown", "onSwitchBlock"); thiso.catchEvent(this, "onMouseDragged", "onSwitchBlockDrag"); } return block; } function onSwitchBlock(block) { block.isFloor = ! block.isFloor; thiso.colorBlock(block); this.dragSet = block.isFloor; } function onSwitchBlockDrag(block) { block.isFloor = this.dragSet; thiso.colorBlock(block); } function colorBlocks() { with (DungeonEditor_BlockScroll) { for (temp.blockRow : this.blockRows) { for (temp.block : blockRow) { thiso.colorBlock(block); } } } } function colorBlock(block) { block.profile.fillColor = block.isFloor ? COLOR_FLOOR : COLOR_WALL; } function getBlockX(bx) { return bx * ((BLOCK_HORIZONTAL * thiso.zoomLevel) + 1); } function getBlockY(by) { return by * ((BLOCK_VERTICAL * thiso.zoomLevel) + 1); } function getBlockWidth() { return BLOCK_HORIZONTAL * thiso.zoomLevel; } function getBlockHeight() { return BLOCK_VERTICAL * thiso.zoomLevel; } function onChangeZoom(button) { this.setZoom(this.zoomLevel + button.zoomAction); } function DungeonEditor_ExternalToggle.onAction() { DungeonEditor_Window.isExternal = ! DungeonEditor_Window.isExternal; } function drawSaveWindow(exportedText) { if (DungeonEditorSave_Window != null) { DungeonEditorSave_Window.destroy(); } new GuiWindowCtrl("DungeonEditorSave_Window") { profile = GuiBlueWindowProfile; clientRelative = canClose = canMinimize = canMaximize = canResize = true; isExternal = DungeonEditor_Window.isExternal; clientWidth = 225; clientHeight = 175; minExtent = {200, 150}; x = (GraalControl.width / 2) - (width / 2); y = (GraalControl.height / 2) - (height / 2); text = "Dungeon Editor Export"; this.showTop(); new GuiMLTextCtrl("DungeonEditorSave_Help") { profile = GuiBlueMLTextProfile; x = GUI_PADDING; y = GUI_PADDING; width = DungeonEditorSave_Window.clientWidth - (x * 2); text = "<center>Paste the following code into your Dungeon.txt file:"; horizSizing = "width"; } new GuiScrollCtrl("DungeonEditorSave_Scroll") { profile = GuiBlueScrollProfile; useOwnProfile = true; profile.border = 1; x = GUI_PADDING; y = 50; width = DungeonEditorSave_Window.clientWidth - (x * 2); height = DungeonEditorSave_Window.clientHeight - y - GUI_PADDING; vertSizing = "height"; horizSizing = "width"; hScrollBar = vScrollBar = "alwaysOn"; new GuiMLTextEditCtrl("DungeonEditorSave_Text") { profile = GuiBlueMLTextProfile; wordwrap = false; useOwnProfile = true; profile.fontType = "Courier New"; x = 2; y = 2; width = DungeonEditorSave_Scroll.clientWidth; text = exportedText; } } } } function DungeonEditorSave_Help.onResize(newWidth, newHeight) { DungeonEditorSave_Scroll.y = newHeight + (GUI_PADDING * 2); DungeonEditorSave_Scroll.height = DungeonEditorSave_Window.clientHeight - DungeonEditorSave_Scroll.y - GUI_PADDING; } function drawLoadWindow() { if (DungeonEditorLoad_Window != null) { DungeonEditorLoad_Window.destroy(); } new GuiWindowCtrl("DungeonEditorLoad_Window") { profile = GuiBlueWindowProfile; clientRelative = canClose = canMinimize = canMaximize = canResize = true; isExternal = DungeonEditor_Window.isExternal; clientWidth = 225; clientHeight = 175; minExtent = {200, 150}; x = (GraalControl.width / 2) - (width / 2); y = (GraalControl.height / 2) - (height / 2); text = "Dungeon Editor Load"; this.showTop(); new GuiMLTextCtrl("DungeonEditorLoad_Help") { profile = GuiBlueMLTextProfile; x = GUI_PADDING; y = GUI_PADDING; width = DungeonEditorLoad_Window.clientWidth - (x * 2); text = "<center>Enter your Dungeon.txt file here to edit it:"; horizSizing = "width"; } new GuiScrollCtrl("DungeonEditorLoad_Scroll") { profile = GuiBlueScrollProfile; useOwnProfile = true; profile.border = 1; x = GUI_PADDING; y = 50; width = DungeonEditorLoad_Window.clientWidth - (x * 2); height = DungeonEditorLoad_Window.clientHeight - y - GUI_PADDING; vertSizing = "height"; horizSizing = "width"; hScrollBar = vScrollBar = "alwaysOn"; new GuiMLTextEditCtrl("DungeonEditorLoad_Text") { profile = GuiBlueMLTextProfile; wordwrap = false; useOwnProfile = true; profile.fontType = "Courier New"; x = 2; y = 2; width = DungeonEditorLoad_Scroll.clientWidth; text = ""; } } new GuiButtonCtrl("DungeonEditorLoad_Load") { profile = GuiBlueButtonProfile; width = DungeonEditorLoad_Window.clientWidth - (GUI_PADDING * 2); height = 28; x = GUI_PADDING; y = DungeonEditorLoad_Window.clientHeight - height - GUI_PADDING; text = "Load"; vertSizing = "top"; horizSizing = "width"; } } } function DungeonEditorLoad_Help.onResize(newWidth, newHeight) { DungeonEditorLoad_Scroll.y = newHeight + (GUI_PADDING * 2); DungeonEditorLoad_Scroll.height = DungeonEditorLoad_Window.clientHeight - DungeonEditorLoad_Scroll.y - (GUI_PADDING * 2) - DungeonEditorLoad_Load.height; } function DungeonEditorLoad_Load.onAction() { temp.lines = DungeonEditorLoad_Text.getLines(); this.setBlocks(lines[0].length(), lines.size()); temp.lineCount = 0; for (temp.line : lines) { for (temp.blockCount = 0; blockCount < line.length(); blockCount ++) { temp.char = line.charat(blockCount); DungeonEditor_BlockScroll.blockRows[lineCount][blockCount].isFloor = (char == EXPORT_FLOOR); } lineCount ++; } this.colorBlocks(); }