Added block breaking and refactored Controls
- Blocks can be broken by pointing at them at pressing LMB - Rewritten ControlTriggers - Rewritten KeyMatcher - CollisionPathComputer now has a 0.5 margin
This commit is contained in:
		| @@ -0,0 +1,48 @@ | ||||
| package ru.windcorp.progressia.client.comms.controls; | ||||
|  | ||||
| import java.util.function.BiConsumer; | ||||
| import java.util.function.Predicate; | ||||
|  | ||||
| import ru.windcorp.progressia.client.graphics.input.InputEvent; | ||||
| import ru.windcorp.progressia.common.comms.controls.ControlData; | ||||
| import ru.windcorp.progressia.common.comms.controls.ControlDataRegistry; | ||||
| import ru.windcorp.progressia.common.comms.controls.PacketControl; | ||||
| import ru.windcorp.progressia.common.util.namespaces.NamespacedUtil; | ||||
|  | ||||
| public class ControlTriggerLambda extends ControlTriggerInputBased { | ||||
| 	 | ||||
| 	private final String packetId; | ||||
| 	private final Predicate<InputEvent> predicate; | ||||
| 	private final BiConsumer<InputEvent, ControlData> dataWriter; | ||||
|  | ||||
| 	public ControlTriggerLambda( | ||||
| 			String id, | ||||
| 			Predicate<InputEvent> predicate, | ||||
| 			BiConsumer<InputEvent, ControlData> dataWriter | ||||
| 	) { | ||||
| 		super(id); | ||||
| 		 | ||||
| 		this.packetId = NamespacedUtil.getId( | ||||
| 				NamespacedUtil.getNamespace(id), | ||||
| 				"ControlKeyPress" + NamespacedUtil.getName(id) | ||||
| 		); | ||||
| 		 | ||||
| 		this.predicate = predicate; | ||||
| 		this.dataWriter = dataWriter; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public PacketControl onInputEvent(InputEvent event) { | ||||
| 		if (!predicate.test(event)) return null; | ||||
| 		 | ||||
| 		PacketControl packet = new PacketControl( | ||||
| 				packetId, | ||||
| 				ControlDataRegistry.getInstance().create(getId()) | ||||
| 		); | ||||
| 		 | ||||
| 		dataWriter.accept(event, packet.getControl()); | ||||
| 		 | ||||
| 		return packet; | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -1,40 +0,0 @@ | ||||
| package ru.windcorp.progressia.client.comms.controls; | ||||
|  | ||||
| import java.util.function.Predicate; | ||||
|  | ||||
| import ru.windcorp.progressia.client.graphics.input.InputEvent; | ||||
| import ru.windcorp.progressia.client.graphics.input.KeyEvent; | ||||
| import ru.windcorp.progressia.common.comms.controls.ControlDataRegistry; | ||||
| import ru.windcorp.progressia.common.comms.controls.PacketControl; | ||||
| import ru.windcorp.progressia.common.util.namespaces.NamespacedUtil; | ||||
|  | ||||
| public class ControlTriggerOnKeyPress extends ControlTriggerInputBased { | ||||
| 	 | ||||
| 	private final Predicate<KeyEvent> predicate; | ||||
| 	private final PacketControl packet; | ||||
|  | ||||
| 	public ControlTriggerOnKeyPress( | ||||
| 			String id, | ||||
| 			Predicate<KeyEvent> predicate | ||||
| 	) { | ||||
| 		super(id); | ||||
| 		this.predicate = predicate; | ||||
| 		this.packet = new PacketControl( | ||||
| 				NamespacedUtil.getId(getNamespace(), "ControlKeyPress" + getName()), | ||||
| 				ControlDataRegistry.getInstance().get(getId()) | ||||
| 		); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public PacketControl onInputEvent(InputEvent event) { | ||||
| 		if (!(event instanceof KeyEvent)) return null; | ||||
| 		 | ||||
| 		KeyEvent keyEvent = (KeyEvent) event; | ||||
| 		 | ||||
| 		if (!keyEvent.isPress()) return null; | ||||
| 		if (!predicate.test(keyEvent)) return null; | ||||
| 		 | ||||
| 		return packet; | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,176 @@ | ||||
| package ru.windcorp.progressia.client.comms.controls; | ||||
|  | ||||
| import java.util.function.BiConsumer; | ||||
| import java.util.function.Consumer; | ||||
| import java.util.function.Predicate; | ||||
|  | ||||
| import ru.windcorp.progressia.client.graphics.input.InputEvent; | ||||
| import ru.windcorp.progressia.common.comms.controls.ControlData; | ||||
|  | ||||
| public class ControlTriggers { | ||||
| 	 | ||||
| 	public static ControlTriggerInputBased of( | ||||
| 			String id, | ||||
| 			BiConsumer<InputEvent, ControlData> dataWriter, | ||||
| 			Predicate<InputEvent> predicate | ||||
| 	) { | ||||
| 		return new ControlTriggerLambda(id, predicate, dataWriter); | ||||
| 	} | ||||
| 	 | ||||
| 	public static ControlTriggerInputBased of( | ||||
| 			String id, | ||||
| 			Consumer<ControlData> dataWriter, | ||||
| 			Predicate<InputEvent> predicate | ||||
| 	) { | ||||
| 		return of( | ||||
| 				id, | ||||
| 				(input, control) -> dataWriter.accept(control), | ||||
| 				predicate | ||||
| 		); | ||||
| 	} | ||||
| 	 | ||||
| 	public static ControlTriggerInputBased of( | ||||
| 			String id, | ||||
| 			Predicate<InputEvent> predicate | ||||
| 	) { | ||||
| 		return of( | ||||
| 				id, | ||||
| 				(input, control) -> {}, | ||||
| 				predicate | ||||
| 		); | ||||
| 	} | ||||
| 	 | ||||
| 	@SafeVarargs | ||||
| 	public static <I extends InputEvent> ControlTriggerInputBased of( | ||||
| 			String id, | ||||
| 			Class<I> inputType, | ||||
| 			BiConsumer<I, ControlData> dataWriter, | ||||
| 			Predicate<I>... predicates | ||||
| 	) { | ||||
| 		return of( | ||||
| 				id, | ||||
| 				createCheckedDataWriter(inputType, dataWriter), | ||||
| 				createCheckedCompoundPredicate(inputType, predicates) | ||||
| 		); | ||||
| 	} | ||||
| 	 | ||||
| 	@SafeVarargs | ||||
| 	public static <I extends InputEvent> ControlTriggerInputBased of( | ||||
| 			String id, | ||||
| 			Class<I> inputType, | ||||
| 			Consumer<ControlData> dataWriter, | ||||
| 			Predicate<I>... predicates | ||||
| 	) { | ||||
| 		return of( | ||||
| 				id, | ||||
| 				inputType, | ||||
| 				(input, control) -> dataWriter.accept(control), | ||||
| 				predicates | ||||
| 		); | ||||
| 	} | ||||
| 	 | ||||
| 	@SafeVarargs | ||||
| 	public static <I extends InputEvent> ControlTriggerInputBased of( | ||||
| 			String id, | ||||
| 			Class<I> inputType, | ||||
| 			Predicate<I>... predicates | ||||
| 	) { | ||||
| 		return of( | ||||
| 				id, | ||||
| 				(input, control) -> {}, | ||||
| 				createCheckedCompoundPredicate(inputType, predicates) | ||||
| 		); | ||||
| 	} | ||||
| 	 | ||||
| 	@SafeVarargs | ||||
| 	public static ControlTriggerInputBased of( | ||||
| 			String id, | ||||
| 			BiConsumer<InputEvent, ControlData> dataWriter, | ||||
| 			Predicate<InputEvent>... predicates | ||||
| 	) { | ||||
| 		return of( | ||||
| 				id, | ||||
| 				InputEvent.class, | ||||
| 				dataWriter, | ||||
| 				predicates | ||||
| 		); | ||||
| 	} | ||||
| 	 | ||||
| 	@SafeVarargs | ||||
| 	public static <I extends InputEvent> ControlTriggerInputBased of( | ||||
| 			String id, | ||||
| 			Consumer<ControlData> dataWriter, | ||||
| 			Predicate<InputEvent>... predicates | ||||
| 	) { | ||||
| 		return of( | ||||
| 				id, | ||||
| 				(input, control) -> dataWriter.accept(control), | ||||
| 				predicates | ||||
| 		); | ||||
| 	} | ||||
| 	 | ||||
| 	@SafeVarargs | ||||
| 	public static ControlTriggerInputBased of( | ||||
| 			String id, | ||||
| 			Predicate<InputEvent>... predicates | ||||
| 	) { | ||||
| 		return of( | ||||
| 				id, | ||||
| 				InputEvent.class, | ||||
| 				(input, control) -> {}, | ||||
| 				predicates | ||||
| 		); | ||||
| 	} | ||||
|  | ||||
| 	private static | ||||
| 	<I extends InputEvent> | ||||
| 	BiConsumer<InputEvent, ControlData> | ||||
| 	createCheckedDataWriter( | ||||
| 			Class<I> inputType, | ||||
| 			BiConsumer<I, ControlData> dataWriter | ||||
| 	) { | ||||
| 		return (inputEvent, control) -> dataWriter.accept(inputType.cast(inputEvent), control); | ||||
| 	} | ||||
| 	 | ||||
| 	private static | ||||
| 	<I extends InputEvent> | ||||
| 	Predicate<InputEvent> | ||||
| 	createCheckedCompoundPredicate( | ||||
| 			Class<I> inputType, | ||||
| 			Predicate<I>[] predicates | ||||
| 	) { | ||||
| 		return new CompoundCastPredicate<>(inputType, predicates); | ||||
| 	} | ||||
| 	 | ||||
| 	private static class CompoundCastPredicate<I extends InputEvent> implements Predicate<InputEvent> { | ||||
| 		 | ||||
| 		private final Class<I> inputType; | ||||
| 		private final Predicate<I>[] predicates; | ||||
| 		 | ||||
| 		public CompoundCastPredicate(Class<I> inputType, Predicate<I>[] predicates) { | ||||
| 			this.inputType = inputType; | ||||
| 			this.predicates = predicates; | ||||
| 		} | ||||
|  | ||||
| 		@Override | ||||
| 		public boolean test(InputEvent inputEvent) { | ||||
| 			if (!inputType.isInstance(inputEvent)) { | ||||
| 				return false; | ||||
| 			} | ||||
| 			 | ||||
| 			I castEvent = inputType.cast(inputEvent); | ||||
| 			 | ||||
| 			for (Predicate<I> predicate : predicates) { | ||||
| 				if (!predicate.test(castEvent)) { | ||||
| 					return false; | ||||
| 				} | ||||
| 			} | ||||
| 			 | ||||
| 			return true; | ||||
| 		} | ||||
| 		 | ||||
| 	} | ||||
|  | ||||
| 	private ControlTriggers() {} | ||||
|  | ||||
| } | ||||
| @@ -17,46 +17,24 @@ | ||||
|  *******************************************************************************/ | ||||
| package ru.windcorp.progressia.client.graphics.input; | ||||
|  | ||||
| import gnu.trove.set.TIntSet; | ||||
| import ru.windcorp.progressia.client.graphics.backend.InputTracker; | ||||
| import java.util.function.Predicate; | ||||
|  | ||||
| import org.lwjgl.glfw.GLFW; | ||||
|  | ||||
| public class KeyMatcher { | ||||
|  | ||||
| 	private final int key; | ||||
| 	private final int[] additionalKeys; | ||||
| 	private final int mods; | ||||
| 	 | ||||
| 	public KeyMatcher(int key, int[] additionalKeys, int mods) { | ||||
| 	protected KeyMatcher(int key, int mods) { | ||||
| 		this.key = key; | ||||
| 		this.additionalKeys = additionalKeys; | ||||
| 		this.mods = mods; | ||||
| 	} | ||||
|  | ||||
| 	public KeyMatcher(KeyEvent template, int... additionalKeys) { | ||||
| 		this(template.getKey(), additionalKeys, template.getMods()); | ||||
| 	} | ||||
| 	 | ||||
| 	public static KeyMatcher createKeyMatcher(KeyEvent template) { | ||||
| 		return new KeyMatcher( | ||||
| 				template, | ||||
| 				InputTracker.getPressedKeys().toArray() | ||||
| 		); | ||||
| 	} | ||||
|  | ||||
| 	public boolean matches(KeyEvent event) { | ||||
| 		if (!event.isPress()) return false; | ||||
| 		if (event.getKey() != getKey()) return false; | ||||
| 		if (event.getMods() != getMods()) return false; | ||||
| 		 | ||||
| 		TIntSet pressedKeys = InputTracker.getPressedKeys(); | ||||
| 		 | ||||
| 		if (pressedKeys.size() != additionalKeys.length) return false; | ||||
| 		 | ||||
| 		for (int additionalKey : additionalKeys) { | ||||
| 			if (!pressedKeys.contains(additionalKey)) { | ||||
| 				return false; | ||||
| 			} | ||||
| 		} | ||||
| 		if ((event.getMods() & getMods()) != getMods()) return false; | ||||
| 		 | ||||
| 		return true; | ||||
| 	} | ||||
| @@ -65,12 +43,52 @@ public class KeyMatcher { | ||||
| 		return key; | ||||
| 	} | ||||
| 	 | ||||
| 	public int[] getAdditionalKeys() { | ||||
| 		return additionalKeys; | ||||
| 	} | ||||
| 	 | ||||
| 	public int getMods() { | ||||
| 		return mods; | ||||
| 	} | ||||
| 	 | ||||
| 	public static KeyMatcher.Builder of(int key) { | ||||
| 		return new KeyMatcher.Builder(key); | ||||
| 	} | ||||
| 	 | ||||
| 	public static class Builder { | ||||
| 		 | ||||
| 		private final int key; | ||||
| 		private int mods = 0; | ||||
| 		 | ||||
| 		public Builder(int key) { | ||||
| 			this.key = key; | ||||
| 		} | ||||
| 		 | ||||
| 		public Builder with(int modifier) { | ||||
| 			this.mods += modifier; | ||||
| 			return this; | ||||
| 		} | ||||
| 		 | ||||
| 		public Builder withShift() { | ||||
| 			return with(GLFW.GLFW_MOD_SHIFT); | ||||
| 		} | ||||
| 		 | ||||
| 		public Builder withCtrl() { | ||||
| 			return with(GLFW.GLFW_MOD_CONTROL); | ||||
| 		} | ||||
| 		 | ||||
| 		public Builder withAlt() { | ||||
| 			return with(GLFW.GLFW_MOD_ALT); | ||||
| 		} | ||||
| 		 | ||||
| 		public Builder withSuper() { | ||||
| 			return with(GLFW.GLFW_MOD_SUPER); | ||||
| 		} | ||||
| 		 | ||||
| 		public KeyMatcher build() { | ||||
| 			return new KeyMatcher(key, mods); | ||||
| 		} | ||||
| 		 | ||||
| 		public Predicate<KeyEvent> matcher() { | ||||
| 			return build()::matches; | ||||
| 		} | ||||
| 		 | ||||
| 	} | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -10,6 +10,8 @@ import static java.lang.Math.*; | ||||
|  | ||||
| public class CollisionPathComputer { | ||||
| 	 | ||||
| 	private static final float PADDING = 0.5f; | ||||
| 	 | ||||
| 	public static void forEveryBlockInCollisionPath( | ||||
| 			Collideable coll, | ||||
| 			float maxTime, | ||||
| @@ -52,18 +54,18 @@ public class CollisionPathComputer { | ||||
| 		Vec3i pos = Vectors.grab3i(); | ||||
| 		 | ||||
| 		for ( | ||||
| 				pos.x =  (int) floor(origin.x + min(0, size.x) + min(0, displacement.x)); | ||||
| 				pos.x <= (int)  ceil(origin.x + max(0, size.x) + max(0, displacement.x)); | ||||
| 				pos.x =  (int) floor(origin.x + min(0, size.x) + min(0, displacement.x) - PADDING); | ||||
| 				pos.x <= (int)  ceil(origin.x + max(0, size.x) + max(0, displacement.x) + PADDING); | ||||
| 				pos.x += 1 | ||||
| 		) { | ||||
| 			for ( | ||||
| 					pos.y =  (int) floor(origin.y + min(0, size.y) + min(0, displacement.y)); | ||||
| 					pos.y <= (int)  ceil(origin.y + max(0, size.y) + max(0, displacement.y)); | ||||
| 					pos.y =  (int) floor(origin.y + min(0, size.y) + min(0, displacement.y) - PADDING); | ||||
| 					pos.y <= (int)  ceil(origin.y + max(0, size.y) + max(0, displacement.y) + PADDING); | ||||
| 					pos.y += 1 | ||||
| 			) { | ||||
| 				for ( | ||||
| 						pos.z =  (int) floor(origin.z + min(0, size.z) + min(0, displacement.z)); | ||||
| 						pos.z <= (int)  ceil(origin.z + max(0, size.z) + max(0, displacement.z)); | ||||
| 						pos.z =  (int) floor(origin.z + min(0, size.z) + min(0, displacement.z) - PADDING); | ||||
| 						pos.z <= (int)  ceil(origin.z + max(0, size.z) + max(0, displacement.z) + PADDING); | ||||
| 						pos.z += 1 | ||||
| 				) { | ||||
| 					action.accept(pos); | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| package ru.windcorp.progressia.common.comms.controls; | ||||
|  | ||||
| import ru.windcorp.progressia.common.util.namespaces.NamespacedInstanceRegistry; | ||||
| import ru.windcorp.progressia.common.util.namespaces.NamespacedFactoryRegistry; | ||||
|  | ||||
| public class ControlDataRegistry extends NamespacedInstanceRegistry<ControlData> { | ||||
| public class ControlDataRegistry extends NamespacedFactoryRegistry<ControlData> { | ||||
| 	 | ||||
| 	private static final ControlDataRegistry INSTANCE = new ControlDataRegistry(); | ||||
| 	 | ||||
|   | ||||
| @@ -7,6 +7,15 @@ import ru.windcorp.progressia.server.comms.Client; | ||||
|  | ||||
| public abstract class ControlLogic extends Namespaced { | ||||
| 	 | ||||
| 	@FunctionalInterface | ||||
| 	public static interface Lambda { | ||||
| 		void apply( | ||||
| 				Server server, | ||||
| 				PacketControl packet, | ||||
| 				Client client | ||||
| 		); | ||||
| 	} | ||||
|  | ||||
| 	public ControlLogic(String id) { | ||||
| 		super(id); | ||||
| 	} | ||||
| @@ -17,4 +26,13 @@ public abstract class ControlLogic extends Namespaced { | ||||
| 			Client client | ||||
| 	); | ||||
| 	 | ||||
| 	public static ControlLogic of(String id, Lambda logic) { | ||||
| 		return new ControlLogic(id) { | ||||
| 			@Override | ||||
| 			public void apply(Server server, PacketControl packet, Client client) { | ||||
| 				logic.apply(server, packet, client); | ||||
| 			} | ||||
| 		}; | ||||
| 	} | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,22 @@ | ||||
| package ru.windcorp.progressia.test; | ||||
|  | ||||
| import glm.vec._3.i.Vec3i; | ||||
| import ru.windcorp.progressia.common.comms.controls.ControlData; | ||||
|  | ||||
| public class ControlBreakBlockData extends ControlData { | ||||
| 	 | ||||
| 	private final Vec3i blockInWorld = new Vec3i(); | ||||
|  | ||||
| 	public ControlBreakBlockData(String id) { | ||||
| 		super(id); | ||||
| 	} | ||||
| 	 | ||||
| 	public Vec3i getBlockInWorld() { | ||||
| 		return blockInWorld; | ||||
| 	} | ||||
| 	 | ||||
| 	public void setBlockInWorld(Vec3i blockInWorld) { | ||||
| 		this.blockInWorld.set(blockInWorld.x, blockInWorld.y, blockInWorld.z); | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -8,8 +8,11 @@ import java.util.function.Consumer; | ||||
| import org.lwjgl.glfw.GLFW; | ||||
|  | ||||
| import glm.vec._3.i.Vec3i; | ||||
| import ru.windcorp.progressia.client.ClientState; | ||||
| import ru.windcorp.progressia.client.comms.controls.*; | ||||
| import ru.windcorp.progressia.client.graphics.input.KeyEvent; | ||||
| import ru.windcorp.progressia.client.graphics.input.KeyMatcher; | ||||
| import ru.windcorp.progressia.client.graphics.world.LocalPlayer; | ||||
| import ru.windcorp.progressia.client.world.block.*; | ||||
| import ru.windcorp.progressia.client.world.entity.*; | ||||
| import ru.windcorp.progressia.client.world.tile.*; | ||||
| @@ -21,8 +24,6 @@ import ru.windcorp.progressia.common.world.ChunkData; | ||||
| import ru.windcorp.progressia.common.world.block.*; | ||||
| import ru.windcorp.progressia.common.world.entity.*; | ||||
| import ru.windcorp.progressia.common.world.tile.*; | ||||
| import ru.windcorp.progressia.server.Server; | ||||
| import ru.windcorp.progressia.server.comms.Client; | ||||
| import ru.windcorp.progressia.server.comms.controls.*; | ||||
| import ru.windcorp.progressia.server.world.block.*; | ||||
| import ru.windcorp.progressia.server.world.entity.*; | ||||
| @@ -88,7 +89,7 @@ public class TestContent { | ||||
|  | ||||
| 	private static void registerEntities() { | ||||
| 		float scale = 1.8f / 8; | ||||
| 		registerEntityData("Test:Player", e -> e.setCollisionModel(new AABB(0, 0, 4*scale, 0.75f, 0.75f, 1.8f))); | ||||
| 		registerEntityData("Test:Player", e -> e.setCollisionModel(new AABB(0, 0, 4*scale, 0.8f, 0.8f, 1.8f))); | ||||
| 		register(new TestEntityRenderHuman("Test:Player")); | ||||
| 		register(new EntityLogic("Test:Player")); | ||||
| 		 | ||||
| @@ -98,25 +99,43 @@ public class TestContent { | ||||
| 	} | ||||
|  | ||||
| 	private static void regsiterControls() { | ||||
| 		ControlDataRegistry.getInstance().register(new ControlData("Test:Switch000")); | ||||
| 		ControlTriggerRegistry.getInstance().register(new ControlTriggerOnKeyPress("Test:Switch000", new KeyMatcher(GLFW.GLFW_KEY_H, new int[0], 0)::matches)); | ||||
| 		ControlLogicRegistry.getInstance().register(new ControlLogic("Test:Switch000") { | ||||
| 			@Override | ||||
| 			public void apply(Server server, PacketControl packet, Client client) { | ||||
| 				Vec3i z000 = new Vec3i(0, 0, 0); | ||||
| 		ControlDataRegistry data = ControlDataRegistry.getInstance(); | ||||
| 		ControlTriggerRegistry triggers = ControlTriggerRegistry.getInstance(); | ||||
| 		ControlLogicRegistry logic = ControlLogicRegistry.getInstance(); | ||||
| 		 | ||||
| 				ChunkData data = server.getWorld().getChunk(z000).getData(); | ||||
| 		data.register("Test:Switch000", ControlData::new); | ||||
| 		triggers.register(ControlTriggers.of( | ||||
| 				"Test:Switch000", | ||||
| 				KeyEvent.class, | ||||
| 				KeyMatcher.of(GLFW.GLFW_KEY_H).matcher() | ||||
| 		)); | ||||
| 		logic.register(ControlLogic.of("Test:Switch000", (server, packet, client) -> { | ||||
| 			Vec3i z000 = new Vec3i(0, 0, 0); | ||||
| 			 | ||||
| 				BlockData block; | ||||
| 				if (data.getBlock(z000).getId().equals("Test:Stone")) { | ||||
| 					block = BlockDataRegistry.getInstance().get("Test:Glass"); | ||||
| 				} else { | ||||
| 					block = BlockDataRegistry.getInstance().get("Test:Stone"); | ||||
| 				} | ||||
| 			ChunkData chunk = server.getWorld().getChunk(z000).getData(); | ||||
| 			 | ||||
| 				server.getAdHocChanger().setBlock(z000, block); | ||||
| 			BlockData block; | ||||
| 			if (chunk.getBlock(z000).getId().equals("Test:Stone")) { | ||||
| 				block = BlockDataRegistry.getInstance().get("Test:Glass"); | ||||
| 			} else { | ||||
| 				block = BlockDataRegistry.getInstance().get("Test:Stone"); | ||||
| 			} | ||||
| 		}); | ||||
| 			 | ||||
| 			server.getAdHocChanger().setBlock(z000, block); | ||||
| 		})); | ||||
| 		 | ||||
| 		data.register("Test:BreakBlock", ControlBreakBlockData::new); | ||||
| 		triggers.register(ControlTriggers.of( | ||||
| 				"Test:BreakBlock", | ||||
| 				KeyEvent.class, | ||||
| 				TestContent::onBlockBreakTrigger, | ||||
| 				KeyMatcher.of(GLFW.GLFW_MOUSE_BUTTON_LEFT).matcher(), | ||||
| 				i -> getLookingAt() != null | ||||
| 		)); | ||||
| 		logic.register(ControlLogic.of("Test:BreakBlock", (server, packet, client) -> { | ||||
| 			Vec3i blockInWorld = ((ControlBreakBlockData) packet.getControl()).getBlockInWorld(); | ||||
| 			server.getAdHocChanger().setBlock(blockInWorld, BlockDataRegistry.getInstance().get("Test:Air")); | ||||
| 		})); | ||||
| 	} | ||||
| 	 | ||||
| 	private static void register(BlockData x) { | ||||
| @@ -172,4 +191,18 @@ public class TestContent { | ||||
| 		EntityLogicRegistry.getInstance().register(x); | ||||
| 	} | ||||
| 	 | ||||
| 	private static Vec3i getLookingAt() { | ||||
| 		ru.windcorp.progressia.client.Client client = ClientState.getInstance(); | ||||
| 		if (client == null) return null; | ||||
| 		 | ||||
| 		LocalPlayer player = client.getLocalPlayer(); | ||||
| 		if (player == null) return null; | ||||
| 		 | ||||
| 		return player.getLookingAt(); | ||||
| 	} | ||||
| 	 | ||||
| 	private static void onBlockBreakTrigger(ControlData control) { | ||||
| 		((ControlBreakBlockData) control).setBlockInWorld(getLookingAt()); | ||||
| 	} | ||||
|  | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user