From 34ea071e5fc67cfa6030916a9927a1590661066b Mon Sep 17 00:00:00 2001 From: Octol1ttle Date: Fri, 16 Feb 2024 17:13:30 +0500 Subject: [PATCH] Increase invulnerability period and tenacity periods --- .../knockdowns/common/KnockdownsClient.java | 4 +- .../knockdowns/common/KnockdownsCommon.java | 6 --- .../knockdowns/common/KnockdownsUtils.java | 31 +++++++++++ .../knockdowns/common/api/IKnockableDown.java | 4 ++ .../common/events/KnockdownsEvents.java | 54 ++++++++++++------- .../common/mixin/PlayerEntityMixin.java | 14 +++++ gradle.properties | 2 +- 7 files changed, 86 insertions(+), 29 deletions(-) create mode 100644 common/src/main/java/ru/octol1ttle/knockdowns/common/KnockdownsUtils.java 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 79f04c3..1b4272f 100644 --- a/common/src/main/java/ru/octol1ttle/knockdowns/common/KnockdownsClient.java +++ b/common/src/main/java/ru/octol1ttle/knockdowns/common/KnockdownsClient.java @@ -31,7 +31,7 @@ public class KnockdownsClient { } public static EventResult onEntityUse(PlayerEntity player, Entity entity) { - if (KnockdownsCommon.isKnockedOrReviving(player) || !(entity instanceof IKnockableDown knockable) || !knockable.is_KnockedDown()) { + if (KnockdownsUtils.isKnockedOrReviving(player) || !(entity instanceof IKnockableDown knockable) || !knockable.is_KnockedDown()) { return EventResult.pass(); } @@ -49,7 +49,7 @@ public class KnockdownsClient { 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()); + && ((EntityHitResult) client.crosshairTarget).getEntity().equals(reviving); if (!(reviving instanceof IKnockableDown knockable)) { return; 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 286367c..d36f5d7 100644 --- a/common/src/main/java/ru/octol1ttle/knockdowns/common/KnockdownsCommon.java +++ b/common/src/main/java/ru/octol1ttle/knockdowns/common/KnockdownsCommon.java @@ -1,8 +1,6 @@ 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; @@ -16,8 +14,4 @@ public class KnockdownsCommon { 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/KnockdownsUtils.java b/common/src/main/java/ru/octol1ttle/knockdowns/common/KnockdownsUtils.java new file mode 100644 index 0000000..8715bd8 --- /dev/null +++ b/common/src/main/java/ru/octol1ttle/knockdowns/common/KnockdownsUtils.java @@ -0,0 +1,31 @@ +package ru.octol1ttle.knockdowns.common; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.MinecraftServer; +import ru.octol1ttle.knockdowns.common.api.IKnockableDown; + +public class KnockdownsUtils { + public static boolean isKnockedOrReviving(PlayerEntity player) { + return player instanceof IKnockableDown knockable && (knockable.is_KnockedDown() || knockable.is_Reviving()); + } + + public static boolean allTeammatesKnocked(MinecraftServer server, PlayerEntity player) { + for (PlayerEntity teammate : server.getPlayerManager().getPlayerList()) { + if (teammate.equals(player)) { + continue; + } + IKnockableDown knockable = (IKnockableDown) teammate; + if (!knockable.is_KnockedDown() && !player.isDead()) { + return false; + } + } + return true; + } + + public static void hurtTenacity(PlayerEntity player, float damage) { + player.setInvulnerable(false); + //DamageSource recent = player.getRecentDamageSource(); + player.damage(/*Objects.requireNonNullElse(recent, */player.getDamageSources().generic()/*)*/, damage); + player.velocityModified = false; + } +} 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 74fad18..17c4308 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 @@ -16,4 +16,8 @@ public interface IKnockableDown { int get_ReviveTimer(); void set_ReviveTimer(int reviveTimer); + + int get_KnockedAge(); + + void set_KnockedAge(int knockedAge); } 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 be6b190..8f46b96 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 @@ -6,21 +6,24 @@ 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.SharedConstants; 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.util.math.MathHelper; import ru.octol1ttle.knockdowns.common.KnockdownsClient; import ru.octol1ttle.knockdowns.common.KnockdownsCommon; +import ru.octol1ttle.knockdowns.common.KnockdownsUtils; import ru.octol1ttle.knockdowns.common.api.IKnockableDown; 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; + private static final float KNOCKED_INVULNERABILITY_TICKS = 3.0f * SharedConstants.TICKS_PER_SECOND; + private static final float KNOCKED_HURT_PERIOD = 1.2f; + private static final float KNOCKED_TENACITY = 60.0f; public static void registerCallbacks() { registerOnLivingDeath(); @@ -31,13 +34,14 @@ public class KnockdownsEvents { private static void registerOnLivingDeath() { EntityEvent.LIVING_DEATH.register((entity, source) -> { - if (entity.getWorld().isClient() || !(entity instanceof IKnockableDown knockable)) { + MinecraftServer server = entity.getServer(); + if (server == null || !(entity instanceof IKnockableDown knockable)) { return EventResult.pass(); } - ServerPlayerEntity serverPlayer = (ServerPlayerEntity) entity; - MinecraftServer server = serverPlayer.getServer(); - if (server == null || server.getCurrentPlayerCount() == 1) { + ServerPlayerEntity player = (ServerPlayerEntity) entity; + + if (KnockdownsUtils.allTeammatesKnocked(server, player)) { return EventResult.pass(); } @@ -45,6 +49,7 @@ public class KnockdownsEvents { knockable.set_KnockedDown(false); knockable.set_ReviverCount(0); knockable.set_ReviveTimer(KnockdownsCommon.REVIVE_WAIT_TIME); + knockable.set_KnockedAge(0); return EventResult.pass(); } @@ -56,12 +61,13 @@ public class KnockdownsEvents { entity.extinguish(); entity.setAir(entity.getMaxAir()); entity.setFrozenTicks(0); - serverPlayer.stopFallFlying(); + player.stopFallFlying(); knockable.set_KnockedDown(true); knockable.set_ReviveTimer(KnockdownsCommon.REVIVE_WAIT_TIME); + knockable.set_KnockedAge(0); - KnockdownsNetwork.sendToWorld(serverPlayer.getServerWorld(), new PlayKnockedDownSoundS2CPacket(serverPlayer.getX(), serverPlayer.getY(), serverPlayer.getZ())); + KnockdownsNetwork.sendToWorld(player.getServerWorld(), new PlayKnockedDownSoundS2CPacket(player.getX(), player.getY(), player.getZ())); Text deathMessage = entity.getDamageTracker().getDeathMessage(); TranslatableTextContent content = (TranslatableTextContent) deathMessage.getContent(); @@ -75,13 +81,20 @@ public class KnockdownsEvents { private static void registerOnPlayerTick() { TickEvent.PLAYER_POST.register(player -> { - if (player.getWorld().isClient()) { + MinecraftServer server = player.getServer(); + if (server == null) { KnockdownsClient.onPlayerTick(player); return; } if (!(player instanceof IKnockableDown knockable) || !knockable.is_KnockedDown()) { return; } + + if (KnockdownsUtils.allTeammatesKnocked(server, player)) { + KnockdownsUtils.hurtTenacity(player, player.getMaxHealth()); + return; + } + if (knockable.get_ReviverCount() > 0) { knockable.set_ReviveTimer(knockable.get_ReviveTimer() - knockable.get_ReviverCount()); @@ -89,6 +102,7 @@ public class KnockdownsEvents { knockable.set_KnockedDown(false); knockable.set_ReviverCount(0); knockable.set_ReviveTimer(KnockdownsCommon.REVIVE_WAIT_TIME); + knockable.set_KnockedAge(0); player.setInvulnerable(false); player.setGlowing(false); @@ -96,38 +110,38 @@ public class KnockdownsEvents { } return; } - knockable.set_ReviveTimer(Math.min(KnockdownsCommon.REVIVE_WAIT_TIME, knockable.get_ReviveTimer() + 2)); + knockable.set_ReviveTimer(Math.min(KnockdownsCommon.REVIVE_WAIT_TIME, knockable.get_ReviveTimer() + 1)); - 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; + knockable.set_KnockedAge(knockable.get_KnockedAge() + 1); + + int period = MathHelper.floor(KNOCKED_HURT_PERIOD * SharedConstants.TICKS_PER_SECOND); + if (knockable.get_KnockedAge() >= KNOCKED_INVULNERABILITY_TICKS && knockable.get_KnockedAge() % period == 0) { + KnockdownsUtils.hurtTenacity(player, player.getMaxHealth() / (KNOCKED_TENACITY / KNOCKED_HURT_PERIOD)); } }); } private static void registerOnPlayerInteractions() { InteractionEvent.LEFT_CLICK_BLOCK.register((player, hand, pos, direction) -> { - if (KnockdownsCommon.isKnockedOrReviving(player)) { + if (KnockdownsUtils.isKnockedOrReviving(player)) { return EventResult.interruptFalse(); } return EventResult.pass(); }); PlayerEvent.ATTACK_ENTITY.register((player, world, hand, entity, hitResult) -> { - if (KnockdownsCommon.isKnockedOrReviving(player)) { + if (KnockdownsUtils.isKnockedOrReviving(player)) { return EventResult.interruptFalse(); } return EventResult.pass(); }); InteractionEvent.RIGHT_CLICK_ITEM.register((player, hand) -> { - if (KnockdownsCommon.isKnockedOrReviving(player)) { + if (KnockdownsUtils.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 (KnockdownsCommon.isKnockedOrReviving(player)) { + if (KnockdownsUtils.isKnockedOrReviving(player)) { return EventResult.interruptFalse(); } return EventResult.pass(); 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 876e0a1..ce8f9f1 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 @@ -30,6 +30,8 @@ public abstract class PlayerEntityMixin extends Entity implements IKnockableDown 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); + @Unique + public int knocked_age; private PlayerEntityMixin(EntityType type, World world) { super(type, world); @@ -65,12 +67,14 @@ public abstract class PlayerEntityMixin extends Entity implements IKnockableDown private void readKnockedDownFromNbt(NbtCompound nbt, CallbackInfo ci) { this.set_KnockedDown(nbt.getBoolean("KnockedDown")); this.set_ReviveTimer(nbt.getInt("ReviveTimer")); + this.set_KnockedAge(nbt.getInt("KnockedAge")); } @Inject(method = "writeCustomDataToNbt", at = @At("TAIL")) private void writeKnockedDownToNbt(NbtCompound nbt, CallbackInfo ci) { nbt.putBoolean("KnockedDown", this.is_KnockedDown()); nbt.putInt("ReviveTimer", this.get_ReviveTimer()); + nbt.putInt("KnockedAge", this.get_KnockedAge()); } @Override @@ -112,4 +116,14 @@ public abstract class PlayerEntityMixin extends Entity implements IKnockableDown public void set_ReviveTimer(int reviveTimer) { this.dataTracker.set(REVIVE_TIMER, reviveTimer); } + + @Override + public int get_KnockedAge() { + return knocked_age; + } + + @Override + public void set_KnockedAge(int knockedAge) { + this.knocked_age = knockedAge; + } } diff --git a/gradle.properties b/gradle.properties index c3bc8bf..f07c82c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ minecraft_version=1.20.1 enabled_platforms=fabric,forge archives_base_name=knockdowns -mod_version=2.0.0 +mod_version=2.1.0 maven_group=ru.octol1ttle.knockdowns architectury_version=9.1.12