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 }