Some bug fixes

This commit is contained in:
IM23a-spirgif
2025-04-26 13:07:05 +02:00
parent 39078cc8cf
commit df9bf5f568
4 changed files with 54 additions and 63 deletions
@@ -1,15 +1,15 @@
package net.fretux.knockedback; package net.fretux.knockedback;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
import net.minecraftforge.event.TickEvent; import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.entity.EntityMountEvent;
import net.minecraftforge.event.entity.living.LivingHurtEvent; import net.minecraftforge.event.entity.living.LivingHurtEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.event.entity.EntityMountEvent;
import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket;
import java.util.*; import java.util.*;
@@ -19,101 +19,94 @@ public class CarryManager {
private static final double CARRY_RANGE = 2.0; private static final double CARRY_RANGE = 2.0;
public static void toggleCarry(ServerPlayer carrier) { public static void toggleCarry(ServerPlayer carrier) {
// 1) If they’re already carrying someone, drop them—and quit immediately if (KnockedManager.isKnocked(carrier)) {
carrier.getPassengers().stream() carrier.sendSystemMessage(Component.literal("You cannot carry others while you are knocked!"));
return;
}
Optional<Player> existing = carrier.getPassengers().stream()
.filter(p -> p instanceof Player) .filter(p -> p instanceof Player)
.map(p -> (Player)p) .map(p -> (Player)p)
.findFirst() .findFirst();
.ifPresent(p -> { if (existing.isPresent()) {
stopCarry((Player)p, carrier); stopCarry(existing.get(), carrier);
}); return;
if (carrier.getPassengers().size() > 0) return;
// 2) Otherwise look for a knocked player to pick up
ServerPlayer near = findNearestKnocked(carrier);
if (near != null) {
startCarry(carrier, near);
} }
Player near = findNearestKnocked(carrier);
if (near != null) startCarry(carrier, near);
} }
private static ServerPlayer findNearestKnocked(ServerPlayer carrier) { private static Player findNearestKnocked(ServerPlayer carrier) {
AABB box = carrier.getBoundingBox().inflate(CARRY_RANGE); AABB box = carrier.getBoundingBox().inflate(CARRY_RANGE);
return carrier.getCommandSenderWorld() return carrier
.getEntitiesOfClass(ServerPlayer.class, box).stream() .getCommandSenderWorld()
.getEntitiesOfClass(Player.class, box).stream()
.filter(p -> KnockedManager.isKnocked(p) .filter(p -> KnockedManager.isKnocked(p)
&& !p.getUUID().equals(carrier.getUUID())) && !p.getUUID().equals(carrier.getUUID()))
.findFirst() .findFirst()
.orElse(null); .orElse(null);
} }
private static void startCarry(ServerPlayer carrier, ServerPlayer knocked) { private static void startCarry(ServerPlayer carrier, Player knocked) {
// mount once
knocked.startRiding(carrier, true); knocked.startRiding(carrier, true);
carrying.put(knocked.getUUID(), carrier.getUUID()); carrying.put(knocked.getUUID(), carrier.getUUID());
ClientboundSetPassengersPacket mountPacket = new ClientboundSetPassengersPacket(carrier);
// tell both clients carrier.connection.send(mountPacket);
ClientboundSetPassengersPacket pkt = new ClientboundSetPassengersPacket(carrier); if (knocked instanceof ServerPlayer spKnocked) {
carrier.connection.send(pkt); spKnocked.connection.send(mountPacket);
knocked.connection.send(pkt); }
carrier.sendSystemMessage(Component.literal("Picked up " + knocked.getName().getString())); carrier.sendSystemMessage(Component.literal("Picked up " + knocked.getName().getString()));
knocked.sendSystemMessage(Component.literal("You are being carried by " + carrier.getName().getString())); knocked.sendSystemMessage(Component.literal("You are being carried by " + carrier.getName().getString()));
} }
private static void stopCarry(Player knocked, ServerPlayer carrier) { private static void stopCarry(Player knocked, ServerPlayer carrier) {
knocked.stopRiding(); knocked.stopRiding();
carrying.remove(knocked.getUUID()); carrying.remove(knocked.getUUID());
ClientboundSetPassengersPacket dismountPacket = new ClientboundSetPassengersPacket(carrier);
// same packet to both sides carrier.connection.send(dismountPacket);
ClientboundSetPassengersPacket pkt = new ClientboundSetPassengersPacket(carrier); if (knocked instanceof ServerPlayer spKnocked) {
carrier.connection.send(pkt); spKnocked.connection.send(dismountPacket);
if (knocked instanceof ServerPlayer sp) {
sp.connection.send(pkt);
} }
carrier.sendSystemMessage(Component.literal("Dropped " + knocked.getName().getString())); carrier.sendSystemMessage(Component.literal("Dropped " + knocked.getName().getString()));
knocked.sendSystemMessage(Component.literal("You have been dropped")); knocked.sendSystemMessage(Component.literal("You have been dropped"));
} }
/** 2) auto-drop if out of range or no longer knocked */
@SubscribeEvent @SubscribeEvent
public static void onServerTick(TickEvent.ServerTickEvent ev) { public static void onServerTick(TickEvent.ServerTickEvent ev) {
if (ev.phase != TickEvent.Phase.END || !ev.side.isServer()) return; if (ev.phase != TickEvent.Phase.END || !ev.side.isServer()) return;
var server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(); var server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer();
List<UUID> toDrop = new ArrayList<>(); List<UUID> toDrop = new ArrayList<>();
for (var entry : carrying.entrySet()) { for (var entry : carrying.entrySet()) {
UUID k = entry.getKey(); UUID knockedId = entry.getKey();
UUID c = entry.getValue(); UUID carrierId = entry.getValue();
ServerPlayer carrier = NetworkHandlerHelper.getPlayerByUuid(server, c); ServerPlayer carrier = NetworkHandlerHelper.getPlayerByUuid(server, carrierId);
ServerPlayer knocked = NetworkHandlerHelper.getPlayerByUuid(server, k); ServerPlayer knocked = NetworkHandlerHelper.getPlayerByUuid(server, knockedId);
if (carrier == null || knocked == null if (carrier == null || knocked == null
|| !KnockedManager.isKnocked(knocked) || !KnockedManager.isKnocked(knocked)
|| carrier.distanceTo(knocked) > CARRY_RANGE) { || carrier.distanceTo(knocked) > CARRY_RANGE) {
toDrop.add(k); toDrop.add(knockedId);
} }
} }
toDrop.forEach(k -> { for (UUID kid : toDrop) {
UUID cid = carrying.get(kid);
ServerPlayer carrier = NetworkHandlerHelper.getPlayerByUuid( ServerPlayer carrier = NetworkHandlerHelper.getPlayerByUuid(
net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(), net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(), cid);
carrying.get(k));
ServerPlayer knocked = NetworkHandlerHelper.getPlayerByUuid( ServerPlayer knocked = NetworkHandlerHelper.getPlayerByUuid(
net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(), k); net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(), kid);
if (carrier != null && knocked != null) stopCarry(knocked, carrier); if (carrier != null && knocked != null) stopCarry(knocked, carrier);
});
}
/** 2b) prevent sneak-dismount */
@SubscribeEvent
public static void onEntityMount(EntityMountEvent evt) {
if (!evt.isMounting()
&& evt.getEntityMounting() instanceof Player knocked
&& carrying.containsKey(knocked.getUUID())) {
evt.setCanceled(true);
} }
} }
/** 3) auto-drop if carrier is hurt */ @SubscribeEvent
public static void onEntityMount(EntityMountEvent evt) {
if (!evt.isMounting()) {
if (evt.getEntityMounting() instanceof Player knocked
&& carrying.containsKey(knocked.getUUID())) {
evt.setCanceled(true);
}
}
}
@SubscribeEvent @SubscribeEvent
public static void onCarrierHurt(LivingHurtEvent ev) { public static void onCarrierHurt(LivingHurtEvent ev) {
if (!(ev.getEntity() instanceof ServerPlayer carrier)) return; if (!(ev.getEntity() instanceof ServerPlayer carrier)) return;
@@ -121,9 +114,9 @@ public class CarryManager {
.filter(e -> e.getValue().equals(carrier.getUUID())) .filter(e -> e.getValue().equals(carrier.getUUID()))
.map(Map.Entry::getKey) .map(Map.Entry::getKey)
.findFirst() .findFirst()
.ifPresent(k -> { .ifPresent(knockedId -> {
ServerPlayer knocked = NetworkHandlerHelper.getPlayerByUuid( ServerPlayer knocked = NetworkHandlerHelper.getPlayerByUuid(
net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(), k); net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(), knockedId);
if (knocked != null) stopCarry(knocked, carrier); if (knocked != null) stopCarry(knocked, carrier);
}); });
} }
@@ -7,10 +7,8 @@ import net.minecraftforge.network.simple.SimpleChannel;
public class NetworkHandler { public class NetworkHandler {
public static final String PROTOCOL_VERSION = "1"; public static final String PROTOCOL_VERSION = "1";
public static SimpleChannel CHANNEL; public static SimpleChannel CHANNEL;
public static void register() { public static void register() {
CHANNEL = NetworkRegistry.newSimpleChannel(new ResourceLocation(KnockedBack.MOD_ID, "main"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals); CHANNEL = NetworkRegistry.newSimpleChannel(new ResourceLocation(KnockedBack.MOD_ID, "main"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals);
int id = 0; int id = 0;
CHANNEL.registerMessage(id++, ExecuteKnockedPacket.class, ExecuteKnockedPacket::encode, ExecuteKnockedPacket::decode, ExecuteKnockedPacket::handle); CHANNEL.registerMessage(id++, ExecuteKnockedPacket.class, ExecuteKnockedPacket::encode, ExecuteKnockedPacket::decode, ExecuteKnockedPacket::handle);
CHANNEL.registerMessage(id++, KnockedTimePacket.class, KnockedTimePacket::encode, KnockedTimePacket::decode, KnockedTimePacket::handle); CHANNEL.registerMessage(id++, KnockedTimePacket.class, KnockedTimePacket::encode, KnockedTimePacket::decode, KnockedTimePacket::handle);
@@ -57,12 +57,15 @@ public class PlayerExecutionHandler {
} }
} }
public static void register() { public static void register() {
MinecraftForge.EVENT_BUS.register(new PlayerExecutionHandler()); MinecraftForge.EVENT_BUS.register(new PlayerExecutionHandler());
} }
public static void startExecution(ServerPlayer executor, Player target) { public static void startExecution(ServerPlayer executor, Player target) {
if (KnockedManager.isKnocked(executor)) {
executor.sendSystemMessage(Component.literal("You cannot execute others while you are knocked!"));
return;
}
UUID knockedId = target.getUUID(); UUID knockedId = target.getUUID();
if (!KnockedManager.isKnocked(target)) return; if (!KnockedManager.isKnocked(target)) return;
if (CarryManager.isBeingCarried(target.getUUID())) { if (CarryManager.isBeingCarried(target.getUUID())) {
@@ -14,15 +14,12 @@ public class KnockedTimeOverlay {
@SubscribeEvent @SubscribeEvent
public static void onRenderOverlay(RenderGuiOverlayEvent.Post event) { public static void onRenderOverlay(RenderGuiOverlayEvent.Post event) {
if (!ClientKnockedState.isKnocked()) return; if (!ClientKnockedState.isKnocked()) return;
Minecraft mc = Minecraft.getInstance(); Minecraft mc = Minecraft.getInstance();
GuiGraphics guiGraphics = event.getGuiGraphics(); GuiGraphics guiGraphics = event.getGuiGraphics();
String text = "Time until recovery: " + (ClientKnockedState.getTimeLeft() / 20) + " s"; String text = "Time until recovery: " + (ClientKnockedState.getTimeLeft() / 20) + " s";
int screenWidth = mc.getWindow().getGuiScaledWidth(); int screenWidth = mc.getWindow().getGuiScaledWidth();
int x = screenWidth / 2 - mc.font.width(text) / 2; int x = screenWidth / 2 - mc.font.width(text) / 2;
int y = 10; // 10 pixels from the top int y = 10;
guiGraphics.drawString(mc.font, text, x, y, 0xFFFFFF, true); guiGraphics.drawString(mc.font, text, x, y, 0xFFFFFF, true);
} }
} }