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