add "Help Up" feature for knocked players, improve execution handling, and update mod version to 1.6.0
This commit is contained in:
@@ -10,6 +10,7 @@ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.event.entity.EntityMountEvent;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -26,11 +27,15 @@ public class CarryManager {
|
||||
Optional<Player> existing = carrier.getPassengers().stream()
|
||||
.filter(p -> p instanceof Player)
|
||||
.map(p -> (Player) p)
|
||||
.filter(p -> carrier.getUUID().equals(carrying.get(p.getUUID())))
|
||||
.findFirst();
|
||||
if (existing.isPresent()) {
|
||||
stopCarry(existing.get(), carrier);
|
||||
return;
|
||||
}
|
||||
if (stopCarrying(carrier.getUUID())) {
|
||||
return;
|
||||
}
|
||||
Player near = findNearestKnocked(carrier);
|
||||
if (near != null) startCarry(carrier, near);
|
||||
}
|
||||
@@ -45,18 +50,19 @@ public class CarryManager {
|
||||
&& !isBeingCarried(p.getUUID())
|
||||
&& !PlayerExecutionHandler.isBeingPlayerExecuted(p.getUUID())
|
||||
&& !HelpUpHandler.isBeingHelped(p.getUUID()))
|
||||
.findFirst()
|
||||
.min(Comparator.comparingDouble(carrier::distanceToSqr))
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
private static void startCarry(ServerPlayer carrier, Player knocked) {
|
||||
knocked.startRiding(carrier, true);
|
||||
carrying.put(knocked.getUUID(), carrier.getUUID());
|
||||
ClientboundSetPassengersPacket mountPacket = new ClientboundSetPassengersPacket(carrier);
|
||||
carrier.connection.send(mountPacket);
|
||||
if (knocked instanceof ServerPlayer spKnocked) {
|
||||
spKnocked.connection.send(mountPacket);
|
||||
if (knocked.level() != carrier.level()) {
|
||||
return;
|
||||
}
|
||||
if (!knocked.startRiding(carrier, true)) {
|
||||
return;
|
||||
}
|
||||
carrying.put(knocked.getUUID(), carrier.getUUID());
|
||||
sendPassengerUpdate(carrier);
|
||||
KnockedbackAdvancements.recordCarry(carrier);
|
||||
carrier.sendSystemMessage(Component.translatable("message.knockedback.picked_up", knocked.getDisplayName()));
|
||||
knocked.sendSystemMessage(Component.translatable("message.knockedback.being_carried", carrier.getDisplayName()));
|
||||
@@ -66,15 +72,43 @@ public class CarryManager {
|
||||
private static void stopCarry(Player knocked, ServerPlayer carrier) {
|
||||
carrying.remove(knocked.getUUID());
|
||||
knocked.stopRiding();
|
||||
ClientboundSetPassengersPacket dismountPacket = new ClientboundSetPassengersPacket(carrier);
|
||||
carrier.connection.send(dismountPacket);
|
||||
if (knocked instanceof ServerPlayer spKnocked) {
|
||||
spKnocked.connection.send(dismountPacket);
|
||||
}
|
||||
sendPassengerUpdate(carrier);
|
||||
carrier.sendSystemMessage(Component.translatable("message.knockedback.dropped", knocked.getDisplayName()));
|
||||
knocked.sendSystemMessage(Component.translatable("message.knockedback.been_dropped", carrier.getDisplayName()));
|
||||
}
|
||||
|
||||
public static void stopCarry(UUID knockedId) {
|
||||
UUID carrierId = carrying.get(knockedId);
|
||||
if (carrierId == null) return;
|
||||
var server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer();
|
||||
ServerPlayer carrier = NetworkHandlerHelper.getPlayerByUuid(server, carrierId);
|
||||
ServerPlayer knocked = NetworkHandlerHelper.getPlayerByUuid(server, knockedId);
|
||||
if (carrier != null && knocked != null) {
|
||||
stopCarry(knocked, carrier);
|
||||
} else {
|
||||
carrying.remove(knockedId);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean stopCarrying(UUID carrierId) {
|
||||
List<UUID> knockedIds = carrying.entrySet().stream()
|
||||
.filter(entry -> entry.getValue().equals(carrierId))
|
||||
.map(Map.Entry::getKey)
|
||||
.toList();
|
||||
for (UUID knockedId : knockedIds) {
|
||||
stopCarry(knockedId);
|
||||
}
|
||||
return !knockedIds.isEmpty();
|
||||
}
|
||||
|
||||
private static void sendPassengerUpdate(ServerPlayer carrier) {
|
||||
if (carrier.level() instanceof ServerLevel level) {
|
||||
level.getChunkSource().broadcastAndSend(carrier, new ClientboundSetPassengersPacket(carrier));
|
||||
} else {
|
||||
carrier.connection.send(new ClientboundSetPassengersPacket(carrier));
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onServerTick(TickEvent.ServerTickEvent ev) {
|
||||
if (ev.phase != TickEvent.Phase.END || !ev.side.isServer()) return;
|
||||
@@ -87,7 +121,9 @@ public class CarryManager {
|
||||
ServerPlayer knocked = NetworkHandlerHelper.getPlayerByUuid(server, knockedId);
|
||||
if (carrier == null || knocked == null
|
||||
|| !KnockedManager.isKnocked(knocked)
|
||||
|| carrier.distanceTo(knocked) > CARRY_RANGE) {
|
||||
|| carrier.level() != knocked.level()
|
||||
|| knocked.getVehicle() != carrier
|
||||
|| carrier.distanceToSqr(knocked) > CARRY_RANGE * CARRY_RANGE) {
|
||||
toDrop.add(knockedId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,8 +45,9 @@ public class ExecuteKnockedPacket {
|
||||
.map(uuid -> NetworkHandlerHelper.getPlayerByUuid(executor.getServer(), uuid))
|
||||
.filter(player -> player != null
|
||||
&& !player.getUUID().equals(executor.getUUID())
|
||||
&& player.distanceTo(executor) <= (float) PlayerExecutionHandler.EXECUTION_RANGE)
|
||||
.findFirst()
|
||||
&& player.level() == executor.level()
|
||||
&& player.distanceToSqr(executor) <= PlayerExecutionHandler.EXECUTION_RANGE * PlayerExecutionHandler.EXECUTION_RANGE)
|
||||
.min(java.util.Comparator.comparingDouble(executor::distanceToSqr))
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,14 +115,17 @@ public class HelpUpHandler {
|
||||
HelpUpAttempt attempt = entry.getValue();
|
||||
ServerPlayer knocked = getPlayerByUuid(knockedId);
|
||||
ServerPlayer helper = getPlayerByUuid(attempt.helperId);
|
||||
if (knocked == null || helper == null || !KnockedManager.isKnocked(knocked)) {
|
||||
if (knocked == null || helper == null
|
||||
|| !KnockedManager.isKnocked(knocked)
|
||||
|| KnockedManager.isKnocked(helper)) {
|
||||
toCancel.add(knockedId);
|
||||
continue;
|
||||
}
|
||||
if (CarryManager.isBeingCarried(knockedId)
|
||||
|| PlayerExecutionHandler.isBeingPlayerExecuted(knockedId)
|
||||
|| MobKillHandler.isBeingMobExecuted(knockedId)
|
||||
|| helper.distanceTo(knocked) > HELP_UP_RANGE) {
|
||||
|| helper.level() != knocked.level()
|
||||
|| helper.distanceToSqr(knocked) > HELP_UP_RANGE * HELP_UP_RANGE) {
|
||||
toCancel.add(knockedId);
|
||||
continue;
|
||||
}
|
||||
@@ -143,7 +146,9 @@ public class HelpUpHandler {
|
||||
if (attempt == null) continue;
|
||||
ServerPlayer knocked = getPlayerByUuid(knockedId);
|
||||
ServerPlayer helper = getPlayerByUuid(attempt.helperId);
|
||||
if (knocked == null || helper == null) {
|
||||
if (knocked == null || helper == null
|
||||
|| helper.level() != knocked.level()
|
||||
|| helper.distanceToSqr(knocked) > HELP_UP_RANGE * HELP_UP_RANGE) {
|
||||
cancelHelpUp(knockedId);
|
||||
continue;
|
||||
}
|
||||
@@ -190,7 +195,7 @@ public class HelpUpHandler {
|
||||
&& !PlayerExecutionHandler.isBeingPlayerExecuted(player.getUUID())
|
||||
&& !MobKillHandler.isBeingMobExecuted(player.getUUID())
|
||||
&& !isBeingHelped(player.getUUID()))
|
||||
.findFirst()
|
||||
.min(java.util.Comparator.comparingDouble(helper::distanceToSqr))
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
|
||||
@@ -69,9 +69,11 @@ public class KnockedManager {
|
||||
}
|
||||
|
||||
public static void removeKnockedState(LivingEntity entity) {
|
||||
CarryManager.stopCarry(entity.getUUID());
|
||||
knockedEntities.remove(entity.getUUID());
|
||||
setGripped(entity, false);
|
||||
MobKillHandler.clearKillAttempt(entity.getUUID());
|
||||
PlayerExecutionHandler.cancelExecution(entity.getUUID());
|
||||
HelpUpHandler.cancelHelpUp(entity.getUUID());
|
||||
entity.setPose(Pose.STANDING);
|
||||
if (entity instanceof ServerPlayer sp) {
|
||||
@@ -211,8 +213,12 @@ public class KnockedManager {
|
||||
knockedEntities.remove(playerId);
|
||||
grippedEntities.remove(playerId);
|
||||
MobKillHandler.clearKillAttempt(playerId);
|
||||
PlayerExecutionHandler.cancelExecution(playerId);
|
||||
PlayerExecutionHandler.cancelExecutionByExecutor(playerId);
|
||||
HelpUpHandler.cancelHelpUp(playerId);
|
||||
HelpUpHandler.cancelHelpUpByHelper(playerId);
|
||||
CarryManager.stopCarry(playerId);
|
||||
CarryManager.stopCarrying(playerId);
|
||||
NetworkHandler.CHANNEL.send(
|
||||
PacketDistributor.PLAYER.with(() -> sp),
|
||||
new KnockedTimePacket(0)
|
||||
@@ -238,7 +244,10 @@ public class KnockedManager {
|
||||
return;
|
||||
}
|
||||
HelpUpHandler.cancelHelpUpByHelper(sp.getUUID());
|
||||
PlayerExecutionHandler.cancelExecutionByExecutor(sp.getUUID());
|
||||
CarryManager.stopCarrying(sp.getUUID());
|
||||
if (!isKnocked(sp)) {
|
||||
CarryManager.stopCarry(sp.getUUID());
|
||||
return;
|
||||
}
|
||||
killAndRemove(sp);
|
||||
|
||||
@@ -109,6 +109,11 @@ public class MobKillHandler {
|
||||
setGripped(knocked, false);
|
||||
continue;
|
||||
}
|
||||
if (PlayerExecutionHandler.isBeingPlayerExecuted(knockedId)
|
||||
|| HelpUpHandler.isBeingHelped(knockedId)) {
|
||||
setGripped(knocked, false);
|
||||
continue;
|
||||
}
|
||||
KillAttempt attempt = killAttempts.get(knockedId);
|
||||
Mob mob = attempt != null ? getMobInRangeById(knocked, attempt.mobUuid) : null;
|
||||
if (mob == null) {
|
||||
|
||||
@@ -70,13 +70,17 @@ public class PlayerExecutionHandler {
|
||||
executor.sendSystemMessage(Component.translatable("message.knockedback.cannot_execute_while_knocked"));
|
||||
return;
|
||||
}
|
||||
if (isExecuting(executor.getUUID())) return;
|
||||
UUID knockedId = target.getUUID();
|
||||
if (!KnockedManager.isKnocked(target)) return;
|
||||
if (executor.level() != target.level()
|
||||
|| executor.distanceToSqr(target) > EXECUTION_RANGE * EXECUTION_RANGE) return;
|
||||
if (CarryManager.isBeingCarried(target.getUUID())) {
|
||||
executor.sendSystemMessage(Component.translatable("message.knockedback.cannot_execute_carried_player"));
|
||||
return;
|
||||
}
|
||||
if (HelpUpHandler.isBeingHelped(knockedId)) return;
|
||||
if (MobKillHandler.isBeingMobExecuted(knockedId)) return;
|
||||
if (executionAttempts.containsKey(knockedId)) return;
|
||||
executionAttempts.put(knockedId, new PlayerExecutionAttempt(executor.getUUID()));
|
||||
executor.sendSystemMessage(Component.translatable("message.knockedback.execution_started"));
|
||||
@@ -105,12 +109,9 @@ public class PlayerExecutionHandler {
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onLivingHurt(LivingHurtEvent event) {
|
||||
if (!(event.getEntity() instanceof ServerPlayer hurtPlayer)) return;
|
||||
UUID hurtId = hurtPlayer.getUUID();
|
||||
public static void cancelExecutionByExecutor(UUID executorId) {
|
||||
List<UUID> toCancel = executionAttempts.entrySet().stream()
|
||||
.filter(entry -> entry.getValue().executorUuid.equals(hurtId))
|
||||
.filter(entry -> entry.getValue().executorUuid.equals(executorId))
|
||||
.map(Map.Entry::getKey)
|
||||
.toList();
|
||||
for (UUID knockedId : toCancel) {
|
||||
@@ -118,12 +119,24 @@ public class PlayerExecutionHandler {
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onLivingHurt(LivingHurtEvent event) {
|
||||
if (!(event.getEntity() instanceof ServerPlayer hurtPlayer)) return;
|
||||
cancelExecutionByExecutor(hurtPlayer.getUUID());
|
||||
}
|
||||
|
||||
private static ServerPlayer getPlayerByUuid(UUID uuid) {
|
||||
MinecraftServer server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer();
|
||||
return server.getPlayerList().getPlayer(uuid);
|
||||
}
|
||||
|
||||
public static void executeKnockedPlayer(ServerPlayer executor, LivingEntity knockedPlayer) {
|
||||
if (!KnockedManager.isKnocked(knockedPlayer)
|
||||
|| executor.level() != knockedPlayer.level()
|
||||
|| executor.distanceToSqr(knockedPlayer) > EXECUTION_RANGE * EXECUTION_RANGE) {
|
||||
cancelExecution(knockedPlayer.getUUID());
|
||||
return;
|
||||
}
|
||||
UUID id = knockedPlayer.getUUID();
|
||||
executionAttempts.remove(id);
|
||||
KnockedManager.removeKnockedState(knockedPlayer);
|
||||
@@ -159,11 +172,16 @@ public class PlayerExecutionHandler {
|
||||
PlayerExecutionAttempt attempt = entry.getValue();
|
||||
ServerPlayer knocked = getPlayerByUuid(knockedId);
|
||||
ServerPlayer executor = getPlayerByUuid(attempt.executorUuid);
|
||||
if (knocked == null || executor == null || !KnockedManager.isKnocked(knocked)) {
|
||||
if (knocked == null || executor == null
|
||||
|| !KnockedManager.isKnocked(knocked)
|
||||
|| KnockedManager.isKnocked(executor)) {
|
||||
toCancel.add(knockedId);
|
||||
continue;
|
||||
}
|
||||
if (executor.distanceTo(knocked) > EXECUTION_RANGE) {
|
||||
if (executor.level() != knocked.level()
|
||||
|| executor.distanceToSqr(knocked) > EXECUTION_RANGE * EXECUTION_RANGE
|
||||
|| CarryManager.isBeingCarried(knockedId)
|
||||
|| HelpUpHandler.isBeingHelped(knockedId)) {
|
||||
toCancel.add(knockedId);
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user