commit 8c4b8c7eaea5879d5014bdf2384c267a2760a03d Author: arkonsadter Date: Tue Feb 3 16:36:08 2026 +0600 initial commit diff --git a/.gradle/8.9/checksums/checksums.lock b/.gradle/8.9/checksums/checksums.lock new file mode 100644 index 0000000..e6c80de Binary files /dev/null and b/.gradle/8.9/checksums/checksums.lock differ diff --git a/.gradle/8.9/checksums/md5-checksums.bin b/.gradle/8.9/checksums/md5-checksums.bin new file mode 100644 index 0000000..619cbcd Binary files /dev/null and b/.gradle/8.9/checksums/md5-checksums.bin differ diff --git a/.gradle/8.9/checksums/sha1-checksums.bin b/.gradle/8.9/checksums/sha1-checksums.bin new file mode 100644 index 0000000..38c4ea0 Binary files /dev/null and b/.gradle/8.9/checksums/sha1-checksums.bin differ diff --git a/.gradle/8.9/dependencies-accessors/gc.properties b/.gradle/8.9/dependencies-accessors/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/.gradle/8.9/fileChanges/last-build.bin b/.gradle/8.9/fileChanges/last-build.bin new file mode 100644 index 0000000..f76dd23 Binary files /dev/null and b/.gradle/8.9/fileChanges/last-build.bin differ diff --git a/.gradle/8.9/fileHashes/fileHashes.lock b/.gradle/8.9/fileHashes/fileHashes.lock new file mode 100644 index 0000000..2769033 Binary files /dev/null and b/.gradle/8.9/fileHashes/fileHashes.lock differ diff --git a/.gradle/8.9/gc.properties b/.gradle/8.9/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock new file mode 100644 index 0000000..bb06cba Binary files /dev/null and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties new file mode 100644 index 0000000..58211ea --- /dev/null +++ b/.gradle/buildOutputCleanup/cache.properties @@ -0,0 +1,2 @@ +#Tue Feb 03 16:21:29 OMST 2026 +gradle.version=8.9 diff --git a/.gradle/vcs-1/gc.properties b/.gradle/vcs-1/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c5f3f6b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.configuration.updateBuildConfiguration": "interactive" +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..20fa7eb --- /dev/null +++ b/README.md @@ -0,0 +1,51 @@ +# PvP Mod для Minecraft Forge 1.20.1 + +Мод для улучшения PvP с различными функциями. + +## Функции + +### Основные возможности: +1. **KillAura** - автоматическая атака ближайших врагов +2. **TriggerBot** - автоматическая атака при наведении на цель +3. **Hitbox Expander** - увеличение хитбоксов для легкого попадания +4. **Aim Assist** - помощь в прицеливании +5. **ESP** - подсветка игроков и мобов через стены +6. **HUD** - информационный интерфейс + +### HUD включает: +1. **TargetHUD** - информация о текущей цели +2. **Keybinds** - статус горячих клавиш +3. **Potions** - активные эффекты зелий +4. **Armor** - состояние брони + +## Управление + +- **Правый Shift** - открыть меню настроек +- **R** - переключить KillAura +- **T** - переключить TriggerBot +- **B** - переключить ESP + +## Настройки + +В меню настроек (Правый Shift) можно настроить: +- Радиус KillAura (3.0 - 6.0 блоков) +- Скорость атак KillAura (6-20 атак в секунду) +- Размер хитбоксов (1.0 - 2.0x) +- Включение/выключение всех функций +- Настройки HUD + +## Установка + +1. Установите Minecraft Forge 1.20.1 +2. Скомпилируйте мод: `./gradlew build` +3. Поместите .jar файл из `build/libs/` в папку `mods` + +## Компиляция + +```bash +./gradlew build +``` + +## Предупреждение + +Этот мод предназначен только для образовательных целей и использования на приватных серверах. Использование на публичных серверах может нарушать правила сервера. \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..f32cb66 --- /dev/null +++ b/build.gradle @@ -0,0 +1,69 @@ +buildscript { + repositories { + // These repositories are only for Gradle plugins, put any other repositories in the repository block further below + maven { url = 'https://maven.minecraftforge.net' } + gradlePluginPortal() + mavenCentral() + } + dependencies { + classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true + } +} + +plugins { + id 'eclipse' + id 'maven-publish' +} + +apply plugin: 'net.minecraftforge.gradle' + +version = '1.0.0' +group = 'com.example.pvpmod' +archivesBaseName = 'pvpmod' + +java.toolchain.languageVersion = JavaLanguageVersion.of(17) + +minecraft { + mappings channel: 'official', version: '1.20.1' + + runs { + client { + workingDirectory project.file('run') + property 'forge.logging.markers', 'REGISTRIES' + property 'forge.logging.console.level', 'debug' + mods { + pvpmod { + source sourceSets.main + } + } + } + } +} + +repositories { + // Put repositories for dependencies here + // ForgeGradle automatically adds the Forge maven and Maven Central for you + + // If you have mod jar dependencies in ./libs, you can declare them as a repository like so: + // flatDir { + // dir 'libs' + // } +} + +dependencies { + minecraft 'net.minecraftforge:forge:1.20.1-47.2.0' +} + +jar { + manifest { + attributes([ + "Specification-Title": "PvP Mod", + "Specification-Vendor": "Example", + "Specification-Version": "1", + "Implementation-Title": project.name, + "Implementation-Version": "${version}", + "Implementation-Vendor": "Example", + "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") + ]) + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..878bf1f --- /dev/null +++ b/gradle.properties @@ -0,0 +1,4 @@ +# Sets default memory used for gradle commands. Can be overridden by user or command line properties. +# This is required to provide enough memory for the Minecraft decompilation process. +org.gradle.jvmargs=-Xmx3G +org.gradle.daemon=false \ No newline at end of file diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..413db1a --- /dev/null +++ b/settings.gradle @@ -0,0 +1,11 @@ +pluginManagement { + repositories { + gradlePluginPortal() + maven { + name = 'MinecraftForge' + url = 'https://maven.minecraftforge.net/' + } + } +} + +rootProject.name = 'pvpmod' \ No newline at end of file diff --git a/src/main/java/com/example/pvpmod/PvPMod.java b/src/main/java/com/example/pvpmod/PvPMod.java new file mode 100644 index 0000000..9cb990d --- /dev/null +++ b/src/main/java/com/example/pvpmod/PvPMod.java @@ -0,0 +1,85 @@ +package com.example.pvpmod; + +import com.example.pvpmod.client.ModKeyBindings; +import com.example.pvpmod.client.gui.ModMenuScreen; +import com.example.pvpmod.config.ModConfig; +import com.example.pvpmod.features.*; +import net.minecraft.client.Minecraft; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.client.event.InputEvent; +import net.minecraftforge.client.event.RenderGuiOverlayEvent; +import net.minecraftforge.client.event.RenderLevelStageEvent; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.TickEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.minecraftforge.fml.loading.FMLEnvironment; + +@Mod("pvpmod") +public class PvPMod { + public static final String MODID = "pvpmod"; + + public static ModConfig config = new ModConfig(); + public static KillAura killAura = new KillAura(); + public static TriggerBot triggerBot = new TriggerBot(); + public static HitboxExpander hitboxExpander = new HitboxExpander(); + public static AimAssist aimAssist = new AimAssist(); + public static ESP esp = new ESP(); + public static HUD hud = new HUD(); + + public PvPMod() { + if (FMLEnvironment.dist == Dist.CLIENT) { + FMLJavaModLoadingContext.get().getModEventBus().addListener(this::clientSetup); + MinecraftForge.EVENT_BUS.register(this); + } + } + + private void clientSetup(final FMLClientSetupEvent event) { + ModKeyBindings.register(); + } + + @SubscribeEvent + public void onClientTick(TickEvent.ClientTickEvent event) { + if (event.phase != TickEvent.Phase.START) return; + + Minecraft mc = Minecraft.getInstance(); + if (mc.player == null || mc.level == null) return; + + if (config.killAuraEnabled) { + killAura.onTick(); + } + + if (config.triggerBotEnabled) { + triggerBot.onTick(); + } + + if (config.aimAssistEnabled) { + aimAssist.onTick(); + } + } + + @SubscribeEvent + public void onKeyInput(InputEvent.Key event) { + if (ModKeyBindings.OPEN_MENU.consumeClick()) { + Minecraft.getInstance().setScreen(new ModMenuScreen()); + } + } + + @SubscribeEvent + public void onRenderLevel(RenderLevelStageEvent event) { + if (event.getStage() == RenderLevelStageEvent.Stage.AFTER_TRANSLUCENT_BLOCKS) { + if (config.espEnabled) { + esp.render(event.getPoseStack(), event.getPartialTick()); + } + } + } + + @SubscribeEvent + public void onRenderGui(RenderGuiOverlayEvent.Post event) { + if (config.hudEnabled) { + hud.render(event.getGuiGraphics()); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/example/pvpmod/client/ModKeyBindings.java b/src/main/java/com/example/pvpmod/client/ModKeyBindings.java new file mode 100644 index 0000000..6fa8f30 --- /dev/null +++ b/src/main/java/com/example/pvpmod/client/ModKeyBindings.java @@ -0,0 +1,45 @@ +package com.example.pvpmod.client; + +import com.mojang.blaze3d.platform.InputConstants; +import net.minecraft.client.KeyMapping; +import net.minecraftforge.client.ClientRegistry; +import org.lwjgl.glfw.GLFW; + +public class ModKeyBindings { + public static final String CATEGORY = "key.categories.pvpmod"; + + public static final KeyMapping OPEN_MENU = new KeyMapping( + "key.pvpmod.open_menu", + InputConstants.Type.KEYSYM, + GLFW.GLFW_KEY_RIGHT_SHIFT, + CATEGORY + ); + + public static final KeyMapping TOGGLE_KILLAURA = new KeyMapping( + "key.pvpmod.toggle_killaura", + InputConstants.Type.KEYSYM, + GLFW.GLFW_KEY_R, + CATEGORY + ); + + public static final KeyMapping TOGGLE_TRIGGERBOT = new KeyMapping( + "key.pvpmod.toggle_triggerbot", + InputConstants.Type.KEYSYM, + GLFW.GLFW_KEY_T, + CATEGORY + ); + + public static final KeyMapping TOGGLE_ESP = new KeyMapping( + "key.pvpmod.toggle_esp", + InputConstants.Type.KEYSYM, + GLFW.GLFW_KEY_B, + CATEGORY + ); + + public static void register() { + ClientRegistry.registerKeyBinding(OPEN_MENU); + ClientRegistry.registerKeyBinding(TOGGLE_KILLAURA); + ClientRegistry.registerKeyBinding(TOGGLE_TRIGGERBOT); + ClientRegistry.registerKeyBinding(TOGGLE_ESP); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/pvpmod/client/gui/ModMenuScreen.java b/src/main/java/com/example/pvpmod/client/gui/ModMenuScreen.java new file mode 100644 index 0000000..7cd8bf9 --- /dev/null +++ b/src/main/java/com/example/pvpmod/client/gui/ModMenuScreen.java @@ -0,0 +1,139 @@ +package com.example.pvpmod.client.gui; + +import com.example.pvpmod.PvPMod; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.Checkbox; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; + +public class ModMenuScreen extends Screen { + private Checkbox killAuraCheckbox; + private Checkbox triggerBotCheckbox; + private Checkbox hitboxExpanderCheckbox; + private Checkbox aimAssistCheckbox; + private Checkbox espCheckbox; + private Checkbox hudCheckbox; + + private Button killAuraRangeButton; + private Button killAuraSpeedButton; + private Button hitboxSizeButton; + + public ModMenuScreen() { + super(Component.literal("PvP Mod Settings")); + } + + @Override + protected void init() { + int centerX = this.width / 2; + int startY = 50; + + // Feature toggles + killAuraCheckbox = addRenderableWidget(Checkbox.builder(Component.literal("KillAura"), this.font) + .pos(centerX - 100, startY) + .selected(PvPMod.config.killAuraEnabled) + .build()); + + triggerBotCheckbox = addRenderableWidget(Checkbox.builder(Component.literal("TriggerBot"), this.font) + .pos(centerX - 100, startY + 25) + .selected(PvPMod.config.triggerBotEnabled) + .build()); + + hitboxExpanderCheckbox = addRenderableWidget(Checkbox.builder(Component.literal("Hitbox Expander"), this.font) + .pos(centerX - 100, startY + 50) + .selected(PvPMod.config.hitboxExpanderEnabled) + .build()); + + aimAssistCheckbox = addRenderableWidget(Checkbox.builder(Component.literal("Aim Assist"), this.font) + .pos(centerX - 100, startY + 75) + .selected(PvPMod.config.aimAssistEnabled) + .build()); + + espCheckbox = addRenderableWidget(Checkbox.builder(Component.literal("ESP"), this.font) + .pos(centerX - 100, startY + 100) + .selected(PvPMod.config.espEnabled) + .build()); + + hudCheckbox = addRenderableWidget(Checkbox.builder(Component.literal("HUD"), this.font) + .pos(centerX - 100, startY + 125) + .selected(PvPMod.config.hudEnabled) + .build()); + + // Settings buttons + killAuraRangeButton = addRenderableWidget(Button.builder( + Component.literal("Range: " + PvPMod.config.killAuraRange), + button -> { + PvPMod.config.killAuraRange += 0.5f; + if (PvPMod.config.killAuraRange > 6.0f) { + PvPMod.config.killAuraRange = 3.0f; + } + button.setMessage(Component.literal("Range: " + PvPMod.config.killAuraRange)); + }) + .pos(centerX + 20, startY) + .size(100, 20) + .build()); + + killAuraSpeedButton = addRenderableWidget(Button.builder( + Component.literal("Speed: " + PvPMod.config.killAuraSpeed), + button -> { + PvPMod.config.killAuraSpeed += 2; + if (PvPMod.config.killAuraSpeed > 20) { + PvPMod.config.killAuraSpeed = 6; + } + button.setMessage(Component.literal("Speed: " + PvPMod.config.killAuraSpeed)); + }) + .pos(centerX + 20, startY + 25) + .size(100, 20) + .build()); + + hitboxSizeButton = addRenderableWidget(Button.builder( + Component.literal("Hitbox: " + PvPMod.config.hitboxSize), + button -> { + PvPMod.config.hitboxSize += 0.1f; + if (PvPMod.config.hitboxSize > 2.0f) { + PvPMod.config.hitboxSize = 1.0f; + } + button.setMessage(Component.literal("Hitbox: " + String.format("%.1f", PvPMod.config.hitboxSize))); + }) + .pos(centerX + 20, startY + 50) + .size(100, 20) + .build()); + + // Close button + addRenderableWidget(Button.builder(Component.literal("Close"), button -> this.onClose()) + .pos(centerX - 50, this.height - 40) + .size(100, 20) + .build()); + } + + @Override + public void tick() { + super.tick(); + + // Update config based on checkboxes + PvPMod.config.killAuraEnabled = killAuraCheckbox.selected(); + PvPMod.config.triggerBotEnabled = triggerBotCheckbox.selected(); + PvPMod.config.hitboxExpanderEnabled = hitboxExpanderCheckbox.selected(); + PvPMod.config.aimAssistEnabled = aimAssistCheckbox.selected(); + PvPMod.config.espEnabled = espCheckbox.selected(); + PvPMod.config.hudEnabled = hudCheckbox.selected(); + } + + @Override + public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { + this.renderBackground(guiGraphics); + + // Title + guiGraphics.drawCenteredString(this.font, this.title, this.width / 2, 20, 0xFFFFFF); + + // Instructions + guiGraphics.drawCenteredString(this.font, "Press Right Shift to open this menu", this.width / 2, this.height - 60, 0x888888); + + super.render(guiGraphics, mouseX, mouseY, partialTick); + } + + @Override + public boolean isPauseScreen() { + return false; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/pvpmod/config/ModConfig.java b/src/main/java/com/example/pvpmod/config/ModConfig.java new file mode 100644 index 0000000..eb8edc2 --- /dev/null +++ b/src/main/java/com/example/pvpmod/config/ModConfig.java @@ -0,0 +1,34 @@ +package com.example.pvpmod.config; + +public class ModConfig { + // Feature toggles + public boolean killAuraEnabled = false; + public boolean triggerBotEnabled = false; + public boolean hitboxExpanderEnabled = false; + public boolean aimAssistEnabled = false; + public boolean espEnabled = false; + public boolean hudEnabled = true; + + // KillAura settings + public float killAuraRange = 4.0f; + public int killAuraSpeed = 10; // attacks per second + public boolean killAuraTargetPlayers = true; + public boolean killAuraTargetMobs = false; + + // Hitbox settings + public float hitboxSize = 1.0f; + + // HUD settings + public boolean showTargetHUD = true; + public boolean showKeybinds = true; + public boolean showPotions = true; + public boolean showArmor = true; + public int hudX = 10; + public int hudY = 10; + + // Colors (ARGB format) + public int espPlayerColor = 0xFF00FF00; // Green + public int espMobColor = 0xFFFF0000; // Red + public int hudBackgroundColor = 0x80000000; // Semi-transparent black + public int hudTextColor = 0xFFFFFFFF; // White +} \ No newline at end of file diff --git a/src/main/java/com/example/pvpmod/features/AimAssist.java b/src/main/java/com/example/pvpmod/features/AimAssist.java new file mode 100644 index 0000000..f327024 --- /dev/null +++ b/src/main/java/com/example/pvpmod/features/AimAssist.java @@ -0,0 +1,82 @@ +package com.example.pvpmod.features; + +import com.example.pvpmod.PvPMod; +import com.example.pvpmod.util.RotationUtil; +import net.minecraft.client.Minecraft; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.monster.Monster; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; + +import java.util.List; + +public class AimAssist { + private final Minecraft mc = Minecraft.getInstance(); + private static final double AIM_RANGE = 6.0; + private static final float AIM_STRENGTH = 0.3f; + + public void onTick() { + if (mc.player == null || mc.level == null) return; + + LivingEntity target = findNearestTarget(); + if (target == null) return; + + // Get current and target rotations + Vec3 targetPos = target.getEyePosition(); + Vec3 playerPos = mc.player.getEyePosition(); + float[] targetRotations = RotationUtil.getRotationsToPosition(playerPos, targetPos); + + float currentYaw = mc.player.getYRot(); + float currentPitch = mc.player.getXRot(); + + // Calculate rotation difference + float yawDiff = RotationUtil.getAngleDifference(currentYaw, targetRotations[0]); + float pitchDiff = RotationUtil.getAngleDifference(currentPitch, targetRotations[1]); + + // Apply smooth aim assist + float newYaw = currentYaw + (yawDiff * AIM_STRENGTH); + float newPitch = currentPitch + (pitchDiff * AIM_STRENGTH); + + mc.player.setYRot(newYaw); + mc.player.setXRot(newPitch); + } + + private LivingEntity findNearestTarget() { + if (mc.player == null || mc.level == null) return null; + + Vec3 playerPos = mc.player.position(); + AABB searchBox = new AABB( + playerPos.x - AIM_RANGE, playerPos.y - AIM_RANGE, playerPos.z - AIM_RANGE, + playerPos.x + AIM_RANGE, playerPos.y + AIM_RANGE, playerPos.z + AIM_RANGE + ); + + List entities = mc.level.getEntities(mc.player, searchBox); + LivingEntity closestTarget = null; + double closestDistance = Double.MAX_VALUE; + + for (Entity entity : entities) { + if (!(entity instanceof LivingEntity living)) continue; + if (living.isDeadOrDying()) continue; + + boolean isValidTarget = false; + + if (PvPMod.config.killAuraTargetPlayers && entity instanceof Player && entity != mc.player) { + isValidTarget = true; + } else if (PvPMod.config.killAuraTargetMobs && entity instanceof Monster) { + isValidTarget = true; + } + + if (isValidTarget) { + double distance = mc.player.distanceTo(entity); + if (distance < closestDistance && distance <= AIM_RANGE) { + closestDistance = distance; + closestTarget = living; + } + } + } + + return closestTarget; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/pvpmod/features/ESP.java b/src/main/java/com/example/pvpmod/features/ESP.java new file mode 100644 index 0000000..f83524c --- /dev/null +++ b/src/main/java/com/example/pvpmod/features/ESP.java @@ -0,0 +1,60 @@ +package com.example.pvpmod.features; + +import com.example.pvpmod.PvPMod; +import com.example.pvpmod.util.RenderUtil; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.Minecraft; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.monster.Monster; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; + +public class ESP { + private final Minecraft mc = Minecraft.getInstance(); + + public void render(PoseStack poseStack, float partialTick) { + if (mc.player == null || mc.level == null) return; + + Vec3 cameraPos = mc.gameRenderer.getMainCamera().getPosition(); + + for (Entity entity : mc.level.entitiesForRendering()) { + if (!(entity instanceof LivingEntity living)) continue; + if (living == mc.player) continue; + if (living.isDeadOrDying()) continue; + + int color = getESPColor(entity); + if (color == 0) continue; + + // Get entity position + Vec3 entityPos = entity.position(); + double x = entityPos.x - cameraPos.x; + double y = entityPos.y - cameraPos.y; + double z = entityPos.z - cameraPos.z; + + // Get entity bounding box + AABB boundingBox = entity.getBoundingBox(); + double width = boundingBox.getXsize(); + double height = boundingBox.getYsize(); + + // Render ESP box + RenderUtil.drawESPBox(poseStack, x, y, z, width, height, color); + + // Render name tag + if (entity instanceof Player player) { + String name = player.getGameProfile().getName(); + RenderUtil.drawNameTag(poseStack, name, x, y + height + 0.3, z, color); + } + } + } + + private int getESPColor(Entity entity) { + if (entity instanceof Player && entity != mc.player) { + return PvPMod.config.espPlayerColor; + } else if (entity instanceof Monster) { + return PvPMod.config.espMobColor; + } + return 0; // No ESP for this entity + } +} \ No newline at end of file diff --git a/src/main/java/com/example/pvpmod/features/HUD.java b/src/main/java/com/example/pvpmod/features/HUD.java new file mode 100644 index 0000000..aa1baf2 --- /dev/null +++ b/src/main/java/com/example/pvpmod/features/HUD.java @@ -0,0 +1,133 @@ +package com.example.pvpmod.features; + +import com.example.pvpmod.PvPMod; +import com.example.pvpmod.client.ModKeyBindings; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; + +public class HUD { + private final Minecraft mc = Minecraft.getInstance(); + + public void render(GuiGraphics guiGraphics) { + if (mc.player == null) return; + + int x = PvPMod.config.hudX; + int y = PvPMod.config.hudY; + + // Render background + guiGraphics.fill(x - 5, y - 5, x + 200, y + 150, PvPMod.config.hudBackgroundColor); + + // Title + guiGraphics.drawString(mc.font, "PvP Mod", x, y, PvPMod.config.hudTextColor); + y += 15; + + // Target HUD + if (PvPMod.config.showTargetHUD) { + renderTargetHUD(guiGraphics, x, y); + y += 30; + } + + // Keybinds + if (PvPMod.config.showKeybinds) { + renderKeybinds(guiGraphics, x, y); + y += 40; + } + + // Potions + if (PvPMod.config.showPotions) { + renderPotions(guiGraphics, x, y); + y += 30; + } + + // Armor + if (PvPMod.config.showArmor) { + renderArmor(guiGraphics, x, y); + } + } + + private void renderTargetHUD(GuiGraphics guiGraphics, int x, int y) { + LivingEntity target = PvPMod.killAura.getCurrentTarget(); + + guiGraphics.drawString(mc.font, "Target:", x, y, PvPMod.config.hudTextColor); + + if (target != null) { + String targetName = target.getName().getString(); + float health = target.getHealth(); + float maxHealth = target.getMaxHealth(); + + guiGraphics.drawString(mc.font, targetName, x + 50, y, PvPMod.config.hudTextColor); + guiGraphics.drawString(mc.font, String.format("HP: %.1f/%.1f", health, maxHealth), x, y + 10, PvPMod.config.hudTextColor); + + // Health bar + int barWidth = 100; + int barHeight = 4; + float healthPercent = health / maxHealth; + + guiGraphics.fill(x, y + 20, x + barWidth, y + 20 + barHeight, 0xFF333333); + guiGraphics.fill(x, y + 20, x + (int)(barWidth * healthPercent), y + 20 + barHeight, 0xFF00FF00); + } else { + guiGraphics.drawString(mc.font, "None", x + 50, y, 0xFF888888); + } + } + + private void renderKeybinds(GuiGraphics guiGraphics, int x, int y) { + guiGraphics.drawString(mc.font, "Keybinds:", x, y, PvPMod.config.hudTextColor); + + String killAuraStatus = PvPMod.config.killAuraEnabled ? "ON" : "OFF"; + String triggerBotStatus = PvPMod.config.triggerBotEnabled ? "ON" : "OFF"; + String espStatus = PvPMod.config.espEnabled ? "ON" : "OFF"; + + guiGraphics.drawString(mc.font, "KillAura [R]: " + killAuraStatus, x, y + 10, + PvPMod.config.killAuraEnabled ? 0xFF00FF00 : 0xFF888888); + guiGraphics.drawString(mc.font, "TriggerBot [T]: " + triggerBotStatus, x, y + 20, + PvPMod.config.triggerBotEnabled ? 0xFF00FF00 : 0xFF888888); + guiGraphics.drawString(mc.font, "ESP [B]: " + espStatus, x, y + 30, + PvPMod.config.espEnabled ? 0xFF00FF00 : 0xFF888888); + } + + private void renderPotions(GuiGraphics guiGraphics, int x, int y) { + guiGraphics.drawString(mc.font, "Effects:", x, y, PvPMod.config.hudTextColor); + + int effectY = y + 10; + for (MobEffectInstance effect : mc.player.getActiveEffects()) { + String effectName = effect.getEffect().getDisplayName().getString(); + int duration = effect.getDuration() / 20; // Convert to seconds + int amplifier = effect.getAmplifier() + 1; + + String effectText = String.format("%s %d (%d:%02d)", effectName, amplifier, duration / 60, duration % 60); + guiGraphics.drawString(mc.font, effectText, x, effectY, PvPMod.config.hudTextColor); + effectY += 10; + } + } + + private void renderArmor(GuiGraphics guiGraphics, int x, int y) { + guiGraphics.drawString(mc.font, "Armor:", x, y, PvPMod.config.hudTextColor); + + ItemStack[] armorItems = { + mc.player.getInventory().getArmor(3), // Helmet + mc.player.getInventory().getArmor(2), // Chestplate + mc.player.getInventory().getArmor(1), // Leggings + mc.player.getInventory().getArmor(0) // Boots + }; + + String[] armorNames = {"Helmet", "Chest", "Legs", "Boots"}; + + for (int i = 0; i < armorItems.length; i++) { + ItemStack armor = armorItems[i]; + String armorText; + + if (armor.isEmpty()) { + armorText = armorNames[i] + ": None"; + } else { + int durability = armor.getMaxDamage() - armor.getDamageValue(); + int maxDurability = armor.getMaxDamage(); + armorText = String.format("%s: %d/%d", armorNames[i], durability, maxDurability); + } + + guiGraphics.drawString(mc.font, armorText, x, y + 10 + (i * 10), PvPMod.config.hudTextColor); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/example/pvpmod/features/HitboxExpander.java b/src/main/java/com/example/pvpmod/features/HitboxExpander.java new file mode 100644 index 0000000..35bd6c3 --- /dev/null +++ b/src/main/java/com/example/pvpmod/features/HitboxExpander.java @@ -0,0 +1,46 @@ +package com.example.pvpmod.features; + +import com.example.pvpmod.PvPMod; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.phys.AABB; +import net.minecraftforge.event.entity.EntityEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +public class HitboxExpander { + + @SubscribeEvent + public void onEntityConstruct(EntityEvent.EntityConstructing event) { + if (!PvPMod.config.hitboxExpanderEnabled) return; + + Entity entity = event.getEntity(); + if (entity == null) return; + + // Expand hitbox for all entities except the player + if (entity != net.minecraft.client.Minecraft.getInstance().player) { + expandHitbox(entity); + } + } + + private void expandHitbox(Entity entity) { + AABB originalBox = entity.getBoundingBox(); + float expansion = PvPMod.config.hitboxSize - 1.0f; + + if (expansion > 0) { + AABB expandedBox = originalBox.inflate(expansion); + entity.setBoundingBox(expandedBox); + } + } + + public void updateHitboxes() { + if (!PvPMod.config.hitboxExpanderEnabled) return; + + net.minecraft.client.Minecraft mc = net.minecraft.client.Minecraft.getInstance(); + if (mc.level == null) return; + + for (Entity entity : mc.level.entitiesForRendering()) { + if (entity != mc.player) { + expandHitbox(entity); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/example/pvpmod/features/KillAura.java b/src/main/java/com/example/pvpmod/features/KillAura.java new file mode 100644 index 0000000..6e09f77 --- /dev/null +++ b/src/main/java/com/example/pvpmod/features/KillAura.java @@ -0,0 +1,91 @@ +package com.example.pvpmod.features; + +import com.example.pvpmod.PvPMod; +import com.example.pvpmod.util.RotationUtil; +import net.minecraft.client.Minecraft; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.monster.Monster; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; + +import java.util.List; + +public class KillAura { + private final Minecraft mc = Minecraft.getInstance(); + private long lastAttackTime = 0; + private LivingEntity currentTarget = null; + + public void onTick() { + if (mc.player == null || mc.level == null) return; + + // Find target + currentTarget = findTarget(); + + if (currentTarget != null) { + // Rotate towards target + Vec3 targetPos = currentTarget.getEyePosition(); + Vec3 playerPos = mc.player.getEyePosition(); + float[] rotations = RotationUtil.getRotationsToPosition(playerPos, targetPos); + + mc.player.setYRot(rotations[0]); + mc.player.setXRot(rotations[1]); + + // Attack if cooldown is ready + long currentTime = System.currentTimeMillis(); + long attackDelay = 1000 / PvPMod.config.killAuraSpeed; + + if (currentTime - lastAttackTime >= attackDelay) { + if (mc.player.getAttackStrengthScale(0.5f) > 0.9f) { + mc.gameMode.attack(mc.player, currentTarget); + mc.player.swing(mc.player.getUsedItemHand()); + lastAttackTime = currentTime; + } + } + } + } + + private LivingEntity findTarget() { + if (mc.player == null || mc.level == null) return null; + + Vec3 playerPos = mc.player.position(); + double range = PvPMod.config.killAuraRange; + + AABB searchBox = new AABB( + playerPos.x - range, playerPos.y - range, playerPos.z - range, + playerPos.x + range, playerPos.y + range, playerPos.z + range + ); + + List entities = mc.level.getEntities(mc.player, searchBox); + LivingEntity closestTarget = null; + double closestDistance = Double.MAX_VALUE; + + for (Entity entity : entities) { + if (!(entity instanceof LivingEntity living)) continue; + if (living.isDeadOrDying()) continue; + + boolean isValidTarget = false; + + if (PvPMod.config.killAuraTargetPlayers && entity instanceof Player && entity != mc.player) { + isValidTarget = true; + } else if (PvPMod.config.killAuraTargetMobs && entity instanceof Monster) { + isValidTarget = true; + } + + if (isValidTarget) { + double distance = mc.player.distanceTo(entity); + if (distance < closestDistance && distance <= range) { + closestDistance = distance; + closestTarget = living; + } + } + } + + return closestTarget; + } + + public LivingEntity getCurrentTarget() { + return currentTarget; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/pvpmod/features/TriggerBot.java b/src/main/java/com/example/pvpmod/features/TriggerBot.java new file mode 100644 index 0000000..c62dbdc --- /dev/null +++ b/src/main/java/com/example/pvpmod/features/TriggerBot.java @@ -0,0 +1,39 @@ +package com.example.pvpmod.features; + +import net.minecraft.client.Minecraft; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.phys.EntityHitResult; +import net.minecraft.world.phys.HitResult; + +public class TriggerBot { + private final Minecraft mc = Minecraft.getInstance(); + private long lastAttackTime = 0; + private static final long ATTACK_DELAY = 100; // milliseconds + + public void onTick() { + if (mc.player == null || mc.level == null) return; + + // Check if we're looking at an entity + HitResult hitResult = mc.hitResult; + if (hitResult == null || hitResult.getType() != HitResult.Type.ENTITY) return; + + EntityHitResult entityHit = (EntityHitResult) hitResult; + if (!(entityHit.getEntity() instanceof LivingEntity target)) return; + + // Don't attack ourselves + if (target == mc.player) return; + + // Check if target is alive + if (target.isDeadOrDying()) return; + + // Attack with delay to prevent spam + long currentTime = System.currentTimeMillis(); + if (currentTime - lastAttackTime >= ATTACK_DELAY) { + if (mc.player.getAttackStrengthScale(0.5f) > 0.9f) { + mc.gameMode.attack(mc.player, target); + mc.player.swing(mc.player.getUsedItemHand()); + lastAttackTime = currentTime; + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/example/pvpmod/util/RenderUtil.java b/src/main/java/com/example/pvpmod/util/RenderUtil.java new file mode 100644 index 0000000..7f33de1 --- /dev/null +++ b/src/main/java/com/example/pvpmod/util/RenderUtil.java @@ -0,0 +1,100 @@ +package com.example.pvpmod.util; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.*; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.network.chat.Component; +import org.joml.Matrix4f; + +public class RenderUtil { + + public static void drawESPBox(PoseStack poseStack, double x, double y, double z, double width, double height, int color) { + poseStack.pushPose(); + poseStack.translate(x - width/2, y, z - width/2); + + float red = ((color >> 16) & 0xFF) / 255.0f; + float green = ((color >> 8) & 0xFF) / 255.0f; + float blue = (color & 0xFF) / 255.0f; + float alpha = ((color >> 24) & 0xFF) / 255.0f; + + RenderSystem.setShader(GameRenderer::getPositionColorShader); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + RenderSystem.disableDepthTest(); + + Tesselator tesselator = Tesselator.getInstance(); + BufferBuilder buffer = tesselator.getBuilder(); + Matrix4f matrix = poseStack.last().pose(); + + // Draw outline + buffer.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR); + + // Bottom face + buffer.vertex(matrix, 0, 0, 0).color(red, green, blue, alpha).endVertex(); + buffer.vertex(matrix, (float)width, 0, 0).color(red, green, blue, alpha).endVertex(); + + buffer.vertex(matrix, (float)width, 0, 0).color(red, green, blue, alpha).endVertex(); + buffer.vertex(matrix, (float)width, 0, (float)width).color(red, green, blue, alpha).endVertex(); + + buffer.vertex(matrix, (float)width, 0, (float)width).color(red, green, blue, alpha).endVertex(); + buffer.vertex(matrix, 0, 0, (float)width).color(red, green, blue, alpha).endVertex(); + + buffer.vertex(matrix, 0, 0, (float)width).color(red, green, blue, alpha).endVertex(); + buffer.vertex(matrix, 0, 0, 0).color(red, green, blue, alpha).endVertex(); + + // Top face + buffer.vertex(matrix, 0, (float)height, 0).color(red, green, blue, alpha).endVertex(); + buffer.vertex(matrix, (float)width, (float)height, 0).color(red, green, blue, alpha).endVertex(); + + buffer.vertex(matrix, (float)width, (float)height, 0).color(red, green, blue, alpha).endVertex(); + buffer.vertex(matrix, (float)width, (float)height, (float)width).color(red, green, blue, alpha).endVertex(); + + buffer.vertex(matrix, (float)width, (float)height, (float)width).color(red, green, blue, alpha).endVertex(); + buffer.vertex(matrix, 0, (float)height, (float)width).color(red, green, blue, alpha).endVertex(); + + buffer.vertex(matrix, 0, (float)height, (float)width).color(red, green, blue, alpha).endVertex(); + buffer.vertex(matrix, 0, (float)height, 0).color(red, green, blue, alpha).endVertex(); + + // Vertical lines + buffer.vertex(matrix, 0, 0, 0).color(red, green, blue, alpha).endVertex(); + buffer.vertex(matrix, 0, (float)height, 0).color(red, green, blue, alpha).endVertex(); + + buffer.vertex(matrix, (float)width, 0, 0).color(red, green, blue, alpha).endVertex(); + buffer.vertex(matrix, (float)width, (float)height, 0).color(red, green, blue, alpha).endVertex(); + + buffer.vertex(matrix, (float)width, 0, (float)width).color(red, green, blue, alpha).endVertex(); + buffer.vertex(matrix, (float)width, (float)height, (float)width).color(red, green, blue, alpha).endVertex(); + + buffer.vertex(matrix, 0, 0, (float)width).color(red, green, blue, alpha).endVertex(); + buffer.vertex(matrix, 0, (float)height, (float)width).color(red, green, blue, alpha).endVertex(); + + tesselator.end(); + + RenderSystem.enableDepthTest(); + RenderSystem.disableBlend(); + + poseStack.popPose(); + } + + public static void drawNameTag(PoseStack poseStack, String text, double x, double y, double z, int color) { + Minecraft mc = Minecraft.getInstance(); + + poseStack.pushPose(); + poseStack.translate(x, y, z); + poseStack.mulPose(mc.gameRenderer.getMainCamera().rotation()); + poseStack.scale(-0.025f, -0.025f, 0.025f); + + Matrix4f matrix = poseStack.last().pose(); + + MultiBufferSource.BufferSource bufferSource = mc.renderBuffers().bufferSource(); + + int textWidth = mc.font.width(text); + mc.font.drawInBatch(text, -textWidth / 2.0f, 0, color, false, matrix, bufferSource, false, 0, 15728880); + + bufferSource.endBatch(); + + poseStack.popPose(); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/pvpmod/util/RotationUtil.java b/src/main/java/com/example/pvpmod/util/RotationUtil.java new file mode 100644 index 0000000..8199ce3 --- /dev/null +++ b/src/main/java/com/example/pvpmod/util/RotationUtil.java @@ -0,0 +1,48 @@ +package com.example.pvpmod.util; + +import net.minecraft.util.Mth; +import net.minecraft.world.phys.Vec3; + +public class RotationUtil { + + public static float[] getRotationsToPosition(Vec3 from, Vec3 to) { + double deltaX = to.x - from.x; + double deltaY = to.y - from.y; + double deltaZ = to.z - from.z; + + double distance = Math.sqrt(deltaX * deltaX + deltaZ * deltaZ); + + float yaw = (float) Math.toDegrees(Math.atan2(deltaZ, deltaX)) - 90.0f; + float pitch = (float) -Math.toDegrees(Math.atan2(deltaY, distance)); + + return new float[]{yaw, pitch}; + } + + public static float getAngleDifference(float current, float target) { + float diff = target - current; + + // Normalize angle difference to [-180, 180] + while (diff > 180) diff -= 360; + while (diff < -180) diff += 360; + + return diff; + } + + public static float normalizeAngle(float angle) { + angle = angle % 360.0f; + if (angle < 0) { + angle += 360.0f; + } + return angle; + } + + public static Vec3 getVectorForRotation(float pitch, float yaw) { + float f = pitch * ((float)Math.PI / 180F); + float f1 = -yaw * ((float)Math.PI / 180F); + float f2 = Mth.cos(f1); + float f3 = Mth.sin(f1); + float f4 = Mth.cos(f); + float f5 = Mth.sin(f); + return new Vec3(f3 * f4, -f5, f2 * f4); + } +} \ No newline at end of file diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml new file mode 100644 index 0000000..689d6b8 --- /dev/null +++ b/src/main/resources/META-INF/mods.toml @@ -0,0 +1,25 @@ +modLoader="javafml" +loaderVersion="[47,)" +license="MIT" + +[[mods]] +modId="pvpmod" +version="${file.jarVersion}" +displayName="PvP Mod" +description=''' +PvP enhancement mod with KillAura, Triggerbot, Hitbox, Aim, ESP, and HUD features. +''' + +[[dependencies.pvpmod]] +modId="forge" +mandatory=true +versionRange="[47,)" +ordering="NONE" +side="BOTH" + +[[dependencies.pvpmod]] +modId="minecraft" +mandatory=true +versionRange="[1.20.1,1.21)" +ordering="NONE" +side="BOTH" \ No newline at end of file diff --git a/src/main/resources/assets/pvpmod/lang/en_us.json b/src/main/resources/assets/pvpmod/lang/en_us.json new file mode 100644 index 0000000..6918af5 --- /dev/null +++ b/src/main/resources/assets/pvpmod/lang/en_us.json @@ -0,0 +1,7 @@ +{ + "key.categories.pvpmod": "PvP Mod", + "key.pvpmod.open_menu": "Open Menu", + "key.pvpmod.toggle_killaura": "Toggle KillAura", + "key.pvpmod.toggle_triggerbot": "Toggle TriggerBot", + "key.pvpmod.toggle_esp": "Toggle ESP" +} \ No newline at end of file