diff --git a/common/src/main/java/com/specialeffect/eyemine/EyeMineClient.java b/common/src/main/java/com/specialeffect/eyemine/EyeMineClient.java index 51a88d9..25a5f1f 100644 --- a/common/src/main/java/com/specialeffect/eyemine/EyeMineClient.java +++ b/common/src/main/java/com/specialeffect/eyemine/EyeMineClient.java @@ -34,6 +34,7 @@ import com.specialeffect.eyemine.submod.movement.Swim; import com.specialeffect.eyemine.submod.utils.DebugAverageFps; import me.shedaniel.architectury.event.events.GuiEvent; +import com.specialeffect.eyemine.submod.survival.AutoAim; import me.shedaniel.architectury.event.events.client.ClientLifecycleEvent; import me.shedaniel.architectury.event.events.client.ClientRawInputEvent; import me.shedaniel.architectury.registry.KeyBindings; @@ -49,7 +50,7 @@ public class EyeMineClient { public static boolean disableCustomNewWorld = false; public static void init() { - //Initialize the first StateOverlay + // Initialize the first StateOverlay MainClientHandler.initialize(); // Setup all other sub mods @@ -60,8 +61,8 @@ public static void init() { ClientRawInputEvent.KEY_PRESSED.register(CreativeClientHelper::onKeyInput); ClientLifecycleEvent.CLIENT_SETUP.register((state) -> { - if(!Keybindings.keybindings.isEmpty()) { - for(KeyMapping keyBinding : Keybindings.keybindings) { + if (!Keybindings.keybindings.isEmpty()) { + for (KeyMapping keyBinding : Keybindings.keybindings) { KeyBindings.registerKeyBinding(keyBinding); } } @@ -102,6 +103,7 @@ private static void instantiateSubMods() { setupSubMod(new IronSights()); setupSubMod(new NightVisionHelper()); setupSubMod(new CountBlocks()); + setupSubMod(new AutoAim()); } private static void setupSubMod(SubMod mod) { @@ -113,7 +115,7 @@ public static void refresh() { if (setupComplete) { for (SubMod child : subModList) { if (child instanceof IConfigListener) { - IConfigListener configListener = (IConfigListener)child; + IConfigListener configListener = (IConfigListener) child; configListener.syncConfig(); } } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/building/CountBlocks.java b/common/src/main/java/com/specialeffect/eyemine/submod/building/CountBlocks.java index 2f0c818..e4446e4 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/building/CountBlocks.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/building/CountBlocks.java @@ -1,3 +1,18 @@ +/** +* Copyright (C) 2016-2020 Kirsty McNaught +* +* Developed for SpecialEffect, www.specialeffect.org.uk +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 3 +* of the License, or (at your option) any later version. +* +* This class control counting blocks +* +* @author Kirsty McNaught and Becky Tyler +* @version 1.0 +*/ package com.specialeffect.eyemine.submod.building; import com.specialeffect.eyemine.client.Keybindings; @@ -5,7 +20,11 @@ import com.specialeffect.utils.ModUtils; import com.specialeffect.eyemine.mixin.KeyMappingAccessor; +import java.rmi.server.Skeleton; +import java.util.ArrayList; import java.util.List; +import java.util.function.Predicate; +import java.util.function.Predicate; import com.mojang.blaze3d.platform.InputConstants; import com.mojang.blaze3d.platform.InputConstants.Type; @@ -13,56 +32,119 @@ import org.lwjgl.glfw.GLFW; import me.shedaniel.architectury.event.events.client.ClientRawInputEvent; +import me.shedaniel.architectury.event.events.client.ClientTickEvent; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.player.LocalPlayer; import net.minecraft.core.BlockPos; import net.minecraft.world.InteractionResult; +import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.targeting.TargetingConditions; +import net.minecraft.world.entity.monster.Creeper; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.Vec3; import me.shedaniel.architectury.event.events.GuiEvent; +import me.shedaniel.architectury.event.events.EntityEvent.LivingAttack; import me.shedaniel.architectury.event.events.BlockEvent; - +import me.shedaniel.architectury.event.events.EntityEvent; public class CountBlocks extends SubMod { - public final String MODID = "countblocks"; // this needs to be a unique ID + public final String MODID = "countblocks"; // this needs to be a unique ID // Member variables we need // - a static KeyMapping for the shortcut key + public static KeyMapping mNumberBlockKB; + // - a list of BlockPos positions for all the blocks we are tracking + public ArrayList blockPosList; + // - a boolean indicating whether we are currently counting blocks + public boolean countingBlocks; + + public void onInitializeClient() { - public void onInitializeClient() { + // Create the list of BlockPos positions + blockPosList = new ArrayList(); - // TODO: Register the key binding here - // by adding to Keybindings.keybindings and + // Initialise the countingBlocks flag + countingBlocks = false; + + // Register the key binding here + Keybindings.keybindings.add(mNumberBlockKB = new KeyMapping( + "Number_Block", // this needs to be a unique name + Type.KEYSYM, // this is always KEYSYM + GLFW.GLFW_KEY_K, // this selects the default key. try autocompleting GLFW.GLFW_KEY... to see more + // options + "category.eyemine.category.eyegaze_common" // this sets the translation key for the name of the category + // in the controls list + // (we use eyegaze_common, eyegaze_extra and eyegaze_settings + // depending on the mod) + )); + + // by adding to Keybindings.keybindings and // registering function with ClientRawInputEvent.Key_PRESSED // (look at PickBlock class for reference) + ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); // Register the "place block" event BlockEvent.PLACE.register(this::onPlaceBlock); + } - private InteractionResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { + private InteractionResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { // This method gets called when *any* key is pressed // Skip if there is a GUI visible - if (ModUtils.hasActiveGui()) { return InteractionResult.PASS; } + if (ModUtils.hasActiveGui()) { + return InteractionResult.PASS; + } // Skip if F3 is held down (this is used for debugging) - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { return InteractionResult.PASS; } - - ModUtils.sendPlayerMessage("Key pressed: " + keyCode); - - // TODO: add if statement for if the key pressed is the one we are using. - // Inside the if statement we will need to - // - turn counting on or off - // - empty the list of blocks - - return InteractionResult.PASS; + if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + return InteractionResult.PASS; + } + + // If statement for when the key pressed is the one we are using. + // Inside the if statement we will need to + // - turn counting on or off + // - empty the list of blocks + if (mNumberBlockKB.matches(keyCode, scanCode) && mNumberBlockKB.consumeClick()) { + ModUtils.sendPlayerMessage("Key pressed: " + keyCode); + + // Toggle the value of countingBlocks + countingBlocks = !countingBlocks; + + // Clear the list of BlockPos positions + blockPosList.clear(); + + } + return InteractionResult.PASS; } - + + /** + * Whenever a block is placed, send a chat message with the position of the + * block + * + * @param l The level the block is being placed in + * @param position The position of the block that was placed + * @param state The block state of the block being placed + * @param entity The entity that placed the block. + * @return The return value is an InteractionResult. This is a value that tells + * the game what to do + * with the block. + */ public InteractionResult onPlaceBlock(Level l, BlockPos position, BlockState state, Entity entity) { + // Add block's position to list of block positions + blockPosList.add(position); + + // Send a chat message showing position and number of blocks placed + ModUtils.sendPlayerMessage("Block " + blockPosList.size() + " placed at " + position); // for debugging + // This method is called whenever a block is placed return InteractionResult.PASS; } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/survival/AutoAim.java b/common/src/main/java/com/specialeffect/eyemine/submod/survival/AutoAim.java new file mode 100644 index 0000000..03bb0d3 --- /dev/null +++ b/common/src/main/java/com/specialeffect/eyemine/submod/survival/AutoAim.java @@ -0,0 +1,206 @@ +/** +* Copyright (C) 2016-2020 Kirsty McNaught +* +* Developed for SpecialEffect, www.specialeffect.org.uk +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 3 +* of the License, or (at your option) any later version. +* +* This class control autoAim +* +* @author Kirsty McNaught and Becky Tyler +* @version 1.0 +*/ +package com.specialeffect.eyemine.submod.survival; + +import com.specialeffect.eyemine.client.Keybindings; +import com.specialeffect.eyemine.submod.SubMod; +import com.specialeffect.utils.ModUtils; +import java.util.function.Predicate; +import com.mojang.blaze3d.platform.InputConstants; +import com.mojang.blaze3d.platform.InputConstants.Type; + +import org.lwjgl.glfw.GLFW; + +import me.shedaniel.architectury.event.events.client.ClientRawInputEvent; +import me.shedaniel.architectury.event.events.client.ClientTickEvent; +import net.minecraft.client.KeyMapping; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.targeting.TargetingConditions; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.phys.Vec3; +import me.shedaniel.architectury.event.events.EntityEvent; + +public class AutoAim extends SubMod { + public final String MODID = "autoAim"; // this needs to be a unique ID + + // Member variables we need + // - a static KeyMapping for the shortcut key + public static KeyMapping mAutoAimKB; + + private LivingEntity nearEntity; + private LivingEntity targetEntity = null; + + /** + * We register the keybinding, register the key input event, register the living + * attack event, and + * register the client tick event + */ + public void onInitializeClient() { + + // Register the key binding here + Keybindings.keybindings.add(mAutoAimKB = new KeyMapping( + "Auto Aim", // this needs to be a unique name + Type.KEYSYM, // this is always KEYSYM + GLFW.GLFW_KEY_O, // this selects the default key. try autocompleting GLFW.GLFW_KEY... to see more + // options + "category.eyemine.category.eyegaze_common" // this sets the translation key for the name of the category + // in the controls list + // (we use eyegaze_common, eyegaze_extra and eyegaze_settings + // depending on the mod) + )); + + // by adding to Keybindings.keybindings and + // registering function with ClientRawInputEvent.Key_PRESSED + // (look at PickBlock class for reference) + ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); + + // Register the LivingHurt and LivingAttack events + EntityEvent.LIVING_ATTACK.register(this::onLivingAttack); + + ClientTickEvent.CLIENT_PRE.register(this::onClientTick); + + } + + /** + * This method cheques weather the player is being attacked + * + * @param entity The entity that was attacked + * @param damageSource The source of the damage. + * @param amount The amount of damage that was dealt + * @return The return value is an InteractionResult. + */ + public InteractionResult onLivingAttack(LivingEntity entity, DamageSource damageSource, float amount) { + + // If entity is a LocalPlayer then it is us being attacked + // The damage source is sometimes "DamageSource (generic)" or Damage Source + // (magic) or sometimes an + // EntityDamageSource like "Arrow" which has a position we can query + // The number is probably an amount of damage + if (entity instanceof LocalPlayer) { + System.out.println(entity + " " + damageSource + " " + amount); + LocalPlayer player = (LocalPlayer) entity; + this.findClosestEntity(player); + nearEntity = this.findClosestEntity(player); + Vec3 pos = nearEntity.position(); + + } + return null; + } + + /** + * Find the closest entity to the player that is not the player + * + * @param player The player that is using the aimbot + * @return The closest entity to the player. + */ + private LivingEntity findClosestEntity(Player player) { + Minecraft minecraft = Minecraft.getInstance(); + ClientLevel level = minecraft.level; + + Predicate predicate = i -> !(i.equals(player)); + TargetingConditions conditions = new TargetingConditions(); + conditions.selector(predicate); + + return level.getNearestEntity(LivingEntity.class, conditions, player, + player.getX(), player.getY(), player.getZ(), + player.getBoundingBox().inflate(10)); + + } + + /** + * If the key is pressed, find the closest entity to the player and set it as + * the target entity + * + * @param minecraft The Minecraft instance + * @param keyCode The key code of the key that was pressed. + * @param scanCode The scan code of the key that was pressed. + * @param action 0 = key down, 1 = key up, 2 = repeat + * @param modifiers + * @return The InteractionResult.PASS is being returned. + */ + private InteractionResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { + // This method gets called when *any* key is pressed + + // Skip if there is a GUI visible + if (ModUtils.hasActiveGui()) { + return InteractionResult.PASS; + } + + // Skip if F3 is held down (this is used for debugging) + if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + return InteractionResult.PASS; + } + + // If statement for when the key pressed is the one we are using. + // Inside the if statement we will need to + // - turn counting on or off + // - empty the list of blocks + if (mAutoAimKB.matches(keyCode, scanCode) && mAutoAimKB.consumeClick()) { + ModUtils.sendPlayerMessage("Key pressed: " + keyCode); + + nearEntity = this.findClosestEntity(minecraft.player); + targetEntity = nearEntity; + + } + return InteractionResult.PASS; + } + + /** + * It finds the closest entity to the player, and then turns the player to face + * it + * + * @param event The event that was fired. + */ + public void onClientTick(Minecraft event) { + + if (targetEntity == null) { + System.out.println("can't find entitys"); + return; + } + + Minecraft minecraft = Minecraft.getInstance(); + LocalPlayer player = minecraft.player; + float playerYaw = player.yRot; + Vec3 playerPos = player.position(); + + Vec3 entityPos = targetEntity.position(); + + Vec3 targetDirection = playerPos.subtract(entityPos); + double xDiff = targetDirection.x; + double zDiff = targetDirection.z; + double targetYaw = Math.atan2(zDiff, xDiff); // in radians + targetYaw = targetYaw * 360 / (2 * Math.PI) + 90; + double turnYaw = targetYaw - playerYaw; // possibly out by 90 degrees?? + + System.out.println( + targetEntity.getType().getDescriptionId() + " " + entityPos + "(player at " + playerPos + ")"); + System.out.println(playerYaw + " " + targetYaw + " " + turnYaw); + + System.out.println(findClosestEntity(minecraft.player)); + minecraft.player.turn(turnYaw, 0.0); + + // Turn off once we are facing entity + if (Math.abs(turnYaw) < 1.0) { + targetEntity = null; + } + + } +}