1 /**
2 Copyright: Copyright (c) 2015-2017 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.plugin;
8 
9 import voxelman.log;
10 
11 import pluginlib;
12 import voxelman.core.events;
13 import derelict.imgui.imgui;
14 import dlib.math.utils;
15 import voxelman.utils.textformatter;
16 
17 import voxelman.core.config;
18 import voxelman.eventdispatcher.plugin;
19 import voxelman.graphics.plugin;
20 import voxelman.block.plugin;
21 import voxelman.command.plugin;
22 import voxelman.gui.plugin;
23 import voxelman.dbg.plugin;
24 import voxelman.net.plugin;
25 import voxelman.worldinteraction.plugin;
26 import voxelman.input.keybindingmanager;
27 
28 import voxelman.edit.tools.filltool;
29 
30 
31 abstract class ITool
32 {
33 	string name;
34 	size_t id;
35 	void onUpdate() {}
36 	void onRender(GraphicsPlugin renderer) {}
37 	void onMainActionPress() {}
38 	void onMainActionRelease() {}
39 	void onSecondaryActionPress() {}
40 	void onSecondaryActionRelease() {}
41 	void onTertiaryActionPress() {}
42 	void onTertiaryActionRelease() {}
43 	void onRotateAction() {}
44 }
45 
46 final class NullTool : ITool
47 {
48 	this() { name = "voxelman.edit.null_tool"; }
49 }
50 
51 import voxelman.utils.mapping;
52 class EditPlugin : IPlugin
53 {
54 	mixin IdAndSemverFrom!"voxelman.edit.plugininfo";
55 
56 	size_t selectedTool;
57 	GuiPlugin guiPlugin;
58 	GraphicsPlugin graphics;
59 	BlockManager blockManager;
60 	Mapping!ITool tools;
61 	NullTool nullTool;
62 	FillTool fillTool;
63 
64 	override void registerResources(IResourceManagerRegistry resmanRegistry)
65 	{
66 		blockManager = resmanRegistry.getResourceManager!BlockManager;
67 		auto keyBindingsMan = resmanRegistry.getResourceManager!KeyBindingManager;
68 		keyBindingsMan.registerKeyBinding(new KeyBinding(PointerButton.PB_1, "key.mainAction", &onMainActionPress, &onMainActionRelease));
69 		keyBindingsMan.registerKeyBinding(new KeyBinding(PointerButton.PB_2, "key.secondaryAction", &onSecondaryActionPress, &onSecondaryActionRelease));
70 		keyBindingsMan.registerKeyBinding(new KeyBinding(PointerButton.PB_3, "key.tertiaryAction", &onTertiaryActionPress, &onTertiaryActionRelease));
71 		keyBindingsMan.registerKeyBinding(new KeyBinding(KeyCode.KEY_RIGHT, "key.next_tool", null, &nextTool));
72 		keyBindingsMan.registerKeyBinding(new KeyBinding(KeyCode.KEY_LEFT, "key.prev_tool", null, &prevTool));
73 		keyBindingsMan.registerKeyBinding(new KeyBinding(KeyCode.KEY_R, "key.rotateAction", null, &onRotateAction));
74 	}
75 
76 	override void preInit() {
77 		nullTool = new NullTool;
78 		fillTool = new FillTool;
79 		registerTool(fillTool);
80 	}
81 
82 	override void init(IPluginManager pluginman)
83 	{
84 		fillTool.connection = pluginman.getPlugin!NetClientPlugin;
85 		fillTool.worldInteraction = pluginman.getPlugin!WorldInteractionPlugin;
86 		fillTool.blockInfos = blockManager.getBlocks();
87 
88 		graphics = pluginman.getPlugin!GraphicsPlugin;
89 		guiPlugin = pluginman.getPlugin!GuiPlugin;
90 		EventDispatcherPlugin evDispatcher = pluginman.getPlugin!EventDispatcherPlugin;
91 		evDispatcher.subscribeToEvent(&onUpdateEvent);
92 		evDispatcher.subscribeToEvent(&onRenderEvent);
93 
94 		auto debugClient = pluginman.getPlugin!DebugClient;
95 		debugClient.registerDebugGuiHandler(&showToolName, INFO_ORDER, "Tool");
96 
97 		auto commandPlugin = pluginman.getPlugin!CommandPluginClient;
98 		commandPlugin.registerCommand("pick", &onPickBlockName);
99 	}
100 
101 	private void showToolName() {
102 		igTextf("Tool: %s", currentTool.name);
103 	}
104 
105 	void onPickBlockName(CommandParams params) {
106 		if (params.args.length > 1)
107 		{
108 			size_t blockId = blockManager.getId(params.args[1]);
109 			if (blockId == size_t.max)
110 			{
111 				// no block
112 				infof("no block '%s'", params.args[1]);
113 			}
114 			else
115 			{
116 				fillTool.currentBlock = BlockIdAndMeta(cast(BlockId)blockId);
117 			}
118 		}
119 	}
120 
121 	void registerTool(ITool tool)
122 	{
123 		assert(tool);
124 		tools.put(tool);
125 	}
126 
127 	void nextTool(string) {
128 		selectedTool = selectedTool+1;
129 		if (selectedTool > tools.length-1)
130 			selectedTool = 0;
131 	}
132 
133 	void prevTool(string) {
134 		selectedTool = clamp(selectedTool-1, 0, tools.length-1);
135 	}
136 
137 	ITool currentTool() @property {
138 		if (selectedTool < tools.length)
139 			return tools[selectedTool];
140 		return nullTool;
141 	}
142 
143 	void onUpdateEvent(ref UpdateEvent event) {
144 		currentTool.onUpdate();
145 	}
146 	void onRenderEvent(ref RenderSolid3dEvent event) {
147 		currentTool.onRender(graphics);
148 	}
149 	void onMainActionPress(string key) {
150 		if (!guiPlugin.mouseLocked) return;
151 		currentTool.onMainActionPress();
152 	}
153 	void onMainActionRelease(string key) {
154 		if (!guiPlugin.mouseLocked) return;
155 		currentTool.onMainActionRelease();
156 	}
157 	void onSecondaryActionPress(string key) {
158 		if (!guiPlugin.mouseLocked) return;
159 		currentTool.onSecondaryActionPress();
160 	}
161 	void onSecondaryActionRelease(string key) {
162 		if (!guiPlugin.mouseLocked) return;
163 		currentTool.onSecondaryActionRelease();
164 	}
165 	void onTertiaryActionPress(string key) {
166 		if (!guiPlugin.mouseLocked) return;
167 		currentTool.onTertiaryActionPress();
168 	}
169 	void onTertiaryActionRelease(string key) {
170 		if (!guiPlugin.mouseLocked) return;
171 		currentTool.onTertiaryActionRelease();
172 	}
173 	void onRotateAction(string key) {
174 		if (!guiPlugin.mouseLocked) return;
175 		currentTool.onRotateAction();
176 	}
177 }