Skip to content

Commit

Permalink
Refactor horse entity handling and update access widener mappings.
Browse files Browse the repository at this point in the history
  • Loading branch information
Lyzev committed Jan 1, 2025
1 parent 5af64d2 commit e02e800
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 59 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ repositories {

dependencies {
minecraft(libs.minecraft)
mappings(loom.officialMojangMappings())
mappings(libs.yarn)
modImplementation(libs.fabric.loader)
modImplementation(libs.fabric.language.kotlin)

Expand Down
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
kotlin = "2.1.0"
fabric-loom = "1.9-SNAPSHOT"
minecraft = "1.21.4"
yarn = "1.21.4+build.4"
loader = "0.16.9"
kotlin-loader = "1.13.0+kotlin.2.1.0"
fabric-api = "0.114.0+1.21.4"

[libraries]
minecraft = { group = "com.mojang", name = "minecraft", version.ref = "minecraft" }
yarn = { module = "net.fabricmc:yarn", version.ref = "yarn" }
fabric-loader = { group = "net.fabricmc", name = "fabric-loader", version.ref = "loader" }
fabric-language-kotlin = { group = "net.fabricmc", name = "fabric-language-kotlin", version.ref = "kotlin-loader" }
fabric-api = { group = "net.fabricmc.fabric-api", name = "fabric-api", version.ref = "fabric-api" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,47 +18,44 @@
package dev.lyzev.hp.mixin;

import dev.lyzev.hp.HorsePower;
import kotlin.math.MathKt;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.inventory.HorseInventoryScreen;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.animal.horse.AbstractHorse;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ingame.HorseScreen;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.passive.AbstractHorseEntity;
import org.spongepowered.asm.mixin.Final;
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.CallbackInfo;

@Mixin(HorseInventoryScreen.class)
public class HorseInventoryScreenMixin {
@Mixin(HorseScreen.class)
public class HorseScreenMixin {

@Shadow
@Final
private int inventoryColumns;
private AbstractHorseEntity entity;

@Shadow
@Final
private AbstractHorse horse;

@Inject(method = "renderBg", at = @At("RETURN"))
private void renderBg(GuiGraphics guiGraphics, float f, int i, int j, CallbackInfo ci) {
@Inject(method = "drawBackground", at = @At("RETURN"))
private void onDrawBackground(DrawContext drawContext, float f, int i, int j, CallbackInfo ci) {
// TODO: Add indicator to the horse inventory screen to show the attributes of the horse
if (inventoryColumns > 0) {
if (entity.getInventoryColumns() > 0) {
} else {
int imageWidth = 176;
int imageHeight = 166;
int x = HorsePower.INSTANCE.getMc().getWindow().getGuiScaledWidth() / 2 - imageWidth / 2 + 82;
int y = HorsePower.INSTANCE.getMc().getWindow().getGuiScaledHeight() / 2 - imageHeight / 2 + 20;
AbstractHorse horse = this.horse;

double speedMovement = Math.round(horse.getAttributeBaseValue(Attributes.MOVEMENT_SPEED) * 100) / 100.0;
double jumpHeight = Math.round(horse.getAttributeBaseValue(Attributes.JUMP_STRENGTH) * 100) / 100.0;
double health = Math.round(horse.getAttributeBaseValue(Attributes.MAX_HEALTH) * 100) / 100.0;
guiGraphics.drawString(HorsePower.INSTANCE.getMc().font, "Speed: " + speedMovement, x, y, 0xFFFFFF);
guiGraphics.drawString(HorsePower.INSTANCE.getMc().font, "Jump: " + jumpHeight, x, y + 10, 0xFFFFFF);
guiGraphics.drawString(HorsePower.INSTANCE.getMc().font, "Health: " + health, x, y + 20, 0xFFFFFF);
int x = HorsePower.INSTANCE.getMc().getWindow().getScaledWidth() / 2 - imageWidth / 2 + 82;
int y = HorsePower.INSTANCE.getMc().getWindow().getScaledHeight() / 2 - imageHeight / 2 + 20;

AbstractHorseEntity horse = this.entity;

double speedMovement = Math.round(horse.getAttributeBaseValue(EntityAttributes.MOVEMENT_SPEED) * 100) / 100.0;
double jumpHeight = Math.round(horse.getAttributeBaseValue(EntityAttributes.JUMP_STRENGTH) * 100) / 100.0;
double health = Math.round(horse.getAttributeBaseValue(EntityAttributes.MAX_HEALTH) * 100) / 100.0;

drawContext.drawText(HorsePower.INSTANCE.getMc().textRenderer, "Speed: " + speedMovement, x, y, 0xFFFFFF, true);
drawContext.drawText(HorsePower.INSTANCE.getMc().textRenderer, "Jump: " + jumpHeight, x, y + 10, 0xFFFFFF, true);
drawContext.drawText(HorsePower.INSTANCE.getMc().textRenderer, "Health: " + health, x, y + 20, 0xFFFFFF, true);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,20 @@
package dev.lyzev.hp.mixin;

import dev.lyzev.hp.HorsePower;
import net.minecraft.client.Minecraft;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.animal.horse.AbstractHorse;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.Entity;
import net.minecraft.entity.passive.AbstractHorseEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Mixin(Minecraft.class)
public class MinecraftMixin {
@Mixin(MinecraftClient.class)
public class MinecraftClientMixin {

@Inject(method = "shouldEntityAppearGlowing", at = @At("HEAD"), cancellable = true)
@Inject(method = "hasOutline", at = @At("HEAD"), cancellable = true)
private void shouldEntityAppearGlowing(Entity entity, CallbackInfoReturnable<Boolean> cir) {
if (entity instanceof AbstractHorse) {
if (entity instanceof AbstractHorseEntity) {
if (System.currentTimeMillis() - HorsePower.INSTANCE.getLast() <= 5000 && HorsePower.INSTANCE.getHorses().contains(entity)) {
cir.setReturnValue(true);
cir.cancel();
Expand Down
35 changes: 17 additions & 18 deletions src/main/kotlin/dev/lyzev/hp/HorsePower.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,20 @@ import net.fabricmc.api.ClientModInitializer
import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource
import net.minecraft.ChatFormatting
import net.minecraft.client.Minecraft
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.Style
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.ai.attributes.Attributes
import net.minecraft.world.entity.animal.horse.AbstractHorse
import net.minecraft.world.entity.animal.horse.Donkey
import net.minecraft.world.entity.animal.horse.Horse
import net.minecraft.world.entity.animal.horse.Mule
import net.minecraft.client.MinecraftClient
import net.minecraft.entity.Entity
import net.minecraft.entity.attribute.EntityAttributes
import net.minecraft.entity.passive.AbstractHorseEntity
import net.minecraft.entity.passive.DonkeyEntity
import net.minecraft.entity.passive.HorseEntity
import net.minecraft.entity.passive.MuleEntity
import net.minecraft.text.Text
import net.minecraft.util.Formatting


object HorsePower : ClientModInitializer {

val mc = Minecraft.getInstance()
val mc = MinecraftClient.getInstance()

var last = System.currentTimeMillis()
val horses = mutableListOf<Entity>()
Expand All @@ -46,21 +45,21 @@ object HorsePower : ClientModInitializer {
dispatcher.register(
ClientCommandManager.literal("search")
.executes { context: CommandContext<FabricClientCommandSource> ->
val horses = mc.level!!.entitiesForRendering().filter { it is Horse || it is Donkey || it is Mule }.sortedBy {
val horse = it as AbstractHorse
val movementSpeed = horse.getAttributeBaseValue(Attributes.MOVEMENT_SPEED).coerceIn(AbstractHorse.MIN_MOVEMENT_SPEED.toDouble(), AbstractHorse.MAX_MOVEMENT_SPEED.toDouble()) / AbstractHorse.MAX_MOVEMENT_SPEED.toDouble()
val jumpStrength = horse.getAttributeBaseValue(Attributes.JUMP_STRENGTH).coerceIn(AbstractHorse.MIN_JUMP_STRENGTH.toDouble(), AbstractHorse.MAX_JUMP_STRENGTH.toDouble()) / AbstractHorse.MAX_JUMP_STRENGTH.toDouble()
val health = horse.getAttributeBaseValue(Attributes.MAX_HEALTH).coerceIn(AbstractHorse.MIN_HEALTH.toDouble(), AbstractHorse.MAX_HEALTH.toDouble()) / AbstractHorse.MAX_HEALTH.toDouble()
val horses = mc.world!!.entities.filter { it is HorseEntity || it is DonkeyEntity || it is MuleEntity }.sortedBy {
val horse = it as AbstractHorseEntity
val movementSpeed = horse.getAttributeBaseValue(EntityAttributes.MOVEMENT_SPEED).coerceIn(AbstractHorseEntity.MIN_MOVEMENT_SPEED_BONUS.toDouble(), AbstractHorseEntity.MAX_MOVEMENT_SPEED_BONUS.toDouble()) / AbstractHorseEntity.MAX_MOVEMENT_SPEED_BONUS.toDouble()
val jumpStrength = horse.getAttributeBaseValue(EntityAttributes.JUMP_STRENGTH).coerceIn(AbstractHorseEntity.MIN_JUMP_STRENGTH_BONUS.toDouble(), AbstractHorseEntity.MAX_JUMP_STRENGTH_BONUS.toDouble()) / AbstractHorseEntity.MAX_JUMP_STRENGTH_BONUS.toDouble()
val health = horse.getAttributeBaseValue(EntityAttributes.MAX_HEALTH).coerceIn(AbstractHorseEntity.MIN_HEALTH_BONUS.toDouble(), AbstractHorseEntity.MAX_HEALTH_BONUS.toDouble()) / AbstractHorseEntity.MAX_HEALTH_BONUS.toDouble()
movementSpeed + jumpStrength + health
}
if (horses.isEmpty()) {
context.source.sendError(Component.translatable("hp.search.error"))
context.source.sendError(Text.translatable("hp.search.error"))
0
} else {
last = System.currentTimeMillis()
this.horses.clear()
this.horses += horses.take(2)
context.source.sendFeedback(Component.translatable(if (horses.count() == 1) "hp.search.success.one" else "hp.search.success.two").withColor(ChatFormatting.GREEN.color!!))
context.source.sendFeedback(Text.translatable(if (horses.count() == 1) "hp.search.success.one" else "hp.search.success.two").withColor(Formatting.GREEN.colorValue!!))
1
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/main/resources/horsepower.accesswidener
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
accessWidener v2 named
accessible field net/minecraft/world/entity/animal/horse/AbstractHorse MIN_MOVEMENT_SPEED F
accessible field net/minecraft/world/entity/animal/horse/AbstractHorse MAX_MOVEMENT_SPEED F
accessible field net/minecraft/world/entity/animal/horse/AbstractHorse MIN_JUMP_STRENGTH F
accessible field net/minecraft/world/entity/animal/horse/AbstractHorse MAX_JUMP_STRENGTH F
accessible field net/minecraft/world/entity/animal/horse/AbstractHorse MIN_HEALTH F
accessible field net/minecraft/world/entity/animal/horse/AbstractHorse MAX_HEALTH F
accessible field net/minecraft/entity/passive/AbstractHorseEntity MIN_MOVEMENT_SPEED_BONUS F
accessible field net/minecraft/entity/passive/AbstractHorseEntity MAX_MOVEMENT_SPEED_BONUS F
accessible field net/minecraft/entity/passive/AbstractHorseEntity MIN_JUMP_STRENGTH_BONUS F
accessible field net/minecraft/entity/passive/AbstractHorseEntity MAX_JUMP_STRENGTH_BONUS F
accessible field net/minecraft/entity/passive/AbstractHorseEntity MIN_HEALTH_BONUS F
accessible field net/minecraft/entity/passive/AbstractHorseEntity MAX_HEALTH_BONUS F

4 changes: 2 additions & 2 deletions src/main/resources/horsepower.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"mixins": [
],
"client": [
"HorseInventoryScreenMixin",
"MinecraftMixin"
"HorseScreenMixin",
"MinecraftClientMixin"
],
"injectors": {
"defaultRequire": 1
Expand Down

0 comments on commit e02e800

Please sign in to comment.