实现载具成员切换

This commit is contained in:
Light_Quanta 2025-03-05 00:46:13 +08:00
parent d98913bb21
commit a507236e08
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
6 changed files with 163 additions and 6 deletions

View file

@ -176,6 +176,7 @@ public class ModUtils {
addNetworkMessage(ResetCameraTypeMessage.class, ResetCameraTypeMessage::encode, ResetCameraTypeMessage::decode, ResetCameraTypeMessage::handler, Optional.of(NetworkDirection.PLAY_TO_CLIENT)); 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(SwitchVehicleWeaponMessage.class, SwitchVehicleWeaponMessage::encode, SwitchVehicleWeaponMessage::decode, SwitchVehicleWeaponMessage::handler);
addNetworkMessage(RadarSetTargetMessage.class, RadarSetTargetMessage::encode, RadarSetTargetMessage::decode, RadarSetTargetMessage::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)), 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()))); Ingredient.of(Items.LIGHTNING_ROD), PotionUtils.setPotion(new ItemStack(Items.POTION), ModPotion.SHOCK.get())));

View file

@ -17,6 +17,7 @@ import com.atsuishio.superbwarfare.tools.SeekTool;
import com.atsuishio.superbwarfare.tools.TraceTool; import com.atsuishio.superbwarfare.tools.TraceTool;
import com.mojang.blaze3d.platform.InputConstants; import com.mojang.blaze3d.platform.InputConstants;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.client.KeyMapping;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
@ -271,6 +272,23 @@ public class ClickHandler {
switchZoom = !switchZoom; 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 { } else {
if (player.hasEffect(ModMobEffects.SHOCK.get())) { if (player.hasEffect(ModMobEffects.SHOCK.get())) {
return; return;

View file

@ -10,6 +10,7 @@ import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier;
import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.init.*;
import com.atsuishio.superbwarfare.network.message.ShakeClientMessage; import com.atsuishio.superbwarfare.network.message.ShakeClientMessage;
import com.atsuishio.superbwarfare.tools.*; import com.atsuishio.superbwarfare.tools.*;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.mojang.math.Axis; import com.mojang.math.Axis;
import net.minecraft.core.BlockPos; 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.item.ItemStack;
import net.minecraft.world.level.Explosion; import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.event.ForgeEventFactory;
@ -42,6 +44,7 @@ import net.minecraftforge.network.NetworkHooks;
import net.minecraftforge.network.PacketDistributor; import net.minecraftforge.network.PacketDistributor;
import net.minecraftforge.network.PlayMessages; import net.minecraftforge.network.PlayMessages;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.joml.Math; import org.joml.Math;
import org.joml.Matrix4f; import org.joml.Matrix4f;
import org.joml.Vector3f; import org.joml.Vector3f;
@ -54,10 +57,11 @@ import software.bernie.geckolib.util.GeckoLibUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Objects;
import static com.atsuishio.superbwarfare.tools.ParticleTool.sendParticle; 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); private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
public static final float MAX_HEALTH = VehicleConfig.AH_6_HP.get(); 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()); entity.setYBodyRot(getYRot());
} }
public int getMaxPassengers() {
return 2;
}
@Override @Override
public Matrix4f getVehicleTransform() { public Matrix4f getVehicleTransform() {
Matrix4f transform = new Matrix4f(); Matrix4f transform = new Matrix4f();
@ -764,6 +764,93 @@ public class Ah6Entity extends ContainerMobileVehicleEntity implements GeoEntity
return this.entityData.get(DECOY_COUNT); return this.entityData.get(DECOY_COUNT);
} }
// 自定义骑乘
// TODO 正确实现成员判断
private final List<Entity> orderedPassengers = generatePassengersList();
private ArrayList<Entity> generatePassengersList() {
var list = new ArrayList<Entity>(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 @Override
public void changeWeapon(int scroll) { public void changeWeapon(int scroll) {
var type = (getWeaponType() + scroll + 2) % 2; var type = (getWeaponType() + scroll + 2) % 2;

View file

@ -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();
}

View file

@ -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<NetworkEvent.Context> 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);
}
}

View file

@ -3,4 +3,5 @@ public net.minecraft.server.level.DistanceManager$PlayerTicketTracker f_140905_
public net.minecraft.server.level.DistanceManager$PlayerTicketTracker 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.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.renderer.culling.Frustum f_252406_ # matrix
public net.minecraft.client.player.LocalPlayer f_108611_ # handsBusy public net.minecraft.client.player.LocalPlayer f_108611_ # handsBusy
public net.minecraft.world.entity.Entity f_19823_ # passengers