From a507236e0899b12cbd93e1cb188c4b9fdadc0387 Mon Sep 17 00:00:00 2001 From: Light_Quanta Date: Wed, 5 Mar 2025 00:46:13 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E8=BD=BD=E5=85=B7=E6=88=90?= =?UTF-8?q?=E5=91=98=E5=88=87=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/atsuishio/superbwarfare/ModUtils.java | 1 + .../superbwarfare/client/ClickHandler.java | 18 ++++ .../entity/vehicle/Ah6Entity.java | 97 ++++++++++++++++++- .../vehicle/MultiSeatVehicleEntity.java | 13 +++ .../message/ChangeVehicleSeatMessage.java | 37 +++++++ .../resources/META-INF/accesstransformer.cfg | 3 +- 6 files changed, 163 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/atsuishio/superbwarfare/entity/vehicle/MultiSeatVehicleEntity.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/network/message/ChangeVehicleSeatMessage.java diff --git a/src/main/java/com/atsuishio/superbwarfare/ModUtils.java b/src/main/java/com/atsuishio/superbwarfare/ModUtils.java index a4f488b70..1cb232e2b 100644 --- a/src/main/java/com/atsuishio/superbwarfare/ModUtils.java +++ b/src/main/java/com/atsuishio/superbwarfare/ModUtils.java @@ -176,6 +176,7 @@ public class ModUtils { addNetworkMessage(ResetCameraTypeMessage.class, ResetCameraTypeMessage::encode, ResetCameraTypeMessage::decode, ResetCameraTypeMessage::handler, Optional.of(NetworkDirection.PLAY_TO_CLIENT)); addNetworkMessage(SwitchVehicleWeaponMessage.class, SwitchVehicleWeaponMessage::encode, SwitchVehicleWeaponMessage::decode, SwitchVehicleWeaponMessage::handler); addNetworkMessage(RadarSetTargetMessage.class, RadarSetTargetMessage::encode, RadarSetTargetMessage::decode, RadarSetTargetMessage::handler); + addNetworkMessage(ChangeVehicleSeatMessage.class, ChangeVehicleSeatMessage::encode, ChangeVehicleSeatMessage::decode, ChangeVehicleSeatMessage::handler); event.enqueueWork(() -> BrewingRecipeRegistry.addRecipe(Ingredient.of(PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.WATER)), Ingredient.of(Items.LIGHTNING_ROD), PotionUtils.setPotion(new ItemStack(Items.POTION), ModPotion.SHOCK.get()))); diff --git a/src/main/java/com/atsuishio/superbwarfare/client/ClickHandler.java b/src/main/java/com/atsuishio/superbwarfare/client/ClickHandler.java index 6efc456e5..7f72bb82e 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/ClickHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/ClickHandler.java @@ -17,6 +17,7 @@ import com.atsuishio.superbwarfare.tools.SeekTool; import com.atsuishio.superbwarfare.tools.TraceTool; import com.mojang.blaze3d.platform.InputConstants; import net.minecraft.ChatFormatting; +import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; @@ -271,6 +272,23 @@ public class ClickHandler { switchZoom = !switchZoom; } } + + // 未按住shift且在可切换座位的载具上时,发送切换座位消息 + if (!Screen.hasShiftDown() && player.getVehicle() instanceof MultiSeatVehicleEntity vehicle) { + int index = -1; + for (int slot = 0; slot < Minecraft.getInstance().options.keyHotbarSlots.length; ++slot) { + KeyMapping keyHotbarSlot = Minecraft.getInstance().options.keyHotbarSlots[slot]; + if (key == keyHotbarSlot.getKey().getValue()) { + index = slot; + break; + } + } + + if (index != -1 && index < vehicle.getSeatCount()) { + ModUtils.PACKET_HANDLER.sendToServer(new ChangeVehicleSeatMessage(index)); + } + } + } else { if (player.hasEffect(ModMobEffects.SHOCK.get())) { return; diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Ah6Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Ah6Entity.java index 05b4234a7..9647164ef 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Ah6Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Ah6Entity.java @@ -10,6 +10,7 @@ import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier; import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.network.message.ShakeClientMessage; import com.atsuishio.superbwarfare.tools.*; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.mojang.math.Axis; import net.minecraft.core.BlockPos; @@ -35,6 +36,7 @@ import net.minecraft.world.entity.vehicle.DismountHelper; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Explosion; import net.minecraft.world.level.Level; +import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; import net.minecraftforge.event.ForgeEventFactory; @@ -42,6 +44,7 @@ import net.minecraftforge.network.NetworkHooks; import net.minecraftforge.network.PacketDistributor; import net.minecraftforge.network.PlayMessages; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.joml.Math; import org.joml.Matrix4f; import org.joml.Vector3f; @@ -54,10 +57,11 @@ import software.bernie.geckolib.util.GeckoLibUtil; import java.util.ArrayList; import java.util.Comparator; import java.util.List; +import java.util.Objects; import static com.atsuishio.superbwarfare.tools.ParticleTool.sendParticle; -public class Ah6Entity extends ContainerMobileVehicleEntity implements GeoEntity, IHelicopterEntity, MultiWeaponVehicleEntity { +public class Ah6Entity extends ContainerMobileVehicleEntity implements GeoEntity, IHelicopterEntity, MultiWeaponVehicleEntity, MultiSeatVehicleEntity { private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); public static final float MAX_HEALTH = VehicleConfig.AH_6_HP.get(); @@ -441,10 +445,6 @@ public class Ah6Entity extends ContainerMobileVehicleEntity implements GeoEntity entity.setYBodyRot(getYRot()); } - public int getMaxPassengers() { - return 2; - } - @Override public Matrix4f getVehicleTransform() { Matrix4f transform = new Matrix4f(); @@ -764,6 +764,93 @@ public class Ah6Entity extends ContainerMobileVehicleEntity implements GeoEntity return this.entityData.get(DECOY_COUNT); } + + // 自定义骑乘 + // TODO 正确实现成员判断 + + private final List orderedPassengers = generatePassengersList(); + + private ArrayList generatePassengersList() { + var list = new ArrayList(this.getMaxPassengers()); + for (int i = 0; i < this.getMaxPassengers(); i++) { + list.add(null); + } + return list; + } + + @Override + protected void addPassenger(Entity pPassenger) { + if (pPassenger.getVehicle() != this) { + throw new IllegalStateException("Use x.startRiding(y), not y.addPassenger(x)"); + } + + int index = 0; + for (Entity passenger : orderedPassengers) { + if (passenger == null) { + break; + } + index++; + } + if (index >= getMaxPassengers()) return; + + orderedPassengers.set(index, pPassenger); + this.passengers = ImmutableList.copyOf(orderedPassengers.stream().filter(Objects::nonNull).toList()); + this.gameEvent(GameEvent.ENTITY_MOUNT, pPassenger); + } + + @Nullable + @Override + public LivingEntity getControllingPassenger() { + var first = this.orderedPassengers.get(0); + if (first instanceof LivingEntity) return (LivingEntity) first; + return null; + } + + @Nullable + @Override + public Entity getFirstPassenger() { + return orderedPassengers.get(0); + } + + @Override + protected void removePassenger(@NotNull Entity pPassenger) { + super.removePassenger(pPassenger); + + var index = orderedPassengers.indexOf(pPassenger); + if (index != -1) { + orderedPassengers.set(index, null); + } + } + + + public int getMaxPassengers() { + return 2; + } + + public Entity getNthEntity(int index) { + return orderedPassengers.get(index); + } + + public boolean changeSeat(Entity entity, int index) { + if (index < 0 || index >= getMaxPassengers()) return false; + if (orderedPassengers.get(index) != null) return false; + if (!orderedPassengers.contains(entity)) return false; + + orderedPassengers.set(orderedPassengers.indexOf(entity), null); + orderedPassengers.set(index, entity); + + return true; + } + + public int getSeatIndex(Entity entity) { + return orderedPassengers.indexOf(entity); + } + + public int getSeatCount() { + return getMaxPassengers(); + } + + @Override public void changeWeapon(int scroll) { var type = (getWeaponType() + scroll + 2) % 2; diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/MultiSeatVehicleEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/MultiSeatVehicleEntity.java new file mode 100644 index 000000000..c9d223201 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/MultiSeatVehicleEntity.java @@ -0,0 +1,13 @@ +package com.atsuishio.superbwarfare.entity.vehicle; + +import net.minecraft.world.entity.Entity; + +public interface MultiSeatVehicleEntity { + public Entity getNthEntity(int index); + + public boolean changeSeat(Entity entity, int index); + + public int getSeatIndex(Entity entity); + + public int getSeatCount(); +} diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/ChangeVehicleSeatMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/ChangeVehicleSeatMessage.java new file mode 100644 index 000000000..3ec268e9d --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/ChangeVehicleSeatMessage.java @@ -0,0 +1,37 @@ +package com.atsuishio.superbwarfare.network.message; + +import com.atsuishio.superbwarfare.entity.vehicle.MultiSeatVehicleEntity; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.server.level.ServerPlayer; +import net.minecraftforge.network.NetworkEvent; + +import java.util.function.Supplier; + +public class ChangeVehicleSeatMessage { + + private final int index; + + public ChangeVehicleSeatMessage(int index) { + this.index = index; + } + + public static void encode(ChangeVehicleSeatMessage message, FriendlyByteBuf byteBuf) { + byteBuf.writeInt(message.index); + } + + public static ChangeVehicleSeatMessage decode(FriendlyByteBuf byteBuf) { + return new ChangeVehicleSeatMessage(byteBuf.readInt()); + } + + public static void handler(ChangeVehicleSeatMessage message, Supplier context) { + context.get().enqueueWork(() -> { + ServerPlayer player = context.get().getSender(); + if (player == null || !(player.getVehicle() instanceof MultiSeatVehicleEntity vehicle)) { + return; + } + + vehicle.changeSeat(player, message.index); + }); + context.get().setPacketHandled(true); + } +} diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 04ff8c24d..8d7eb8314 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -3,4 +3,5 @@ public net.minecraft.server.level.DistanceManager$PlayerTicketTracker f_140905_ public net.minecraft.server.level.DistanceManager$PlayerTicketTracker public net.minecraft.client.multiplayer.ClientLevel m_142646_()Lnet/minecraft/world/level/entity/LevelEntityGetter; # getEntities public net.minecraft.client.renderer.culling.Frustum f_252406_ # matrix -public net.minecraft.client.player.LocalPlayer f_108611_ # handsBusy \ No newline at end of file +public net.minecraft.client.player.LocalPlayer f_108611_ # handsBusy +public net.minecraft.world.entity.Entity f_19823_ # passengers \ No newline at end of file