Some bug fixes
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user