1 /** 2 Copyright: Copyright (c) 2016 Andrey Penechko. 3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Andrey Penechko. 5 */ 6 7 module voxelman.edit.tools.filltool; 8 9 import voxelman.math; 10 import voxelman.core.config; 11 import voxelman.core.packets; 12 import voxelman.world.storage.coordinates; 13 import voxelman.world.storage.worldbox; 14 15 import voxelman.client.plugin; 16 import voxelman.worldinteraction.plugin; 17 import voxelman.graphics.plugin; 18 import voxelman.net.plugin; 19 20 import voxelman.edit.plugin : ITool; 21 22 final class FillTool : ITool 23 { 24 WorldInteractionPlugin worldInteraction; 25 GraphicsPlugin graphics; 26 NetClientPlugin connection; 27 28 BlockId currentBlock = 4; 29 BlockWorldPos startingPos; 30 EditState state; 31 WorldBox selection; 32 bool showCursor = true; 33 34 enum EditState 35 { 36 none, 37 placing, 38 removing 39 } 40 41 this() { name = "voxelman.edit.fill_tool"; } 42 43 override void onUpdate() { 44 if (currentCursorPos.w != startingPos.w) 45 { 46 startingPos = currentCursorPos; 47 } 48 selection = worldBoxFromCorners(startingPos.vector.xyz, currentCursorPos.vector.xyz, cast(DimentionId)currentCursorPos.w); 49 drawSelection(); 50 if (showCursor && !worldInteraction.cameraInSolidBlock) 51 { 52 worldInteraction.drawCursor(worldInteraction.blockPos, Colors.red); 53 worldInteraction.drawCursor(worldInteraction.sideBlockPos, Colors.blue); 54 } 55 } 56 57 BlockWorldPos currentCursorPos() @property { 58 final switch(state) { 59 case EditState.none: return worldInteraction.blockPos; 60 case EditState.placing: 61 return worldInteraction.sideBlockPos; 62 case EditState.removing: 63 return worldInteraction.blockPos; 64 } 65 } 66 67 void drawSelection() { 68 final switch(state) { 69 case EditState.none: 70 break; 71 case EditState.placing: 72 graphics.debugBatch.putCube(vec3(selection.position) - cursorOffset, 73 vec3(selection.size) + cursorOffset, Colors.blue, false); 74 break; 75 case EditState.removing: 76 graphics.debugBatch.putCube(vec3(selection.position) - cursorOffset, 77 vec3(selection.size) + cursorOffset, Colors.red, false); 78 break; 79 } 80 } 81 82 override void onMainActionPress() { 83 if (state != EditState.none) return; 84 if (!worldInteraction.cursorHit) return; 85 state = EditState.removing; 86 startingPos = currentCursorPos; 87 showCursor = false; 88 } 89 90 override void onMainActionRelease() { 91 if (state != EditState.removing) return; 92 state = EditState.none; 93 showCursor = true; 94 95 if (worldInteraction.cursorHit) 96 { 97 worldInteraction.fillBox(selection, 1); 98 } 99 } 100 101 override void onSecondaryActionPress() { 102 if (state != EditState.none) return; 103 if (!worldInteraction.cursorHit) return; 104 state = EditState.placing; 105 startingPos = currentCursorPos; 106 showCursor = false; 107 } 108 109 override void onSecondaryActionRelease() { 110 if (state != EditState.placing) return; 111 state = EditState.none; 112 showCursor = true; 113 114 if (worldInteraction.cursorHit) 115 { 116 worldInteraction.fillBox(selection, currentBlock); 117 } 118 } 119 120 override void onTertiaryActionRelease() { 121 currentBlock = worldInteraction.pickBlock(); 122 } 123 }