Initial project setup for ElytraMace mod
Add Gradle build files, MIT license, and .gitignore. Implement ElytraMace client mod with keybindings for target selection and attack, including mixin for entity glowing effect. Register mod metadata and mixins configuration for Fabric loader.
This commit is contained in:
147
src/main/java/com/kasetoatz/elytramace/ElytraMace.java
Normal file
147
src/main/java/com/kasetoatz/elytramace/ElytraMace.java
Normal file
@@ -0,0 +1,147 @@
|
||||
package com.kasetoatz.elytramace;
|
||||
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
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.network.ClientPlayerInteractionManager;
|
||||
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.player.PlayerInventory;
|
||||
import net.minecraft.entity.projectile.ProjectileUtil;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.predicate.entity.EntityPredicates;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.hit.EntityHitResult;
|
||||
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
|
||||
{
|
||||
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
|
||||
)
|
||||
);
|
||||
private final KeyBinding attackKeybind = KeyBindingHelper.registerKeyBinding(
|
||||
new KeyBinding(
|
||||
"key.elytramace.attack",
|
||||
InputUtil.Type.KEYSYM,
|
||||
GLFW.GLFW_KEY_KP_7,
|
||||
keybindCategory
|
||||
)
|
||||
);
|
||||
private KeyBinding cancelFlightKeybind;
|
||||
public static LivingEntity TARGET;
|
||||
private boolean isAttacking = 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 getCancelFlightKeybind()
|
||||
{
|
||||
for (KeyBinding keybind : client.options.allKeys)
|
||||
{
|
||||
if (keybind.getBoundKeyTranslationKey().equals("key.elytracancel.cancel_flight"))
|
||||
{
|
||||
cancelFlightKeybind = keybind;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTarget()
|
||||
{
|
||||
LivingEntity nextTarget = getTarget();
|
||||
if (nextTarget == TARGET)
|
||||
{
|
||||
TARGET = null;
|
||||
}
|
||||
else if (nextTarget != null)
|
||||
{
|
||||
TARGET = nextTarget;
|
||||
}
|
||||
}
|
||||
|
||||
private int getItemIndex(PlayerInventory inventory, Item item)
|
||||
{
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
if (inventory.getStack(i).isOf(item))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void attack()
|
||||
{
|
||||
if (client.player == null || client.interactionManager == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
isAttacking = true;
|
||||
PlayerInventory inventory = client.player.getInventory();
|
||||
ClientPlayerInteractionManager manager = client.interactionManager;
|
||||
int fireworkSlot = getItemIndex(inventory, Items.FIREWORK_ROCKET);
|
||||
int maceSlot = getItemIndex(inventory, Items.MACE);
|
||||
if (fireworkSlot == -1 || maceSlot == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
inventory.setSelectedSlot(fireworkSlot);
|
||||
manager.interactItem(client.player, Hand.MAIN_HAND);
|
||||
isAttacking = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitializeClient()
|
||||
{
|
||||
client = MinecraftClient.getInstance();
|
||||
ClientTickEvents.END_CLIENT_TICK.register(client -> {
|
||||
if (cancelFlightKeybind == null && client.options != null)
|
||||
{
|
||||
getCancelFlightKeybind();
|
||||
}
|
||||
while (selectTargetKeybind.wasPressed() && !isAttacking)
|
||||
{
|
||||
updateTarget();
|
||||
}
|
||||
while (attackKeybind.wasPressed() && TARGET != null && !isAttacking)
|
||||
{
|
||||
attack();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user