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 }