From 3a93c3beaefc52926a24f93aafd7885a9d4f976a Mon Sep 17 00:00:00 2001 From: Octol1ttle Date: Wed, 17 Jan 2024 22:51:32 +0500 Subject: [PATCH] make everything work --- build.gradle | 2 +- .../knockdowns/common/KnockdownsClient.java | 44 ++++++ .../knockdowns/common/KnockdownsCommon.java | 8 + .../knockdowns/common/api/IKnockableDown.java | 18 ++- .../common/events/KnockdownsClientEvents.java | 107 +++----------- .../common/events/KnockdownsEvents.java | 79 +++++++--- .../common/mixin/LivingEntityMixin.java | 15 ++ .../common/mixin/MobEntityMixin.java | 19 +++ .../common/mixin/PlayerEntityMixin.java | 94 ++++++++---- .../mixin/client/ClientPlayerEntityMixin.java | 5 +- .../common/network/KnockdownsNetwork.java | 42 +----- .../packets/KnockedDownStatusPacket.java | 69 --------- .../RequestStartRevivingC2SPacket.java | 39 +++++ .../network/packets/ReviveStatusPacket.java | 138 ------------------ .../packets/StopRevivingC2SPacket.java | 41 ++++++ .../assets/knockdowns/lang/en_us.json | 5 +- .../assets/knockdowns/lang/ru_ru.json | 5 +- .../resources/knockdowns-common.mixins.json | 2 + .../main/resources/knockdowns.accesswidener | 5 +- 19 files changed, 346 insertions(+), 391 deletions(-) create mode 100644 common/src/main/java/ru/octol1ttle/knockdowns/common/mixin/LivingEntityMixin.java create mode 100644 common/src/main/java/ru/octol1ttle/knockdowns/common/mixin/MobEntityMixin.java delete mode 100644 common/src/main/java/ru/octol1ttle/knockdowns/common/network/packets/KnockedDownStatusPacket.java create mode 100644 common/src/main/java/ru/octol1ttle/knockdowns/common/network/packets/RequestStartRevivingC2SPacket.java delete mode 100644 common/src/main/java/ru/octol1ttle/knockdowns/common/network/packets/ReviveStatusPacket.java create mode 100644 common/src/main/java/ru/octol1ttle/knockdowns/common/network/packets/StopRevivingC2SPacket.java diff --git a/build.gradle b/build.gradle index b4c6a6d..df015f7 100644 --- a/build.gradle +++ b/build.gradle @@ -41,7 +41,7 @@ allprojects { // for more information about repositories. } - tasks.withType(JavaCompile) { + tasks.withType(JavaCompile).configureEach { options.encoding = "UTF-8" options.release = 17 } diff --git a/common/src/main/java/ru/octol1ttle/knockdowns/common/KnockdownsClient.java b/common/src/main/java/ru/octol1ttle/knockdowns/common/KnockdownsClient.java index 1929320..79f04c3 100644 --- a/common/src/main/java/ru/octol1ttle/knockdowns/common/KnockdownsClient.java +++ b/common/src/main/java/ru/octol1ttle/knockdowns/common/KnockdownsClient.java @@ -1,12 +1,25 @@ package ru.octol1ttle.knockdowns.common; +import dev.architectury.event.EventResult; import net.minecraft.client.MinecraftClient; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.hit.EntityHitResult; +import net.minecraft.util.hit.HitResult; import net.minecraft.util.math.Vec3d; +import org.jetbrains.annotations.Nullable; +import ru.octol1ttle.knockdowns.common.api.IKnockableDown; import ru.octol1ttle.knockdowns.common.events.KnockdownsClientEvents; +import ru.octol1ttle.knockdowns.common.network.KnockdownsNetwork; +import ru.octol1ttle.knockdowns.common.network.packets.RequestStartRevivingC2SPacket; +import ru.octol1ttle.knockdowns.common.network.packets.StopRevivingC2SPacket; import ru.octol1ttle.knockdowns.common.registries.KnockdownsSoundEvents; import ru.octol1ttle.knockdowns.common.registries.KnockedDownSoundInstance; public class KnockdownsClient { + @Nullable + public static Entity reviving; + public static void init() { KnockdownsClientEvents.registerCallbacks(); } @@ -16,4 +29,35 @@ public class KnockdownsClient { new KnockedDownSoundInstance(KnockdownsSoundEvents.KNOCKED_DOWN.get(), pos) ); } + + public static EventResult onEntityUse(PlayerEntity player, Entity entity) { + if (KnockdownsCommon.isKnockedOrReviving(player) || !(entity instanceof IKnockableDown knockable) || !knockable.is_KnockedDown()) { + return EventResult.pass(); + } + + KnockdownsNetwork.sendToServer(new RequestStartRevivingC2SPacket(entity.getUuid())); + reviving = entity; + + return EventResult.interruptTrue(); + } + + public static void onPlayerTick(PlayerEntity player) { + MinecraftClient client = MinecraftClient.getInstance(); + if (!player.equals(client.player) || reviving == null) { + return; + } + + boolean playerKnocked = ((IKnockableDown) player).is_KnockedDown(); + boolean revivingTargeted = client.crosshairTarget != null && client.crosshairTarget.getType() == HitResult.Type.ENTITY + && ((EntityHitResult) client.crosshairTarget).getEntity().getUuid().equals(reviving.getUuid()); + + if (!(reviving instanceof IKnockableDown knockable)) { + return; + } + + if (!knockable.is_KnockedDown() || playerKnocked || !revivingTargeted) { + KnockdownsNetwork.sendToServer(new StopRevivingC2SPacket(reviving.getUuid())); + reviving = null; + } + } } diff --git a/common/src/main/java/ru/octol1ttle/knockdowns/common/KnockdownsCommon.java b/common/src/main/java/ru/octol1ttle/knockdowns/common/KnockdownsCommon.java index 8514251..286367c 100644 --- a/common/src/main/java/ru/octol1ttle/knockdowns/common/KnockdownsCommon.java +++ b/common/src/main/java/ru/octol1ttle/knockdowns/common/KnockdownsCommon.java @@ -1,15 +1,23 @@ package ru.octol1ttle.knockdowns.common; +import net.minecraft.SharedConstants; +import net.minecraft.entity.player.PlayerEntity; +import ru.octol1ttle.knockdowns.common.api.IKnockableDown; import ru.octol1ttle.knockdowns.common.events.KnockdownsEvents; import ru.octol1ttle.knockdowns.common.network.KnockdownsNetwork; import ru.octol1ttle.knockdowns.common.registries.KnockdownsSoundEvents; public class KnockdownsCommon { public static final String MOD_ID = "knockdowns"; + public static final int REVIVE_WAIT_TIME = 10 * SharedConstants.TICKS_PER_SECOND; public static void init() { KnockdownsSoundEvents.register(); KnockdownsNetwork.registerPackets(); KnockdownsEvents.registerCallbacks(); } + + public static boolean isKnockedOrReviving(PlayerEntity player) { + return player instanceof IKnockableDown knockable && (knockable.is_KnockedDown() || knockable.is_Reviving()); + } } diff --git a/common/src/main/java/ru/octol1ttle/knockdowns/common/api/IKnockableDown.java b/common/src/main/java/ru/octol1ttle/knockdowns/common/api/IKnockableDown.java index 03f010f..74fad18 100644 --- a/common/src/main/java/ru/octol1ttle/knockdowns/common/api/IKnockableDown.java +++ b/common/src/main/java/ru/octol1ttle/knockdowns/common/api/IKnockableDown.java @@ -1,15 +1,19 @@ package ru.octol1ttle.knockdowns.common.api; -import java.util.UUID; - public interface IKnockableDown { - boolean knockdowns$isKnockedDown(); + boolean is_KnockedDown(); - void knockdowns$setKnockedDown(boolean knockedDown); + void set_KnockedDown(boolean knockedDown); - boolean knockdowns$isBeingRevived(); + int get_ReviverCount(); - void knockdowns$setBeingRevived(boolean beingRevived); + void set_ReviverCount(int reviverCount); - UUID knockdowns$getUuid(); + boolean is_Reviving(); + + void set_Reviving(boolean reviving); + + int get_ReviveTimer(); + + void set_ReviveTimer(int reviveTimer); } diff --git a/common/src/main/java/ru/octol1ttle/knockdowns/common/events/KnockdownsClientEvents.java b/common/src/main/java/ru/octol1ttle/knockdowns/common/events/KnockdownsClientEvents.java index 08daac4..47ec31d 100644 --- a/common/src/main/java/ru/octol1ttle/knockdowns/common/events/KnockdownsClientEvents.java +++ b/common/src/main/java/ru/octol1ttle/knockdowns/common/events/KnockdownsClientEvents.java @@ -1,105 +1,44 @@ package ru.octol1ttle.knockdowns.common.events; -import dev.architectury.event.EventResult; import dev.architectury.event.events.client.ClientGuiEvent; -import dev.architectury.event.events.client.ClientPlayerEvent; -import dev.architectury.event.events.client.ClientTickEvent; -import dev.architectury.event.events.common.InteractionEvent; -import java.util.UUID; import net.minecraft.SharedConstants; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; -import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.util.hit.HitResult; -import ru.octol1ttle.knockdowns.common.network.KnockdownsNetwork; +import net.minecraft.util.Formatting; +import ru.octol1ttle.knockdowns.common.KnockdownsClient; import ru.octol1ttle.knockdowns.common.api.IKnockableDown; -import ru.octol1ttle.knockdowns.common.network.packets.KnockedDownStatusPacket; -import ru.octol1ttle.knockdowns.common.network.packets.ReviveStatusPacket; public class KnockdownsClientEvents { - private static final int REVIVAL_WAIT_TIME = 10 * SharedConstants.TICKS_PER_SECOND; - private static IKnockableDown reviving = null; - private static int revivalTimer = -1; - public static void registerCallbacks() { - registerOnClientPlayerJoin(); - registerOnEntityUse(); - registerOnWorldTick(); registerOnHudRender(); } - private static void registerOnClientPlayerJoin() { - ClientPlayerEvent.CLIENT_PLAYER_JOIN.register(player -> { - UUID playerUuid = player.getUuid(); - KnockdownsNetwork.sendToServer(new KnockedDownStatusPacket.RequestC2S(playerUuid)); - KnockdownsNetwork.sendToServer(new ReviveStatusPacket.RequestC2S(playerUuid)); - }); - } - - private static void registerOnEntityUse() { - InteractionEvent.INTERACT_ENTITY.register((player, entity, hand) -> { - if (!player.getWorld().isClient() || !(entity instanceof IKnockableDown knockableEntity) || !knockableEntity.knockdowns$isKnockedDown() - || knockableEntity.knockdowns$isBeingRevived()) { - return EventResult.pass(); - } - - IKnockableDown self = (IKnockableDown) player; - if (self.knockdowns$isKnockedDown()) { - return EventResult.interruptFalse(); - } - - knockableEntity.knockdowns$setBeingRevived(true); - KnockdownsNetwork.sendToServer(new ReviveStatusPacket.SendC2S(entity.getUuid(), true)); - - reviving = knockableEntity; - revivalTimer = REVIVAL_WAIT_TIME; - - return EventResult.interruptTrue(); - }); - } - - private static void registerOnWorldTick() { - ClientTickEvent.ClientLevel.CLIENT_LEVEL_POST.register(world -> { - boolean revived = false; - revivalTimer--; - if (revivalTimer <= 0) { - revivalTimer = -1; - revived = true; - } - - if (reviving == null) { - return; - } - - HitResult crosshairTarget = MinecraftClient.getInstance().crosshairTarget; - if (revived || crosshairTarget == null || crosshairTarget.getType() != HitResult.Type.ENTITY - || !((EntityHitResult) crosshairTarget).getEntity().getUuid().equals(reviving.knockdowns$getUuid())) { - reviving.knockdowns$setBeingRevived(false); - - KnockdownsNetwork.sendToServer(new ReviveStatusPacket.SendC2S(reviving.knockdowns$getUuid(), false)); - if (revived) { - reviving.knockdowns$setKnockedDown(false); - - KnockdownsNetwork.sendToServer(new ReviveStatusPacket.RevivedC2S(reviving.knockdowns$getUuid())); - } - - reviving = null; - revivalTimer = -1; - } - }); - } - private static void registerOnHudRender() { ClientGuiEvent.RENDER_HUD.register((drawContext, tickDelta) -> { - if (revivalTimer == -1) { - return; + IKnockableDown reviving = (IKnockableDown) KnockdownsClient.reviving; + MinecraftClient client = MinecraftClient.getInstance(); + if (reviving == null) { + reviving = (IKnockableDown) client.player; + if (reviving == null || reviving.get_ReviverCount() == 0) { + return; + } } - TextRenderer renderer = MinecraftClient.getInstance().textRenderer; - String text = String.format("%.1f", revivalTimer / (float) SharedConstants.TICKS_PER_SECOND); - int x = (drawContext.getScaledWindowWidth() - renderer.getWidth(text)) / 2; + TextRenderer renderer = client.textRenderer; - drawContext.drawTextWithShadow(renderer, text, x, drawContext.getScaledWindowHeight() / 2 + 15, 0xFFFFFF); + String timerText = String.format("%.1f", reviving.get_ReviveTimer() / (float) SharedConstants.TICKS_PER_SECOND); + int timerX = (drawContext.getScaledWindowWidth() - renderer.getWidth(timerText)) / 2; + + int reviverCount = reviving.get_ReviverCount(); + Integer color = reviverCount > 1 ? Formatting.GREEN.getColorValue() : Formatting.WHITE.getColorValue(); + + String reviverCountText = "x" + reviverCount; + int reviveCountX = (drawContext.getScaledWindowWidth() - renderer.getWidth(reviverCountText)) / 2; + + if (color != null) { + drawContext.drawTextWithShadow(renderer, timerText, timerX, drawContext.getScaledWindowHeight() / 2 + 5, color); + drawContext.drawTextWithShadow(renderer, reviverCountText, reviveCountX, drawContext.getScaledWindowHeight() / 2 + 14, color); + } }); } } diff --git a/common/src/main/java/ru/octol1ttle/knockdowns/common/events/KnockdownsEvents.java b/common/src/main/java/ru/octol1ttle/knockdowns/common/events/KnockdownsEvents.java index 429a3ce..d09e8ec 100644 --- a/common/src/main/java/ru/octol1ttle/knockdowns/common/events/KnockdownsEvents.java +++ b/common/src/main/java/ru/octol1ttle/knockdowns/common/events/KnockdownsEvents.java @@ -5,46 +5,50 @@ import dev.architectury.event.EventResult; import dev.architectury.event.events.common.EntityEvent; import dev.architectury.event.events.common.InteractionEvent; import dev.architectury.event.events.common.PlayerEvent; +import dev.architectury.event.events.common.TickEvent; +import java.util.Objects; +import net.minecraft.entity.damage.DamageSource; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; import net.minecraft.text.TranslatableTextContent; import net.minecraft.util.Hand; -import net.minecraft.world.GameRules; -import ru.octol1ttle.knockdowns.common.network.KnockdownsNetwork; +import ru.octol1ttle.knockdowns.common.KnockdownsClient; +import ru.octol1ttle.knockdowns.common.KnockdownsCommon; import ru.octol1ttle.knockdowns.common.api.IKnockableDown; -import ru.octol1ttle.knockdowns.common.network.packets.KnockedDownStatusPacket; +import ru.octol1ttle.knockdowns.common.network.KnockdownsNetwork; import ru.octol1ttle.knockdowns.common.network.packets.PlayKnockedDownSoundS2CPacket; public class KnockdownsEvents { + private static final float KNOCKED_DOWN_TIMER = 50.0f; + public static void registerCallbacks() { registerOnLivingDeath(); + registerOnPlayerTick(); registerOnPlayerInteractions(); + registerOnEntityUse(); } private static void registerOnLivingDeath() { EntityEvent.LIVING_DEATH.register((entity, source) -> { - if (!(entity instanceof IKnockableDown knockableDown) || knockableDown.knockdowns$isKnockedDown()) { + if (entity.getWorld().isClient() || !(entity instanceof IKnockableDown knockable) || knockable.is_KnockedDown()) { return EventResult.pass(); } ServerPlayerEntity serverPlayer = (ServerPlayerEntity) entity; - // TODO: timer - if (!serverPlayer.getWorld().getGameRules().getBoolean(GameRules.KEEP_INVENTORY)) { - serverPlayer.getInventory().dropAll(); - } - entity.setHealth(1.0f); + + entity.clearStatusEffects(); entity.setInvulnerable(true); entity.setGlowing(true); - entity.setAir(entity.getMaxAir()); + entity.setHealth(entity.getMaxHealth()); entity.extinguish(); + entity.setAir(entity.getMaxAir()); entity.setFrozenTicks(0); - entity.setOnFire(false); - entity.clearStatusEffects(); + serverPlayer.stopFallFlying(); - knockableDown.knockdowns$setKnockedDown(true); + knockable.set_KnockedDown(true); + knockable.set_ReviveTimer(KnockdownsCommon.REVIVE_WAIT_TIME); - KnockdownsNetwork.sendToListenersAndSelf(serverPlayer, new KnockedDownStatusPacket.SendS2C(serverPlayer.getUuid(), true)); KnockdownsNetwork.sendToWorld(serverPlayer.getServerWorld(), new PlayKnockedDownSoundS2CPacket(serverPlayer.getX(), serverPlayer.getY(), serverPlayer.getZ())); TranslatableTextContent content = (TranslatableTextContent) entity.getDamageTracker().getDeathMessage().getContent(); @@ -58,30 +62,69 @@ public class KnockdownsEvents { }); } + private static void registerOnPlayerTick() { + TickEvent.PLAYER_POST.register(player -> { + if (player.getWorld().isClient()) { + KnockdownsClient.onPlayerTick(player); + return; + } + if (!(player instanceof IKnockableDown knockable) || !knockable.is_KnockedDown()) { + return; + } + if (knockable.get_ReviverCount() > 0) { + knockable.set_ReviveTimer(knockable.get_ReviveTimer() - knockable.get_ReviverCount()); + + if (knockable.get_ReviveTimer() <= 0) { + knockable.set_KnockedDown(false); + knockable.set_ReviverCount(0); + knockable.set_ReviveTimer(KnockdownsCommon.REVIVE_WAIT_TIME); + + player.setInvulnerable(false); + player.setGlowing(false); + player.setHealth(6.0f); + } + return; + } + knockable.set_ReviveTimer(Math.min(KnockdownsCommon.REVIVE_WAIT_TIME, knockable.get_ReviveTimer() + 2)); + + if (player.age % 20 == 0) { + player.setInvulnerable(false); + DamageSource recent = player.getRecentDamageSource(); + player.damage(Objects.requireNonNullElse(recent, player.getDamageSources().generic()), player.getMaxHealth() / KNOCKED_DOWN_TIMER); + player.velocityModified = false; + } + }); + } + private static void registerOnPlayerInteractions() { InteractionEvent.LEFT_CLICK_BLOCK.register((player, hand, pos, direction) -> { - if (player instanceof IKnockableDown && ((IKnockableDown) player).knockdowns$isKnockedDown()) { + if (KnockdownsCommon.isKnockedOrReviving(player)) { return EventResult.interruptFalse(); } return EventResult.pass(); }); PlayerEvent.ATTACK_ENTITY.register((player, world, hand, entity, hitResult) -> { - if (player instanceof IKnockableDown && ((IKnockableDown) player).knockdowns$isKnockedDown()) { + if (KnockdownsCommon.isKnockedOrReviving(player)) { return EventResult.interruptFalse(); } return EventResult.pass(); }); InteractionEvent.RIGHT_CLICK_ITEM.register((player, hand) -> { - if (player instanceof IKnockableDown && ((IKnockableDown) player).knockdowns$isKnockedDown()) { + if (KnockdownsCommon.isKnockedOrReviving(player)) { return CompoundEventResult.interruptFalse(hand == Hand.MAIN_HAND ? player.getMainHandStack() : player.getOffHandStack()); } return CompoundEventResult.pass(); }); InteractionEvent.RIGHT_CLICK_BLOCK.register((player, hand, pos, direction) -> { - if (player instanceof IKnockableDown && ((IKnockableDown) player).knockdowns$isKnockedDown()) { + if (KnockdownsCommon.isKnockedOrReviving(player)) { return EventResult.interruptFalse(); } return EventResult.pass(); }); } + + private static void registerOnEntityUse() { + InteractionEvent.INTERACT_ENTITY.register((player, entity, hand) + -> player.getWorld().isClient() ? KnockdownsClient.onEntityUse(player, entity) : EventResult.pass()); + } } diff --git a/common/src/main/java/ru/octol1ttle/knockdowns/common/mixin/LivingEntityMixin.java b/common/src/main/java/ru/octol1ttle/knockdowns/common/mixin/LivingEntityMixin.java new file mode 100644 index 0000000..369a8b4 --- /dev/null +++ b/common/src/main/java/ru/octol1ttle/knockdowns/common/mixin/LivingEntityMixin.java @@ -0,0 +1,15 @@ +package ru.octol1ttle.knockdowns.common.mixin; + +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import net.minecraft.entity.LivingEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import ru.octol1ttle.knockdowns.common.api.IKnockableDown; + +@Mixin(LivingEntity.class) +public abstract class LivingEntityMixin { + @ModifyReturnValue(method = "canTarget(Lnet/minecraft/entity/LivingEntity;)Z", at = @At("RETURN")) + private boolean dontTargetKnockedPlayers(boolean original, LivingEntity target) { + return original && !(target instanceof IKnockableDown knockable && knockable.is_KnockedDown()); + } +} diff --git a/common/src/main/java/ru/octol1ttle/knockdowns/common/mixin/MobEntityMixin.java b/common/src/main/java/ru/octol1ttle/knockdowns/common/mixin/MobEntityMixin.java new file mode 100644 index 0000000..17540a0 --- /dev/null +++ b/common/src/main/java/ru/octol1ttle/knockdowns/common/mixin/MobEntityMixin.java @@ -0,0 +1,19 @@ +package ru.octol1ttle.knockdowns.common.mixin; + +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.mob.MobEntity; +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.CallbackInfo; +import ru.octol1ttle.knockdowns.common.api.IKnockableDown; + +@Mixin(MobEntity.class) +public abstract class MobEntityMixin { + @Inject(method = "setTarget", at = @At("HEAD"), cancellable = true) + private void setTarget(LivingEntity target, CallbackInfo ci) { + if (target instanceof IKnockableDown knockable && knockable.is_KnockedDown()) { + ci.cancel(); + } + } +} diff --git a/common/src/main/java/ru/octol1ttle/knockdowns/common/mixin/PlayerEntityMixin.java b/common/src/main/java/ru/octol1ttle/knockdowns/common/mixin/PlayerEntityMixin.java index 4d7ced9..876e0a1 100644 --- a/common/src/main/java/ru/octol1ttle/knockdowns/common/mixin/PlayerEntityMixin.java +++ b/common/src/main/java/ru/octol1ttle/knockdowns/common/mixin/PlayerEntityMixin.java @@ -2,70 +2,114 @@ package ru.octol1ttle.knockdowns.common.mixin; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.injector.ModifyReturnValue; -import java.util.UUID; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.data.DataTracker; +import net.minecraft.entity.data.TrackedData; +import net.minecraft.entity.data.TrackedDataHandlerRegistry; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.nbt.NbtCompound; +import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import ru.octol1ttle.knockdowns.common.KnockdownsCommon; import ru.octol1ttle.knockdowns.common.api.IKnockableDown; +@SuppressWarnings("WrongEntityDataParameterClass") @Mixin(PlayerEntity.class) -public abstract class PlayerEntityMixin implements IKnockableDown { +public abstract class PlayerEntityMixin extends Entity implements IKnockableDown { @Unique - private boolean knockdowns$knockedDown; + private static final TrackedData KNOCKED_DOWN = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.BOOLEAN); @Unique - private boolean knockdowns$beingRevived; + private static final TrackedData IS_REVIVING = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.BOOLEAN); + @Unique + private static final TrackedData REVIVER_COUNT = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.INTEGER); + @Unique + private static final TrackedData REVIVE_TIMER = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.INTEGER); + + private PlayerEntityMixin(EntityType type, World world) { + super(type, world); + throw new AssertionError(); + } @ModifyExpressionValue(method = "updatePose", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;isSwimming()Z")) private boolean enterSwimmingIfKnockedDown(boolean original) { - PlayerEntity player = (PlayerEntity)(Object)this; - if (!(player instanceof IKnockableDown knockableDown)) { - throw new IllegalStateException(); - } - - return original || knockableDown.knockdowns$isKnockedDown(); + return original || this.is_KnockedDown(); } @ModifyReturnValue(method = "canFoodHeal", at = @At("RETURN")) private boolean dontHealIfKnockedDown(boolean original) { - return original && !this.knockdowns$isKnockedDown(); + return original && !this.is_KnockedDown(); + } + + @Inject(method = "checkFallFlying", at = @At("HEAD"), cancellable = true) + private void dontOpenElytraIfKnockedDown(CallbackInfoReturnable cir) { + if (this.is_KnockedDown()) { + cir.setReturnValue(false); + } + } + + @Inject(method = "initDataTracker", at = @At("TAIL")) + private void initCustomDataTracker(CallbackInfo ci) { + this.dataTracker.startTracking(KNOCKED_DOWN, false); + this.dataTracker.startTracking(IS_REVIVING, false); + this.dataTracker.startTracking(REVIVER_COUNT, 0); + this.dataTracker.startTracking(REVIVE_TIMER, KnockdownsCommon.REVIVE_WAIT_TIME); } @Inject(method = "readCustomDataFromNbt", at = @At("TAIL")) - public void readKnockedDownFromNbt(NbtCompound nbt, CallbackInfo ci) { - this.knockdowns$knockedDown = nbt.getBoolean("KnockedDown"); + private void readKnockedDownFromNbt(NbtCompound nbt, CallbackInfo ci) { + this.set_KnockedDown(nbt.getBoolean("KnockedDown")); + this.set_ReviveTimer(nbt.getInt("ReviveTimer")); } @Inject(method = "writeCustomDataToNbt", at = @At("TAIL")) - public void writeKnockedDownToNbt(NbtCompound nbt, CallbackInfo ci) { - nbt.putBoolean("KnockedDown", this.knockdowns$knockedDown); + private void writeKnockedDownToNbt(NbtCompound nbt, CallbackInfo ci) { + nbt.putBoolean("KnockedDown", this.is_KnockedDown()); + nbt.putInt("ReviveTimer", this.get_ReviveTimer()); } @Override - public boolean knockdowns$isKnockedDown() { - return knockdowns$knockedDown; + public boolean is_KnockedDown() { + return this.dataTracker.get(KNOCKED_DOWN); } @Override - public void knockdowns$setKnockedDown(boolean knockedDown) { - this.knockdowns$knockedDown = knockedDown; + public void set_KnockedDown(boolean knockedDown) { + this.dataTracker.set(KNOCKED_DOWN, knockedDown); } @Override - public boolean knockdowns$isBeingRevived() { - return knockdowns$beingRevived; + public boolean is_Reviving() { + return this.dataTracker.get(IS_REVIVING); } @Override - public void knockdowns$setBeingRevived(boolean beingRevived) { - this.knockdowns$beingRevived = beingRevived; + public void set_Reviving(boolean reviving) { + this.dataTracker.set(IS_REVIVING, reviving); } @Override - public UUID knockdowns$getUuid() { - return ((PlayerEntity)(Object)this).getUuid(); + public int get_ReviverCount() { + return this.dataTracker.get(REVIVER_COUNT); + } + + @Override + public void set_ReviverCount(int reviverCount) { + this.dataTracker.set(REVIVER_COUNT, reviverCount); + } + + @Override + public int get_ReviveTimer() { + return this.dataTracker.get(REVIVE_TIMER); + } + + @Override + public void set_ReviveTimer(int reviveTimer) { + this.dataTracker.set(REVIVE_TIMER, reviveTimer); } } diff --git a/common/src/main/java/ru/octol1ttle/knockdowns/common/mixin/client/ClientPlayerEntityMixin.java b/common/src/main/java/ru/octol1ttle/knockdowns/common/mixin/client/ClientPlayerEntityMixin.java index 5756cdf..440c2ef 100644 --- a/common/src/main/java/ru/octol1ttle/knockdowns/common/mixin/client/ClientPlayerEntityMixin.java +++ b/common/src/main/java/ru/octol1ttle/knockdowns/common/mixin/client/ClientPlayerEntityMixin.java @@ -7,10 +7,9 @@ import org.spongepowered.asm.mixin.injection.At; import ru.octol1ttle.knockdowns.common.api.IKnockableDown; @Mixin(ClientPlayerEntity.class) -public abstract class ClientPlayerEntityMixin { +public abstract class ClientPlayerEntityMixin implements IKnockableDown { @ModifyReturnValue(method = "shouldSlowDown", at = @At("RETURN")) private boolean shouldSlowDown(boolean original) { - IKnockableDown self = (IKnockableDown) this; - return original || self.knockdowns$isKnockedDown(); + return original || this.is_KnockedDown(); } } \ No newline at end of file diff --git a/common/src/main/java/ru/octol1ttle/knockdowns/common/network/KnockdownsNetwork.java b/common/src/main/java/ru/octol1ttle/knockdowns/common/network/KnockdownsNetwork.java index 1d9af8e..8544efb 100644 --- a/common/src/main/java/ru/octol1ttle/knockdowns/common/network/KnockdownsNetwork.java +++ b/common/src/main/java/ru/octol1ttle/knockdowns/common/network/KnockdownsNetwork.java @@ -2,32 +2,22 @@ package ru.octol1ttle.knockdowns.common.network; import dev.architectury.networking.NetworkChannel; import dev.architectury.networking.NetworkManager; -import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.network.packet.Packet; import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.EntityTrackingListener; -import net.minecraft.server.world.ServerChunkManager; import net.minecraft.server.world.ServerWorld; -import net.minecraft.server.world.ThreadedAnvilChunkStorage; import net.minecraft.util.Identifier; import ru.octol1ttle.knockdowns.common.KnockdownsCommon; -import ru.octol1ttle.knockdowns.common.network.packets.KnockedDownStatusPacket; import ru.octol1ttle.knockdowns.common.network.packets.PlayKnockedDownSoundS2CPacket; -import ru.octol1ttle.knockdowns.common.network.packets.ReviveStatusPacket; +import ru.octol1ttle.knockdowns.common.network.packets.RequestStartRevivingC2SPacket; +import ru.octol1ttle.knockdowns.common.network.packets.StopRevivingC2SPacket; public class KnockdownsNetwork { private static final NetworkChannel CHANNEL = NetworkChannel.create(new Identifier(KnockdownsCommon.MOD_ID, "main")); public static void registerPackets() { - CHANNEL.register(KnockedDownStatusPacket.SendS2C.class, KnockedDownStatusPacket.SendS2C::encode, KnockedDownStatusPacket.SendS2C::new, KnockedDownStatusPacket.SendS2C::apply); - CHANNEL.register(KnockedDownStatusPacket.RequestC2S.class, KnockedDownStatusPacket.RequestC2S::encode, KnockedDownStatusPacket.RequestC2S::new, KnockedDownStatusPacket.RequestC2S::apply); - CHANNEL.register(PlayKnockedDownSoundS2CPacket.class, PlayKnockedDownSoundS2CPacket::encode, PlayKnockedDownSoundS2CPacket::new, PlayKnockedDownSoundS2CPacket::apply); - - CHANNEL.register(ReviveStatusPacket.SendS2C.class, ReviveStatusPacket.SendS2C::encode, ReviveStatusPacket.SendS2C::new, ReviveStatusPacket.SendS2C::apply); - CHANNEL.register(ReviveStatusPacket.SendC2S.class, ReviveStatusPacket.SendC2S::encode, ReviveStatusPacket.SendC2S::new, ReviveStatusPacket.SendC2S::apply); - CHANNEL.register(ReviveStatusPacket.RequestC2S.class, ReviveStatusPacket.RequestC2S::encode, ReviveStatusPacket.RequestC2S::new, ReviveStatusPacket.RequestC2S::apply); - CHANNEL.register(ReviveStatusPacket.RevivedC2S.class, ReviveStatusPacket.RevivedC2S::encode, ReviveStatusPacket.RevivedC2S::new, ReviveStatusPacket.RevivedC2S::apply); + CHANNEL.register(RequestStartRevivingC2SPacket.class, RequestStartRevivingC2SPacket::encode, RequestStartRevivingC2SPacket::new, RequestStartRevivingC2SPacket::apply); + CHANNEL.register(StopRevivingC2SPacket.class, StopRevivingC2SPacket::encode, StopRevivingC2SPacket::new, StopRevivingC2SPacket::apply); } public static void sendToServer(T message) { @@ -52,30 +42,6 @@ public class KnockdownsNetwork { } } - // TODO: PR to Architectury API - public static void sendToListeners(Entity entity, T message) { - Packet packet = CHANNEL.toPacket(NetworkManager.Side.S2C, message); - Class messageClass = message.getClass(); - - sendToListeners(entity, packet, messageClass); - } - - private static void sendToListeners(Entity entity, Packet packet, Class messageClass) { - ServerChunkManager chunkManager = (ServerChunkManager) entity.getWorld().getChunkManager(); - ThreadedAnvilChunkStorage.EntityTracker entityTracker = chunkManager.threadedAnvilChunkStorage.entityTrackers.get(entity.getId()); - - for (EntityTrackingListener listener : entityTracker.listeners) { - sendToPlayer(listener.getPlayer(), packet, messageClass); - } - } - - public static void sendToListenersAndSelf(PlayerEntity player, T message) { - Packet packet = CHANNEL.toPacket(NetworkManager.Side.S2C, message); - Class messageClass = message.getClass(); - sendToPlayer(player, packet, messageClass); - sendToListeners(player, packet, messageClass); - } - public static void sendToWorld(ServerWorld world, T message) { Packet packet = CHANNEL.toPacket(NetworkManager.Side.S2C, message); Class messageClass = message.getClass(); diff --git a/common/src/main/java/ru/octol1ttle/knockdowns/common/network/packets/KnockedDownStatusPacket.java b/common/src/main/java/ru/octol1ttle/knockdowns/common/network/packets/KnockedDownStatusPacket.java deleted file mode 100644 index a86205c..0000000 --- a/common/src/main/java/ru/octol1ttle/knockdowns/common/network/packets/KnockedDownStatusPacket.java +++ /dev/null @@ -1,69 +0,0 @@ -package ru.octol1ttle.knockdowns.common.network.packets; - -import dev.architectury.networking.NetworkManager; -import java.util.UUID; -import java.util.function.Supplier; -import net.minecraft.network.PacketByteBuf; -import ru.octol1ttle.knockdowns.common.network.KnockdownsNetwork; -import ru.octol1ttle.knockdowns.common.api.IKnockableDown; - -public class KnockedDownStatusPacket { - public static class SendS2C extends KnockdownsPacket { - private final UUID playerUuid; - private final boolean knockedDown; - - public SendS2C(PacketByteBuf buf) { - this(buf.readUuid(), buf.readBoolean()); - } - - public SendS2C(UUID playerUuid, boolean knockedDown) { - this.playerUuid = playerUuid; - this.knockedDown = knockedDown; - } - - @Override - public void encode(PacketByteBuf buf) { - buf.writeUuid(this.playerUuid); - buf.writeBoolean(this.knockedDown); - } - - @Override - public void apply(Supplier contextSupplier) { - NetworkManager.PacketContext context = contextSupplier.get(); - context.queue(() -> { - IKnockableDown knockableDown = (IKnockableDown) context.getPlayer().getWorld().getPlayerByUuid(this.playerUuid); - if (knockableDown != null) { - knockableDown.knockdowns$setKnockedDown(this.knockedDown); - } - }); - } - } - - public static class RequestC2S extends KnockdownsPacket { - private final UUID playerUuid; - - public RequestC2S(PacketByteBuf buf) { - this(buf.readUuid()); - } - - public RequestC2S(UUID playerUuid) { - this.playerUuid = playerUuid; - } - - @Override - public void encode(PacketByteBuf buf) { - buf.writeUuid(this.playerUuid); - } - - @Override - public void apply(Supplier contextSupplier) { - NetworkManager.PacketContext context = contextSupplier.get(); - context.queue(() -> { - IKnockableDown knockableDown = (IKnockableDown) context.getPlayer().getWorld().getPlayerByUuid(this.playerUuid); - if (knockableDown != null) { - KnockdownsNetwork.sendToPlayer(context.getPlayer(), new SendS2C(this.playerUuid, knockableDown.knockdowns$isKnockedDown())); - } - }); - } - } -} diff --git a/common/src/main/java/ru/octol1ttle/knockdowns/common/network/packets/RequestStartRevivingC2SPacket.java b/common/src/main/java/ru/octol1ttle/knockdowns/common/network/packets/RequestStartRevivingC2SPacket.java new file mode 100644 index 0000000..31a7de0 --- /dev/null +++ b/common/src/main/java/ru/octol1ttle/knockdowns/common/network/packets/RequestStartRevivingC2SPacket.java @@ -0,0 +1,39 @@ +package ru.octol1ttle.knockdowns.common.network.packets; + +import dev.architectury.networking.NetworkManager; +import java.util.UUID; +import java.util.function.Supplier; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.network.PacketByteBuf; +import ru.octol1ttle.knockdowns.common.api.IKnockableDown; + +public class RequestStartRevivingC2SPacket extends KnockdownsPacket { + private final UUID targetUuid; + + public RequestStartRevivingC2SPacket(PacketByteBuf buf) { + this(buf.readUuid()); + } + + public RequestStartRevivingC2SPacket(UUID targetUuid) { + this.targetUuid = targetUuid; + } + + @Override + public void encode(PacketByteBuf buf) { + buf.writeUuid(this.targetUuid); + } + + @Override + public void apply(Supplier contextSupplier) { + NetworkManager.PacketContext context = contextSupplier.get(); + context.queue(() -> { + PlayerEntity player = context.getPlayer(); + IKnockableDown playerKnockable = (IKnockableDown) player; + IKnockableDown targetKnockable = (IKnockableDown) player.getWorld().getPlayerByUuid(this.targetUuid); + if (!playerKnockable.is_Reviving() && targetKnockable != null && targetKnockable.is_KnockedDown()) { + playerKnockable.set_Reviving(true); + targetKnockable.set_ReviverCount(targetKnockable.get_ReviverCount() + 1); + } + }); + } +} diff --git a/common/src/main/java/ru/octol1ttle/knockdowns/common/network/packets/ReviveStatusPacket.java b/common/src/main/java/ru/octol1ttle/knockdowns/common/network/packets/ReviveStatusPacket.java deleted file mode 100644 index e486e7d..0000000 --- a/common/src/main/java/ru/octol1ttle/knockdowns/common/network/packets/ReviveStatusPacket.java +++ /dev/null @@ -1,138 +0,0 @@ -package ru.octol1ttle.knockdowns.common.network.packets; - -import dev.architectury.networking.NetworkManager; -import java.util.UUID; -import java.util.function.Supplier; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.network.PacketByteBuf; -import ru.octol1ttle.knockdowns.common.network.KnockdownsNetwork; -import ru.octol1ttle.knockdowns.common.api.IKnockableDown; - -public class ReviveStatusPacket { - public static class SendS2C extends KnockdownsPacket { - private final UUID playerUuid; - private final boolean beingRevived; - - public SendS2C(PacketByteBuf buf) { - this(buf.readUuid(), buf.readBoolean()); - } - - public SendS2C(UUID playerUuid, boolean beingRevived) { - this.playerUuid = playerUuid; - this.beingRevived = beingRevived; - } - - @Override - public void encode(PacketByteBuf buf) { - buf.writeUuid(this.playerUuid); - buf.writeBoolean(this.beingRevived); - } - - @Override - public void apply(Supplier contextSupplier) { - NetworkManager.PacketContext context = contextSupplier.get(); - context.queue(() -> { - IKnockableDown knockableDown = (IKnockableDown) context.getPlayer().getWorld().getPlayerByUuid(this.playerUuid); - if (knockableDown != null) { - knockableDown.knockdowns$setBeingRevived(this.beingRevived); - } - }); - } - } - - public static class SendC2S extends KnockdownsPacket { - private final UUID playerUuid; - private final boolean beingRevived; - - public SendC2S(PacketByteBuf buf) { - this(buf.readUuid(), buf.readBoolean()); - } - - public SendC2S(UUID playerUuid, boolean beingRevived) { - this.playerUuid = playerUuid; - this.beingRevived = beingRevived; - } - - @Override - public void encode(PacketByteBuf buf) { - buf.writeUuid(this.playerUuid); - buf.writeBoolean(this.beingRevived); - } - - @Override - public void apply(Supplier contextSupplier) { - NetworkManager.PacketContext context = contextSupplier.get(); - context.queue(() -> { - IKnockableDown knockableDown = (IKnockableDown) context.getPlayer().getWorld().getPlayerByUuid(this.playerUuid); - if (knockableDown != null) { - knockableDown.knockdowns$setBeingRevived(this.beingRevived); - KnockdownsNetwork.sendToListenersAndSelf(context.getPlayer(), new ReviveStatusPacket.SendS2C(this.playerUuid, this.beingRevived)); - } - }); - } - } - - public static class RequestC2S extends KnockdownsPacket { - private final UUID playerUuid; - - public RequestC2S(PacketByteBuf buf) { - this(buf.readUuid()); - } - - public RequestC2S(UUID playerUuid) { - this.playerUuid = playerUuid; - } - - @Override - public void encode(PacketByteBuf buf) { - buf.writeUuid(this.playerUuid); - } - - @Override - public void apply(Supplier contextSupplier) { - NetworkManager.PacketContext context = contextSupplier.get(); - context.queue(() -> { - IKnockableDown knockableDown = (IKnockableDown) context.getPlayer().getWorld().getPlayerByUuid(this.playerUuid); - if (knockableDown != null) { - KnockdownsNetwork.sendToPlayer(context.getPlayer(), new ReviveStatusPacket.SendS2C(this.playerUuid, knockableDown.knockdowns$isBeingRevived())); - } - }); - } - } - - public static class RevivedC2S extends KnockdownsPacket { - private final UUID playerUuid; - - public RevivedC2S(PacketByteBuf buf) { - this(buf.readUuid()); - } - - public RevivedC2S(UUID playerUuid) { - this.playerUuid = playerUuid; - } - - @Override - public void encode(PacketByteBuf buf) { - buf.writeUuid(this.playerUuid); - } - - @Override - public void apply(Supplier contextSupplier) { - NetworkManager.PacketContext context = contextSupplier.get(); - context.queue(() -> { - PlayerEntity reviving = context.getPlayer().getWorld().getPlayerByUuid(this.playerUuid); - IKnockableDown knockableDown = (IKnockableDown) reviving; - if (knockableDown == null || !knockableDown.knockdowns$isKnockedDown()) { - return; - } - - reviving.setInvulnerable(false); - reviving.setGlowing(false); - reviving.setHealth(6.0f); - - knockableDown.knockdowns$setKnockedDown(false); - KnockdownsNetwork.sendToListenersAndSelf(reviving, new KnockedDownStatusPacket.SendS2C(reviving.getUuid(), false)); - }); - } - } -} diff --git a/common/src/main/java/ru/octol1ttle/knockdowns/common/network/packets/StopRevivingC2SPacket.java b/common/src/main/java/ru/octol1ttle/knockdowns/common/network/packets/StopRevivingC2SPacket.java new file mode 100644 index 0000000..260cc1e --- /dev/null +++ b/common/src/main/java/ru/octol1ttle/knockdowns/common/network/packets/StopRevivingC2SPacket.java @@ -0,0 +1,41 @@ +package ru.octol1ttle.knockdowns.common.network.packets; + +import dev.architectury.networking.NetworkManager; +import java.util.UUID; +import java.util.function.Supplier; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.network.PacketByteBuf; +import ru.octol1ttle.knockdowns.common.api.IKnockableDown; + +public class StopRevivingC2SPacket extends KnockdownsPacket { + private final UUID targetUuid; + + public StopRevivingC2SPacket(PacketByteBuf buf) { + this(buf.readUuid()); + } + + public StopRevivingC2SPacket(UUID targetUuid) { + this.targetUuid = targetUuid; + } + + @Override + public void encode(PacketByteBuf buf) { + buf.writeUuid(this.targetUuid); + } + + @Override + public void apply(Supplier contextSupplier) { + NetworkManager.PacketContext context = contextSupplier.get(); + context.queue(() -> { + PlayerEntity player = context.getPlayer(); + IKnockableDown playerKnockable = (IKnockableDown) player; + IKnockableDown targetKnockable = (IKnockableDown) player.getWorld().getPlayerByUuid(this.targetUuid); + if (playerKnockable.is_Reviving() && targetKnockable != null) { + playerKnockable.set_Reviving(false); + if (targetKnockable.is_KnockedDown()) { + targetKnockable.set_ReviverCount(targetKnockable.get_ReviverCount() - 1); + } + } + }); + } +} diff --git a/common/src/main/resources/assets/knockdowns/lang/en_us.json b/common/src/main/resources/assets/knockdowns/lang/en_us.json index 256bd9b..57cacc4 100644 --- a/common/src/main/resources/assets/knockdowns/lang/en_us.json +++ b/common/src/main/resources/assets/knockdowns/lang/en_us.json @@ -1,4 +1,6 @@ { + "subtitles.knockdowns.knocked_down": "Player knocked down", + "knockdown.attack.anvil": "%1$s was knocked down by a falling anvil", "knockdown.attack.anvil.player": "%1$s was knocked down by a falling anvil while fighting %2$s", "knockdown.attack.arrow": "%1$s was knocked down due to an arrow fired by %2$s", @@ -97,6 +99,5 @@ "knockdown.fell.assist.item": "%1$s was doomed to get knocked down by %2$s using %3$s", "knockdown.fell.finish": "%1$s fell too far and was knocked down by %2$s", "knockdown.fell.finish.item": "%1$s fell too far and was knocked down by %2$s using %3$s", - "knockdown.fell.killer": "%1$s was doomed to get knocked down by a fall", - "subtitles.knockdowns.knocked_down": "Player knocked down" + "knockdown.fell.killer": "%1$s was doomed to get knocked down by a fall" } \ No newline at end of file diff --git a/common/src/main/resources/assets/knockdowns/lang/ru_ru.json b/common/src/main/resources/assets/knockdowns/lang/ru_ru.json index 5cdd965..9fd0739 100644 --- a/common/src/main/resources/assets/knockdowns/lang/ru_ru.json +++ b/common/src/main/resources/assets/knockdowns/lang/ru_ru.json @@ -1,4 +1,6 @@ { + "subtitles.knockdowns.knocked_down": "Игрок тяжело ранен", + "knockdown.attack.anvil": "%1$s был тяжело ранен упавшей наковальней", "knockdown.attack.anvil.player": "%1$s был тяжело ранен упавшей наковальней, пока сражался с %2$s", "knockdown.attack.arrow": "%1$s тяжело ранен стрелой %2$s", @@ -97,6 +99,5 @@ "knockdown.fell.assist.item": "%1$s был тяжело ранен падением благодаря %2$s с помощью %3$s", "knockdown.fell.finish": "%1$s упал с высоты и был тяжело ранен %2$s", "knockdown.fell.finish.item": "%1$s упал с высоты и был тяжело ранен %2$s с помощью %3$s", - "knockdown.fell.killer": "%1$s был тяжело ранен падением", - "subtitles.knockdowns.knocked_down": "Игрок тяжело ранен" + "knockdown.fell.killer": "%1$s был тяжело ранен падением" } \ No newline at end of file diff --git a/common/src/main/resources/knockdowns-common.mixins.json b/common/src/main/resources/knockdowns-common.mixins.json index 8eef057..b157b56 100644 --- a/common/src/main/resources/knockdowns-common.mixins.json +++ b/common/src/main/resources/knockdowns-common.mixins.json @@ -7,6 +7,8 @@ "client.ClientPlayerEntityMixin" ], "mixins": [ + "LivingEntityMixin", + "MobEntityMixin", "PlayerEntityMixin" ], "injectors": { diff --git a/common/src/main/resources/knockdowns.accesswidener b/common/src/main/resources/knockdowns.accesswidener index 4dddd12..13268c3 100644 --- a/common/src/main/resources/knockdowns.accesswidener +++ b/common/src/main/resources/knockdowns.accesswidener @@ -1,4 +1 @@ -accessWidener v2 named - -accessible field net/minecraft/server/world/ThreadedAnvilChunkStorage entityTrackers Lit/unimi/dsi/fastutil/ints/Int2ObjectMap; -accessible field net/minecraft/server/world/ThreadedAnvilChunkStorage$EntityTracker listeners Ljava/util/Set; \ No newline at end of file +accessWidener v2 named \ No newline at end of file