generated from Polyfrost/OneConfigExampleMod
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
147 additions
and
216 deletions.
There are no files selected for viewing
46 changes: 19 additions & 27 deletions
46
src/main/java/org/redthsgayclub/aimassistant/AimAssistant.kt
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,33 +1,25 @@ | ||
package org.redthsgayclub.aimassistant; | ||
package org.redthsgayclub.aimassistant | ||
|
||
import net.minecraftforge.common.MinecraftForge; | ||
import org.redthsgayclub.aimassistant.config.Config; | ||
import cc.polyfrost.oneconfig.events.event.InitializationEvent; | ||
import net.minecraftforge.fml.common.Mod; | ||
import net.minecraftforge.fml.common.event.FMLInitializationEvent; | ||
import org.redthsgayclub.aimassistant.listener.EventListener; | ||
import net.minecraftforge.common.MinecraftForge | ||
import net.minecraftforge.fml.common.Mod | ||
import net.minecraftforge.fml.common.event.FMLInitializationEvent | ||
import org.redthsgayclub.aimassistant.config.ModConfig | ||
import org.redthsgayclub.aimassistant.listener.EventListener | ||
|
||
/** | ||
* The entrypoint of the Example Mod that initializes it. | ||
* | ||
* @see Mod | ||
* @see InitializationEvent | ||
*/ | ||
@Mod(modid = AimAssistant.MODID, name = AimAssistant.NAME, version = AimAssistant.VERSION) | ||
public class AimAssistant { | ||
@Mod( | ||
modid = AimAssistant.MODID, | ||
name = AimAssistant.NAME, | ||
version = AimAssistant.VERSION, | ||
modLanguageAdapter = "cc.polyfrost.oneconfig.utils.KotlinLanguageAdapter" | ||
) | ||
object AimAssistant { | ||
const val MODID = "@ID@" | ||
const val NAME = "@NAME@" | ||
const val VERSION = "@VER@" | ||
|
||
// Sets the variables from `gradle.properties`. See the `blossom` config in `build.gradle.kts`. | ||
public static final String MODID = "@ID@"; | ||
public static final String NAME = "@NAME@"; | ||
public static final String VERSION = "@VER@"; | ||
@Mod.Instance(MODID) | ||
public static AimAssistant INSTANCE; // Adds the instance of the mod, so we can access other variables. | ||
public static Config config; | ||
|
||
// Register the config and commands. | ||
@Mod.EventHandler | ||
public void onInit(FMLInitializationEvent event) { | ||
config = new Config(); | ||
MinecraftForge.EVENT_BUS.register(new EventListener()); | ||
fun onInit(event: FMLInitializationEvent) { | ||
ModConfig | ||
MinecraftForge.EVENT_BUS.register(EventListener) | ||
} | ||
} |
66 changes: 22 additions & 44 deletions
66
src/main/java/org/redthsgayclub/aimassistant/config/ModConfig.kt
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,53 +1,31 @@ | ||
package org.redthsgayclub.aimassistant.config; | ||
package org.redthsgayclub.aimassistant.config | ||
|
||
import cc.polyfrost.oneconfig.config.annotations.*; | ||
import cc.polyfrost.oneconfig.config.core.OneColor; | ||
import org.redthsgayclub.aimassistant.AimAssistant; | ||
import cc.polyfrost.oneconfig.config.data.Mod; | ||
import cc.polyfrost.oneconfig.config.data.ModType; | ||
import cc.polyfrost.oneconfig.config.Config | ||
import cc.polyfrost.oneconfig.config.annotations.Color | ||
import cc.polyfrost.oneconfig.config.annotations.DualOption | ||
import cc.polyfrost.oneconfig.config.annotations.Slider | ||
import cc.polyfrost.oneconfig.config.core.OneColor | ||
import cc.polyfrost.oneconfig.config.data.Mod | ||
import cc.polyfrost.oneconfig.config.data.ModType | ||
import org.redthsgayclub.aimassistant.AimAssistant | ||
|
||
/** | ||
* The main Config entrypoint that extends the Config type and inits the config options. | ||
* See <a href="https://docs.polyfrost.cc/oneconfig/config/adding-options">this link</a> for more config Options | ||
*/ | ||
public class Config extends cc.polyfrost.oneconfig.config.Config { | ||
object ModConfig : Config(Mod(AimAssistant.NAME, ModType.UTIL_QOL), "${AimAssistant.MODID}.json") { | ||
@DualOption(name = "Mode", left = "Target", right = "Range") | ||
var mode = false | ||
|
||
@DualOption( | ||
name = "", // Name of the Dropdown | ||
left = "Target Mode", | ||
right = "Range Mode" | ||
) | ||
public static boolean mode = false; // Default option (in this case "Option 2") | ||
@Slider(name = "Range Slider", min = 0f, max = 15f) | ||
var range = 5f | ||
|
||
@Color(name = "Box Color") | ||
var boxColor = OneColor(168, 45, 45, 255) | ||
|
||
@Slider( | ||
name = "Range Slider", | ||
min = 0f, max = 15f // Minimum and maximum values for the slider. | ||
) | ||
public static float range = 5f; // The default value for the float Slider. | ||
@Color(name = "Box Color in Reach") | ||
var inReachColor = OneColor(45, 168, 45, 255) | ||
|
||
@Color( | ||
name = "Box Color" | ||
) | ||
public static OneColor boxColor = new OneColor(168, 45, 45, 255); | ||
@Slider(name = "Box Size", min = 0.05f, max = 0.6f) | ||
var size = 0.1f | ||
|
||
@Color( | ||
name = "Box Color in Reach" | ||
) | ||
public static OneColor inReachColor = new OneColor(45, 168, 45, 255); | ||
|
||
@Slider( | ||
name = "Box Size", | ||
min = 0.05f, | ||
max = 0.6f | ||
) | ||
public static float size = 5f; // The default value for the float Slider. | ||
|
||
|
||
public Config() { | ||
super(new Mod(AimAssistant.NAME, ModType.UTIL_QOL), AimAssistant.MODID + ".json"); | ||
initialize(); | ||
//addDependency("range", "mode"); | ||
init { | ||
initialize() | ||
} | ||
} | ||
|
251 changes: 106 additions & 145 deletions
251
src/main/java/org/redthsgayclub/aimassistant/listener/EventListener.kt
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,155 +1,116 @@ | ||
package org.redthsgayclub.aimassistant.listener; | ||
|
||
import cc.polyfrost.oneconfig.config.core.OneColor; | ||
import net.minecraft.client.Minecraft; | ||
import net.minecraft.client.renderer.GlStateManager; | ||
|
||
import net.minecraft.client.renderer.Tessellator; | ||
import net.minecraft.client.renderer.WorldRenderer; | ||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; | ||
import net.minecraft.entity.Entity; | ||
|
||
import net.minecraft.util.*; | ||
import net.minecraftforge.client.event.RenderPlayerEvent; | ||
import net.minecraftforge.fml.common.eventhandler.EventPriority; | ||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; | ||
|
||
import org.redthsgayclub.aimassistant.AimAssistant; | ||
import org.redthsgayclub.aimassistant.config.Config; | ||
|
||
public class EventListener { | ||
private static final Tessellator tessellator = Tessellator.getInstance(); | ||
private static final WorldRenderer worldRenderer = tessellator.getWorldRenderer(); | ||
private static final Minecraft mc = Minecraft.getMinecraft(); | ||
|
||
package org.redthsgayclub.aimassistant.listener | ||
|
||
import cc.polyfrost.oneconfig.config.core.OneColor | ||
import cc.polyfrost.oneconfig.utils.dsl.mc | ||
import net.minecraft.client.renderer.Tessellator | ||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats | ||
import net.minecraft.entity.Entity | ||
import net.minecraft.util.AxisAlignedBB | ||
import net.minecraft.util.Vec3 | ||
import net.minecraftforge.client.event.RenderPlayerEvent | ||
import net.minecraftforge.fml.common.eventhandler.EventPriority | ||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent | ||
import org.lwjgl.opengl.GL11 | ||
import org.redthsgayclub.aimassistant.config.ModConfig | ||
import net.minecraft.client.renderer.GlStateManager as GL | ||
|
||
object EventListener { | ||
@SubscribeEvent(priority = EventPriority.LOWEST) | ||
public void renderPlayerEvent(RenderPlayerEvent.Post event) { | ||
if (!AimAssistant.config.enabled) return; | ||
if (event.entityPlayer.equals(mc.thePlayer)) return; | ||
if (Config.mode) { | ||
//range mode | ||
double distance = event.entityPlayer.getDistanceSq(mc.thePlayer.posX, mc.thePlayer.posY + mc.thePlayer.getEyeHeight(), mc.thePlayer.posZ); | ||
if (distance > Config.range * Config.range) return; | ||
|
||
} else { | ||
//target mode | ||
if (!isLooking(event.entityPlayer)) return; | ||
|
||
fun renderPlayerEvent(event: RenderPlayerEvent.Post) { | ||
if (!ModConfig.enabled) return | ||
val player = mc.thePlayer ?: return | ||
val target = event.entityPlayer | ||
val partialTicks = event.partialRenderTick | ||
if (target == player) return | ||
|
||
if (ModConfig.mode) { // range mode | ||
val distance = target.getDistanceSqToEntity(player) | ||
if (distance > ModConfig.range * ModConfig.range) return | ||
} else { //target mode | ||
val eyes = mc.thePlayer.getPositionEyes(partialTicks) | ||
val lookVector = mc.thePlayer.getLook(partialTicks) * ModConfig.range.toDouble() | ||
val intercept = target.actualHitbox.calculateIntercept(eyes, eyes + lookVector) | ||
if (intercept == null) return | ||
} | ||
|
||
AxisAlignedBB aabb = getAABB(event.entityPlayer, event.partialRenderTick); | ||
val lerpedPos = player.getLerpedPos(partialTicks) | ||
val targetSmoothOffset = (target.prevPos - target.pos) * (1.0 - partialTicks.toDouble()) | ||
val boxAtOrigin = target.actualHitbox.offset(targetSmoothOffset - lerpedPos) | ||
val camera = Vec3(0.0, player.eyeHeight.toDouble(), 0.0) | ||
val bestHitPos = camera.coerceInto(boxAtOrigin) | ||
val tooClose = camera.squareDistanceTo(bestHitPos) < 0.1 * 0.1 | ||
if (tooClose) return | ||
val halfRange = ModConfig.size / 2.0 | ||
val shrunkenTargetBox = boxAtOrigin.contract(halfRange) | ||
val shrunkenBestHitPos = camera.coerceInto(shrunkenTargetBox) | ||
val box = shrunkenBestHitPos.toBox().expand(halfRange) | ||
|
||
if (mc.pointedEntity == event.entityPlayer) { | ||
renderBox(aabb, Config.inReachColor); | ||
renderBox(box, ModConfig.inReachColor) | ||
} else { | ||
renderBox(aabb, Config.boxColor); | ||
renderBox(box, ModConfig.boxColor) | ||
} | ||
} | ||
|
||
private void renderBox(AxisAlignedBB aabb, OneColor color) { | ||
GlStateManager.pushMatrix(); | ||
GlStateManager.disableAlpha(); | ||
GlStateManager.enableBlend(); | ||
GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); | ||
GlStateManager.disableTexture2D(); | ||
GlStateManager.depthMask(true); | ||
GlStateManager.disableLighting(); | ||
GlStateManager.disableCull(); | ||
GlStateManager.disableDepth(); | ||
if (color.getAlpha() > 0.0F) { | ||
GlStateManager.color(color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f, color.getAlpha() / 255f); | ||
renderCube(aabb); | ||
} | ||
GlStateManager.enableCull(); | ||
GlStateManager.enableDepth(); | ||
GlStateManager.enableLighting(); | ||
GlStateManager.depthMask(true); | ||
GlStateManager.enableTexture2D(); | ||
GlStateManager.disableBlend(); | ||
GlStateManager.enableAlpha(); | ||
GlStateManager.popMatrix(); | ||
private val Entity.actualHitbox get() = entityBoundingBox.expand(collisionBorderSize.toDouble()) | ||
private val Entity.prevPos get() = Vec3(prevPosX, prevPosY, prevPosZ) | ||
private val Entity.pos get() = Vec3(posX, posY, posZ) | ||
private fun Entity.getLerpedPos(partialTicks: Float) = prevPos + (pos - prevPos) * partialTicks.toDouble() | ||
private fun AxisAlignedBB.offset(vec: Vec3) = this.offset(vec.xCoord, vec.yCoord, vec.zCoord) | ||
private fun AxisAlignedBB.contract(amount: Double) = this.contract(amount, amount, amount) | ||
private fun AxisAlignedBB.expand(amount: Double) = this.expand(amount, amount, amount) | ||
private fun Vec3.toBox() = AxisAlignedBB(xCoord, yCoord, zCoord, xCoord, yCoord, zCoord) | ||
private operator fun Vec3.plus(other: Vec3) = this.add(other) | ||
private operator fun Vec3.minus(other: Vec3) = this.subtract(other) | ||
private operator fun Vec3.unaryMinus() = Vec3(-xCoord, -yCoord, -zCoord) | ||
private operator fun Vec3.times(scale: Double) = Vec3(xCoord * scale, yCoord * scale, zCoord * scale) | ||
private fun Vec3.coerceInto(box: AxisAlignedBB) = Vec3( | ||
xCoord.coerceIn(box.minX, box.maxX), | ||
yCoord.coerceIn(box.minY, box.maxY), | ||
zCoord.coerceIn(box.minZ, box.maxZ), | ||
) | ||
|
||
private fun renderBox(aabb: AxisAlignedBB, color: OneColor) { | ||
GL.pushMatrix() | ||
GL.disableAlpha() | ||
GL.enableBlend() | ||
GL.tryBlendFuncSeparate(770, 771, 1, 0) | ||
GL.disableTexture2D() | ||
GL.depthMask(true) | ||
GL.disableLighting() | ||
GL.disableCull() | ||
GL.disableDepth() | ||
GL.color(color.red / 255f, color.green / 255f, color.blue / 255f, color.alpha / 255f) | ||
val tessellator = Tessellator.getInstance() | ||
val wr = tessellator.worldRenderer | ||
wr.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION) | ||
wr.pos(aabb.maxX, aabb.maxY, aabb.minZ).endVertex() | ||
wr.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex() | ||
wr.pos(aabb.maxX, aabb.maxY, aabb.maxZ).endVertex() | ||
wr.pos(aabb.minX, aabb.maxY, aabb.maxZ).endVertex() | ||
wr.pos(aabb.maxX, aabb.minY, aabb.maxZ).endVertex() | ||
wr.pos(aabb.minX, aabb.minY, aabb.maxZ).endVertex() | ||
wr.pos(aabb.maxX, aabb.minY, aabb.minZ).endVertex() | ||
wr.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex() | ||
tessellator.draw() | ||
wr.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION) | ||
wr.pos(aabb.maxX, aabb.maxY, aabb.maxZ).endVertex() | ||
wr.pos(aabb.maxX, aabb.minY, aabb.maxZ).endVertex() | ||
wr.pos(aabb.maxX, aabb.maxY, aabb.minZ).endVertex() | ||
wr.pos(aabb.maxX, aabb.minY, aabb.minZ).endVertex() | ||
wr.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex() | ||
wr.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex() | ||
wr.pos(aabb.minX, aabb.maxY, aabb.maxZ).endVertex() | ||
wr.pos(aabb.minX, aabb.minY, aabb.maxZ).endVertex() | ||
tessellator.draw() | ||
GL.color(1f, 1f, 1f, 1f) | ||
GL.enableCull() | ||
GL.enableDepth() | ||
GL.enableLighting() | ||
GL.depthMask(true) | ||
GL.enableTexture2D() | ||
GL.disableBlend() | ||
GL.enableAlpha() | ||
GL.popMatrix() | ||
} | ||
|
||
private static void renderCube(AxisAlignedBB aabb) { | ||
worldRenderer.begin(7, DefaultVertexFormats.POSITION); | ||
worldRenderer.pos(aabb.minX, aabb.maxY, aabb.maxZ).endVertex(); | ||
worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.maxZ).endVertex(); | ||
worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.minZ).endVertex(); | ||
worldRenderer.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex(); | ||
tessellator.draw(); | ||
worldRenderer.begin(7, DefaultVertexFormats.POSITION); | ||
worldRenderer.pos(aabb.maxX, aabb.minY, aabb.maxZ).endVertex(); | ||
worldRenderer.pos(aabb.minX, aabb.minY, aabb.maxZ).endVertex(); | ||
worldRenderer.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex(); | ||
worldRenderer.pos(aabb.maxX, aabb.minY, aabb.minZ).endVertex(); | ||
tessellator.draw(); | ||
worldRenderer.begin(7, DefaultVertexFormats.POSITION); | ||
worldRenderer.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex(); | ||
worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.minZ).endVertex(); | ||
worldRenderer.pos(aabb.maxX, aabb.minY, aabb.minZ).endVertex(); | ||
worldRenderer.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex(); | ||
tessellator.draw(); | ||
worldRenderer.begin(7, DefaultVertexFormats.POSITION); | ||
worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.maxZ).endVertex(); | ||
worldRenderer.pos(aabb.minX, aabb.maxY, aabb.maxZ).endVertex(); | ||
worldRenderer.pos(aabb.minX, aabb.minY, aabb.maxZ).endVertex(); | ||
worldRenderer.pos(aabb.maxX, aabb.minY, aabb.maxZ).endVertex(); | ||
tessellator.draw(); | ||
worldRenderer.begin(7, DefaultVertexFormats.POSITION); | ||
worldRenderer.pos(aabb.minX, aabb.maxY, aabb.maxZ).endVertex(); | ||
worldRenderer.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex(); | ||
worldRenderer.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex(); | ||
worldRenderer.pos(aabb.minX, aabb.minY, aabb.maxZ).endVertex(); | ||
tessellator.draw(); | ||
worldRenderer.begin(7, DefaultVertexFormats.POSITION); | ||
worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.minZ).endVertex(); | ||
worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.maxZ).endVertex(); | ||
worldRenderer.pos(aabb.maxX, aabb.minY, aabb.maxZ).endVertex(); | ||
worldRenderer.pos(aabb.maxX, aabb.minY, aabb.minZ).endVertex(); | ||
tessellator.draw(); | ||
} | ||
|
||
private static AxisAlignedBB getAABB(Entity target, float partialTicks) { | ||
Vec3 lerpedPos = getLerpedPos(mc.thePlayer, partialTicks); | ||
Vec3 targetLerpOffset = getLerpedPos(target, partialTicks); | ||
Vec3 cameraPosRelToEntity = mc.thePlayer.getPositionEyes(partialTicks).subtract(lerpedPos); | ||
AxisAlignedBB boxAtOrigin = target.getEntityBoundingBox() | ||
.offset(-lerpedPos.xCoord, -lerpedPos.yCoord, -lerpedPos.zCoord) | ||
.offset(-target.posX, -target.posY, -target.posZ) | ||
.offset(targetLerpOffset.xCoord, targetLerpOffset.yCoord, targetLerpOffset.zCoord); | ||
float halfRange = Config.size / 2; | ||
AxisAlignedBB shrunkenTargetBox = boxAtOrigin.contract(halfRange, halfRange, halfRange); | ||
Vec3 bestHitPos = pointClampedIntoBox(cameraPosRelToEntity, shrunkenTargetBox); | ||
|
||
|
||
|
||
return new AxisAlignedBB(bestHitPos.xCoord, bestHitPos.yCoord, bestHitPos.zCoord, bestHitPos.xCoord, bestHitPos.yCoord, bestHitPos.zCoord).expand(halfRange, halfRange, halfRange); | ||
} | ||
|
||
private static boolean isInReach(Entity target, float partialTicks) { | ||
Vec3 lerpedPos = getLerpedPos(mc.thePlayer, partialTicks); | ||
Vec3 targetLerpOffset = getLerpedPos(target, partialTicks); | ||
Vec3 cameraPosRelToEntity = mc.thePlayer.getPositionEyes(partialTicks).subtract(lerpedPos); | ||
AxisAlignedBB boxAtOrigin = target.getEntityBoundingBox() | ||
.offset(-lerpedPos.xCoord, -lerpedPos.yCoord, -lerpedPos.zCoord) | ||
.offset(-target.posX, -target.posY, -target.posZ) | ||
.offset(targetLerpOffset.xCoord, targetLerpOffset.yCoord, targetLerpOffset.zCoord); | ||
return cameraPosRelToEntity.squareDistanceTo(pointClampedIntoBox(cameraPosRelToEntity, boxAtOrigin)) > 3.0 * 3.0; | ||
} | ||
|
||
private static boolean isLooking(Entity target) { | ||
Vec3 vec = new Vec3(mc.thePlayer.getLookVec().xCoord * Config.range, mc.thePlayer.getLookVec().yCoord * Config.range, mc.thePlayer.getLookVec().zCoord * Config.range); | ||
return target.getEntityBoundingBox().calculateIntercept(mc.thePlayer.getPositionEyes(1.0f), mc.thePlayer.getPositionEyes(1.0F).add(vec)) != null; | ||
} | ||
|
||
private static Vec3 getLerpedPos(Entity entity, float partialTicks) { | ||
return new Vec3(entity.prevPosX + (entity.posX - entity.prevPosX) * (double) partialTicks, entity.prevPosY + (entity.posY - entity.prevPosY) * (double) partialTicks, entity.prevPosZ + (entity.posZ - entity.prevPosZ) * (double) partialTicks); | ||
} | ||
|
||
private static Vec3 pointClampedIntoBox(Vec3 point, AxisAlignedBB box) { | ||
double x = MathHelper.clamp_double(point.xCoord, box.minX, box.maxX); | ||
double y = MathHelper.clamp_double(point.yCoord, box.minY, box.maxY); | ||
double z = MathHelper.clamp_double(point.zCoord, box.minZ, box.maxZ); | ||
return new Vec3(x, y, z); | ||
} | ||
|
||
} |