automatic target selection

This commit is contained in:
2026-02-16 16:36:56 +01:00
parent cf7adf9953
commit 131978a020
4 changed files with 18 additions and 126 deletions

View File

@@ -2,76 +2,18 @@ package com.kasetoatz.elytramace;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.util.InputUtil;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.attribute.EntityAttributes; import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.entity.projectile.ProjectileUtil;
import net.minecraft.item.*; import net.minecraft.item.*;
import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.registry.tag.ItemTags; import net.minecraft.registry.tag.ItemTags;
import net.minecraft.screen.slot.SlotActionType; import net.minecraft.screen.slot.SlotActionType;
import net.minecraft.util.Identifier;
import net.minecraft.util.hit.EntityHitResult; import java.util.Comparator;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
import org.lwjgl.glfw.GLFW;
public class ElytraMace implements ClientModInitializer public class ElytraMace implements ClientModInitializer
{ {
private MinecraftClient client;
private final KeyBinding.Category keybindCategory = KeyBinding.Category.create(Identifier.of("elytramace", "elytramace"));
private final KeyBinding selectTargetKeybind = KeyBindingHelper.registerKeyBinding(
new KeyBinding(
"key.elytramace.select_target",
InputUtil.Type.KEYSYM,
GLFW.GLFW_KEY_KP_8,
keybindCategory
)
);
public static LivingEntity TARGET;
private boolean unequipped = false; private boolean unequipped = false;
private boolean lockTarget = false;
private LivingEntity getTarget()
{
Entity camera = client.getCameraEntity();
if (camera == null)
{
return null;
}
HitResult hitResult = camera.raycast(client.options.getSimulationDistance().getValue() * 16, 0F, false);
Vec3d start = camera.getCameraPosVec(0F);
double squaredDist = hitResult.getPos().squaredDistanceTo(start);
double newDist = Math.sqrt(squaredDist);
Vec3d rotation = camera.getRotationVec(0F);
Vec3d end = start.add(rotation.multiply(newDist));
Box box = camera.getBoundingBox().stretch(rotation.multiply(newDist)).expand(1D);
EntityHitResult result = ProjectileUtil.raycast(camera, start, end, box, EntityPredicates.CAN_HIT, squaredDist);
if (result == null || !(result.getEntity() instanceof LivingEntity))
{
return null;
}
return (LivingEntity)result.getEntity();
}
private void updateTarget()
{
LivingEntity nextTarget = getTarget();
if (nextTarget == TARGET)
{
TARGET = null;
}
else if (nextTarget != null)
{
TARGET = nextTarget;
}
}
private int getItem(PlayerInventory inventory, Item item) private int getItem(PlayerInventory inventory, Item item)
{ {
@@ -105,44 +47,37 @@ public class ElytraMace implements ClientModInitializer
@Override @Override
public void onInitializeClient() public void onInitializeClient()
{ {
client = MinecraftClient.getInstance();
ClientTickEvents.END_CLIENT_TICK.register(client -> { ClientTickEvents.END_CLIENT_TICK.register(client -> {
if (client.player == null || client.interactionManager == null || client.getNetworkHandler() == null) if (client.player == null || client.interactionManager == null || client.world == null)
{ {
return; return;
} }
LivingEntity target = client.world.getEntitiesByClass(LivingEntity.class, client.player.getBoundingBox().expand(client.player.getAttributeValue(EntityAttributes.ENTITY_INTERACTION_RANGE) + client.player.getVelocity().length() * 2), e -> e != client.player).stream().min(Comparator.comparingDouble(client.player::squaredDistanceTo)).orElse(null);
if (unequipped && !client.player.isGliding()) if (unequipped && !client.player.isGliding())
{ {
client.interactionManager.clickSlot(client.player.playerScreenHandler.syncId, 6, 0, SlotActionType.PICKUP, client.player); client.interactionManager.clickSlot(client.player.playerScreenHandler.syncId, 6, 0, SlotActionType.PICKUP, client.player);
unequipped = false; unequipped = false;
PlayerInventory inventory = client.player.getInventory(); if (target != null)
int axe = getAxe(inventory);
int mace = getItem(inventory, Items.MACE);
int fireworks = getItem(inventory, Items.FIREWORK_ROCKET);
if (TARGET.isBlocking() && axe > -1)
{ {
inventory.setSelectedSlot(axe); PlayerInventory inventory = client.player.getInventory();
client.interactionManager.attackEntity(client.player, TARGET); int axe = getAxe(inventory);
int mace = getItem(inventory, Items.MACE);
int fireworks = getItem(inventory, Items.FIREWORK_ROCKET);
if (target.isBlocking() && axe > -1)
{
inventory.setSelectedSlot(axe);
client.interactionManager.attackEntity(client.player, target);
}
inventory.setSelectedSlot(mace);
client.interactionManager.attackEntity(client.player, target);
inventory.setSelectedSlot(fireworks);
} }
inventory.setSelectedSlot(mace);
client.interactionManager.attackEntity(client.player, TARGET);
inventory.setSelectedSlot(fireworks);
lockTarget = false;
} }
if (TARGET != null && client.player.isGliding() && !unequipped && client.player.distanceTo(TARGET) <= client.player.getAttributeValue(EntityAttributes.ENTITY_INTERACTION_RANGE) + client.player.getVelocity().length() * 2) if (!unequipped && target != null && client.player.isGliding())
{ {
lockTarget = true;
client.interactionManager.clickSlot(client.player.playerScreenHandler.syncId, 6, 0, SlotActionType.PICKUP, client.player); client.interactionManager.clickSlot(client.player.playerScreenHandler.syncId, 6, 0, SlotActionType.PICKUP, client.player);
unequipped = true; unequipped = true;
} }
while (selectTargetKeybind.wasPressed() && !lockTarget)
{
updateTarget();
}
if (TARGET != null && !TARGET.isAlive())
{
TARGET = null;
}
}); });
} }
} }

View File

@@ -1,25 +0,0 @@
package com.kasetoatz.elytramace.mixin;
import net.minecraft.entity.Entity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import static com.kasetoatz.elytramace.ElytraMace.TARGET;
@Mixin(Entity.class)
public class EntityMixin
{
@Shadow private boolean glowing;
@Inject(method="isGlowing", at=@At("HEAD"), cancellable=true)
public void isGlowing(CallbackInfoReturnable<Boolean> cir)
{
if ((Object)this == TARGET)
{
cir.setReturnValue(true);
}
}
}

View File

@@ -1,15 +0,0 @@
{
"required": true,
"minVersion": "0.8",
"package": "com.kasetoatz.elytramace.mixin",
"compatibilityLevel": "JAVA_21",
"client": [
"EntityMixin"
],
"injectors": {
"defaultRequire": 1
},
"overwrites": {
"requireAnnotations": true
}
}

View File

@@ -14,9 +14,6 @@
"com.kasetoatz.elytramace.ElytraMace" "com.kasetoatz.elytramace.ElytraMace"
] ]
}, },
"mixins": [
"elytramace.mixins.json"
],
"depends": { "depends": {
"fabricloader": ">=${loader_version}", "fabricloader": ">=${loader_version}",
"fabric-api": "*", "fabric-api": "*",