-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from N3ROO/MC_1.16.1_dev
Version 1.0.0 for Minecraft 1.16.1
- Loading branch information
Showing
15 changed files
with
756 additions
and
19 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
## Version 1.0.0 | ||
|
||
**Core:** | ||
- Aim assistance for mobs (while fighting) | ||
- Aim assistance for blocks (while mining) | ||
|
||
**Settings:** | ||
- Aim force customizable (0.1 -> 10.0) | ||
- Assistance on mobs (on/off) | ||
- Assistance on blocks (on/off) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 38 additions & 6 deletions
44
src/main/java/dev/nero/aimassistance/AimAssistanceMod.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,71 @@ | ||
package dev.nero.aimassistance; | ||
|
||
import net.minecraft.client.Minecraft; | ||
import dev.nero.aimassistance.config.Config; | ||
import dev.nero.aimassistance.module.AimAssistance; | ||
import dev.nero.aimassistance.utils.Wrapper; | ||
import net.minecraftforge.common.MinecraftForge; | ||
import net.minecraftforge.event.TickEvent; | ||
import net.minecraftforge.eventbus.api.SubscribeEvent; | ||
import net.minecraftforge.fml.ModLoadingContext; | ||
import net.minecraftforge.fml.common.Mod; | ||
import net.minecraftforge.fml.config.ModConfig; | ||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; | ||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; | ||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
|
||
// The value here should match an entry in the META-INF/mods.toml file | ||
@Mod("aimassistancemod") | ||
@Mod(AimAssistanceMod.MODID) | ||
public class AimAssistanceMod | ||
{ | ||
// Directly reference a log4j logger. | ||
private static final Logger LOGGER = LogManager.getLogger(); | ||
|
||
public static final String MODID = "aimassistancemod"; | ||
private AimAssistance aimAssistance; | ||
|
||
public AimAssistanceMod() { | ||
// Register the setup method for modloading | ||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup); | ||
|
||
// Register ourselves for server and other game events we are interested in | ||
MinecraftForge.EVENT_BUS.register(this); | ||
|
||
// Register config | ||
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, Config.CLIENT_SPEC); | ||
} | ||
|
||
private void setup(final FMLCommonSetupEvent event) | ||
{ | ||
private void setup(final FMLCommonSetupEvent event) { | ||
LOGGER.info("Init"); | ||
aimAssistance = new AimAssistance(); | ||
Config.bakeConfig(); // init config values | ||
} | ||
|
||
@SubscribeEvent | ||
public void onModConfigEvent(final ModConfig.ModConfigEvent configEvent) { | ||
if (configEvent.getConfig().getSpec() == Config.CLIENT_SPEC) { | ||
Config.bakeConfig(); // update the values | ||
} | ||
} | ||
|
||
@SubscribeEvent | ||
public void onPlayerTick(TickEvent.PlayerTickEvent playerTickEvent) { | ||
if (Wrapper.playerPlaying()) { | ||
aimAssistance.analyseBehaviour(); | ||
} | ||
} | ||
|
||
@SubscribeEvent | ||
public void onClientTick(TickEvent.ClientTickEvent clientTickEvent) { | ||
if (Wrapper.playerPlaying()) { | ||
aimAssistance.analyseEnvironment(); | ||
} | ||
} | ||
|
||
@SubscribeEvent | ||
public void onRender(TickEvent.RenderTickEvent renderTickEvent) { | ||
if (Minecraft.getInstance().player != null) { | ||
// The user is playing | ||
if (Wrapper.playerPlaying()) { | ||
aimAssistance.assistIfPossible(); | ||
} | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
src/main/java/dev/nero/aimassistance/config/ClientConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package dev.nero.aimassistance.config; | ||
|
||
import dev.nero.aimassistance.AimAssistanceMod; | ||
import net.minecraftforge.common.ForgeConfigSpec; | ||
|
||
public class ClientConfig { | ||
|
||
public final ForgeConfigSpec.DoubleValue aimForce; | ||
public final ForgeConfigSpec.BooleanValue aimMobs; | ||
public final ForgeConfigSpec.BooleanValue aimBlocks; | ||
|
||
public ClientConfig(ForgeConfigSpec.Builder builder) { | ||
|
||
builder.push("Aim assistance"); // Category | ||
|
||
aimForce = builder | ||
.comment("What should be the force of the aim assistance?") | ||
.translation(AimAssistanceMod.MODID + ".config." + "aimForce") | ||
.defineInRange("aimForce", 5.0, 0.1, 10.0); | ||
|
||
aimMobs = builder | ||
.comment("Should the aim assistance be activated for mobs?") | ||
.translation(AimAssistanceMod.MODID + ".config." + "aimMobs") | ||
.define("aimMobs", true); | ||
|
||
aimBlocks = builder | ||
.comment("Should the aim assistance be activated for blocks?") | ||
.translation(AimAssistanceMod.MODID + ".config." + "aimBlocks") | ||
.define("aimBlocks", true); | ||
|
||
builder.pop(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package dev.nero.aimassistance.config; | ||
|
||
import net.minecraftforge.common.ForgeConfigSpec; | ||
import org.apache.commons.lang3.tuple.Pair; | ||
|
||
public class Config { | ||
|
||
public static final ClientConfig CLIENT; | ||
public static final ForgeConfigSpec CLIENT_SPEC; | ||
static { | ||
final Pair<ClientConfig, ForgeConfigSpec> specPair = new ForgeConfigSpec.Builder().configure(ClientConfig::new); | ||
CLIENT_SPEC = specPair.getRight(); | ||
CLIENT = specPair.getLeft(); | ||
} | ||
|
||
private static double aimForce; | ||
private static boolean aimMobs; | ||
private static boolean aimBlocks; | ||
|
||
public static void bakeConfig() { | ||
aimForce = CLIENT.aimForce.get(); | ||
aimMobs = CLIENT.aimMobs.get(); | ||
aimBlocks = CLIENT.aimBlocks.get(); | ||
} | ||
|
||
public static double getAimForce() { | ||
return aimForce; | ||
} | ||
|
||
public static boolean isAimMobs() { | ||
return aimMobs; | ||
} | ||
|
||
public static boolean isAimBlocks() { | ||
return aimBlocks; | ||
} | ||
} |
184 changes: 184 additions & 0 deletions
184
src/main/java/dev/nero/aimassistance/module/AimAssistance.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
package dev.nero.aimassistance.module; | ||
|
||
import dev.nero.aimassistance.config.Config; | ||
import dev.nero.aimassistance.utils.TimeHelper; | ||
import dev.nero.aimassistance.utils.Wrapper; | ||
import net.minecraft.entity.Entity; | ||
import net.minecraft.entity.MobEntity; | ||
import net.minecraft.util.math.BlockRayTraceResult; | ||
|
||
import java.util.List; | ||
|
||
/** | ||
* These functions should be called periodically. Check their description for details. | ||
* - analyseBehaviour() | ||
* - analyseEnvironment() | ||
* - assistIfPossible() | ||
*/ | ||
public class AimAssistance { | ||
|
||
// Main attributes | ||
private Target target; // it defines what the assistance will target | ||
private TargetType interactingWith; // defines what the player is interacting with (can be none) | ||
|
||
// Used to keep track of the player's behaviour | ||
private TimeHelper interactionTimer = new TimeHelper(); // used to toggle the interaction for a given amount of time | ||
private TimeHelper miningTimer = new TimeHelper(); | ||
private TimeHelper attackTimer = new TimeHelper(); // used to calculate the attack speed of the player | ||
private int attackCount = 0; // used to calculate the attack speed of the player | ||
private boolean attackKeyAlreadyPressed = false; // used to handle key press | ||
|
||
// Behaviour settings | ||
private final float INTERACTION_ATTACK_SPEED = 1f / 1000f; // (attacks per ms) user faster means user attacking | ||
private final int INTERACTION_ATTACK_DURATION = 3000; // (ms) duration after which we give up | ||
private final int INTERACTION_MINING_DURATION = 400; // (ms) duration the player needs to be mining to assist | ||
private final int INTERACTION_DURATION = 500; // (ms) duration during which the assistance will assist (i'm a poet) | ||
private final float RANGE_TO_SCAN = 5; // (blocks) range to scan from the player to find entities | ||
private final Class ENTITY_TYPE_TO_SCAN = MobEntity.class; // defines the type of entity to scan | ||
private final float BLOCK_REACH = 7; // (blocks) reach to find blocks (lower than default -> ignored) | ||
|
||
// Assistance settings | ||
// (IS IN CONFIG CLASS) private final float FORCE = 5; // force of the assistance | ||
private final float FOV = 60; // field of view | ||
|
||
/** | ||
* Inits attributes | ||
*/ | ||
public AimAssistance() { | ||
this.target = Target.NULL_TARGET; | ||
this.interactingWith = TargetType.NONE; | ||
} | ||
|
||
/** | ||
* This function analyses the player's environment to know what they're aiming at. | ||
*/ | ||
public void analyseEnvironment() { | ||
if (!Wrapper.playerPlaying()) return; | ||
|
||
// idea: Optimization: only perform the analysis when the player is interacting, and do it once, then start a | ||
// timer to update the target if needed: (if the player is fighting a lot of mobs, they will still be fighting, | ||
// but the target won't be the same anymore) | ||
|
||
switch (this.interactingWith) { | ||
case ENTITY: | ||
// Get all entities around the player | ||
List<Entity> entities = Wrapper.getEntitiesAroundPlayer(this.RANGE_TO_SCAN, this.ENTITY_TYPE_TO_SCAN); | ||
|
||
// Get the closest one to the crosshair | ||
Entity closest = Wrapper.getClosestEntityToCrosshair(entities); | ||
|
||
if (closest != null) { | ||
this.target = new Target(closest); | ||
} | ||
|
||
break; | ||
|
||
case BLOCK: | ||
// Check what block the player is aiming at | ||
BlockRayTraceResult target = Wrapper.getPointedBlock(this.BLOCK_REACH); | ||
|
||
if (target != null) { | ||
this.target = new Target(target); | ||
} | ||
|
||
break; | ||
} | ||
} | ||
|
||
/** | ||
* This function analyzes the player's behaviour to know if the aim assistance should be turned on or not. It should | ||
* be called (at least) at every game tick because it uses input events (attack key information). | ||
*/ | ||
public void analyseBehaviour() { | ||
if (!Wrapper.playerPlaying()) return; | ||
|
||
// MINING SECTION (Block) | ||
|
||
// If the player wasn't doing anything, and is pressing the attack key (same as mining), then start the timer | ||
if (this.miningTimer.isStopped() && Wrapper.attackKeyPressed() && Config.isAimBlocks()) { | ||
this.miningTimer.start(); | ||
} | ||
// Else (means that the player is mining) if the player stopped mining during the timer, then stop it | ||
else if (!this.miningTimer.isDelayComplete(this.INTERACTION_MINING_DURATION) && !Wrapper.attackKeyPressed()) { | ||
this.miningTimer.stop(); | ||
} | ||
// Else (means that the player is mining) if the player has been mining for the given duration, then they're | ||
// interacting | ||
else if (this.miningTimer.isDelayComplete(this.INTERACTION_MINING_DURATION) && Wrapper.attackKeyPressed()) { | ||
this.miningTimer.stop(); | ||
this.interactionTimer.start(); // it will reset if already started, so we're all good | ||
this.interactingWith = TargetType.BLOCK; | ||
} | ||
|
||
// ATTACK SECTION (Entity) | ||
|
||
// Event handling (convert "keyDown" to "isPressed". Minecraft has one built-in but using it may break some | ||
// code in the backend) | ||
boolean playerAttacks = false; | ||
if (this.attackKeyAlreadyPressed && !Wrapper.attackKeyPressed()) { | ||
this.attackKeyAlreadyPressed = false; | ||
} else if (!this.attackKeyAlreadyPressed && Wrapper.attackKeyPressed()) { | ||
playerAttacks = true; | ||
this.attackKeyAlreadyPressed = true; | ||
} | ||
|
||
// First time that the player attacks | ||
if (this.attackCount == 0 && playerAttacks && Config.isAimMobs()) { | ||
this.attackCount += 1; | ||
this.attackTimer.start(); | ||
} | ||
// If it's not the first time that the player attacked | ||
else if (this.attackCount > 0 && playerAttacks) { | ||
this.attackCount += 1; | ||
|
||
// Calculate the number of attacks per miliseconds | ||
float speed = (float) this.attackCount / (float) this.attackTimer.getTimeElapsed(); | ||
|
||
// If player's attack speed is greater than the speed given to toggle the assistance, then we can tell to | ||
// the instance that the player is interacting | ||
if (speed > this.INTERACTION_ATTACK_SPEED) { | ||
// We need to reset the variables that are used to define if the player is interacting because we know | ||
// that the user is interacting right now | ||
this.attackCount = 0; | ||
this.attackTimer.stop(); | ||
|
||
this.interactionTimer.start(); // it will reset if already started, so we're all good | ||
this.interactingWith = TargetType.ENTITY; | ||
} | ||
} | ||
// If the player did not attack for that period of time, we give up and reset everything | ||
else if (this.attackTimer.isDelayComplete(INTERACTION_ATTACK_DURATION)) { | ||
this.attackTimer.stop(); | ||
this.attackCount = 0; | ||
} | ||
|
||
// COMMON SECTION | ||
|
||
// Stop the interaction once that the delay is reached | ||
if (this.interactingWith != TargetType.NONE | ||
&& this.interactionTimer.isDelayComplete(this.INTERACTION_DURATION)) { | ||
this.target = Target.NULL_TARGET; | ||
this.interactingWith = TargetType.NONE; | ||
this.interactionTimer.stop(); | ||
} | ||
} | ||
|
||
/** | ||
* This function will move the player's crosshair. The faster this function is called, the smoother the aim | ||
* assistance is. | ||
*/ | ||
public void assistIfPossible() { | ||
if (!Wrapper.playerPlaying()) return; | ||
|
||
// Assist the player by taking into account this.target, only if this.isInteracting is true | ||
if (this.interactingWith != TargetType.NONE && this.target.getType() != TargetType.NONE) { | ||
final float[] rotations = Wrapper.getRotationsNeeded( | ||
target, | ||
FOV, FOV, | ||
(float) Config.getAimForce(), (float) Config.getAimForce() // forceX, forceY | ||
); | ||
|
||
Wrapper.setRotations(rotations[0], rotations[1]); | ||
} | ||
} | ||
} |
Oops, something went wrong.