整合顺序多座位载具接口

This commit is contained in:
Light_Quanta 2025-03-05 03:03:12 +08:00
parent fdd4dd97c9
commit 77342a999c
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
5 changed files with 121 additions and 167 deletions

View file

@ -154,20 +154,15 @@ public class ClickHandler {
double scroll = event.getScrollDelta(); double scroll = event.getScrollDelta();
// 未按下shift时为载具切换武器 // 未按下shift时为有多武器的载具切换武器
if (player.getVehicle() instanceof MultiWeaponVehicleEntity multiWeaponVehicle && !Screen.hasShiftDown()) { if (!Screen.hasShiftDown()
if (player.getVehicle() instanceof MultiSeatVehicleEntity multiSeatVehicle) { && player.getVehicle() instanceof VehicleEntity vehicle
// 若该载具有多个座位且该座位存在武器时取消滚动并发送武器切换请求 && vehicle instanceof MultiWeaponVehicleEntity multiWeaponVehicle
if (multiWeaponVehicle.hasWeapon(multiSeatVehicle.getSeatIndex(player))) { && multiWeaponVehicle.hasWeapon(vehicle.getSeatIndex(player))
int index = multiSeatVehicle.getSeatIndex(player); ) {
ModUtils.PACKET_HANDLER.sendToServer(new SwitchVehicleWeaponMessage(index, -scroll)); int index = vehicle.getSeatIndex(player);
event.setCanceled(true); ModUtils.PACKET_HANDLER.sendToServer(new SwitchVehicleWeaponMessage(index, -scroll));
} event.setCanceled(true);
} else {
// 若该载具无多座位直接发送0号位武器切换请求
ModUtils.PACKET_HANDLER.sendToServer(new SwitchVehicleWeaponMessage(0, -scroll));
event.setCanceled(true);
}
} }
if (stack.is(ModTags.Items.GUN) && ClientEventHandler.zoom) { if (stack.is(ModTags.Items.GUN) && ClientEventHandler.zoom) {
@ -285,7 +280,7 @@ public class ClickHandler {
} }
// 未按住shift且在可切换座位的载具上时发送切换座位消息 // 未按住shift且在可切换座位的载具上时发送切换座位消息
if (!Screen.hasShiftDown() && player.getVehicle() instanceof MultiSeatVehicleEntity vehicle) { if (!Screen.hasShiftDown() && player.getVehicle() instanceof VehicleEntity vehicle) {
int index = -1; int index = -1;
for (int slot = 0; slot < Minecraft.getInstance().options.keyHotbarSlots.length; ++slot) { for (int slot = 0; slot < Minecraft.getInstance().options.keyHotbarSlots.length; ++slot) {
KeyMapping keyHotbarSlot = Minecraft.getInstance().options.keyHotbarSlots[slot]; KeyMapping keyHotbarSlot = Minecraft.getInstance().options.keyHotbarSlots[slot];
@ -295,7 +290,7 @@ public class ClickHandler {
} }
} }
if (index != -1 && index < vehicle.getSeatCount() && vehicle.getNthEntity(index) == null) { if (index != -1 && index < vehicle.getMaxPassengers() && vehicle.getNthEntity(index) == null) {
ModUtils.PACKET_HANDLER.sendToServer(new ChangeVehicleSeatMessage(index)); ModUtils.PACKET_HANDLER.sendToServer(new ChangeVehicleSeatMessage(index));
vehicle.changeSeat(player, index); vehicle.changeSeat(player, index);
} }

View file

@ -8,13 +8,11 @@ import com.atsuishio.superbwarfare.entity.projectile.HeliRocketEntity;
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.ContainerMobileVehicleEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.ContainerMobileVehicleEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.HelicopterEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.HelicopterEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.MultiSeatVehicleEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.MultiWeaponVehicleEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.MultiWeaponVehicleEntity;
import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier; 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;
@ -40,7 +38,6 @@ 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;
@ -48,7 +45,6 @@ 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;
@ -61,11 +57,10 @@ 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, HelicopterEntity, MultiWeaponVehicleEntity, MultiSeatVehicleEntity { public class Ah6Entity extends ContainerMobileVehicleEntity implements GeoEntity, HelicopterEntity, MultiWeaponVehicleEntity {
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();
@ -769,97 +764,10 @@ public class Ah6Entity extends ContainerMobileVehicleEntity implements GeoEntity
return this.entityData.get(DECOY_COUNT); return this.entityData.get(DECOY_COUNT);
} }
// 自定义骑乘
private final List<Entity> orderedPassengers = generatePassengersList();
@Override
public List<Entity> getOrderedPassengers() {
return orderedPassengers;
}
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() { public int getMaxPassengers() {
return 2; 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 index, int scroll) { public void changeWeapon(int index, int scroll) {
if (index != 0) return; if (index != 0) return;

View file

@ -1,56 +0,0 @@
package com.atsuishio.superbwarfare.entity.vehicle.base;
import net.minecraft.world.entity.Entity;
import java.util.List;
/**
* 拥有多个按顺序排列的座位的载具每个座位可以为空
* <p>
* 需要为实体自己重写addPassengergetControllingPassengergetFirstPassengerremovePassenger等方法
*/
public interface MultiSeatVehicleEntity {
/**
* 获取按顺序排列的成员列表
*
* @return 按顺序排列的成员列表
*/
List<Entity> getOrderedPassengers();
/**
* 获取第index个乘客
*
* @param index 目标座位
* @return 目标座位的乘客
*/
Entity getNthEntity(int index);
/**
* 尝试切换座位
*
* @param entity 乘客
* @param index 目标座位
* @return 是否切换成功
*/
boolean changeSeat(Entity entity, int index);
/**
* 获取乘客所在座位索引
*
* @param entity 乘客
* @return 座位索引
*/
int getSeatIndex(Entity entity);
/**
* 获取座位数量
*
* @return 座位数量
*/
int getSeatCount();
}

View file

@ -13,6 +13,7 @@ import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage;
import com.atsuishio.superbwarfare.tools.EntityFindUtil; import com.atsuishio.superbwarfare.tools.EntityFindUtil;
import com.atsuishio.superbwarfare.tools.ParticleTool; import com.atsuishio.superbwarfare.tools.ParticleTool;
import com.atsuishio.superbwarfare.tools.VectorTool; import com.atsuishio.superbwarfare.tools.VectorTool;
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;
@ -40,17 +41,20 @@ import net.minecraft.world.entity.vehicle.DismountHelper;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.fluids.FluidType; import net.minecraftforge.fluids.FluidType;
import net.minecraftforge.network.PacketDistributor; import net.minecraftforge.network.PacketDistributor;
import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistries;
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.Vector4f; import org.joml.Vector4f;
import java.util.ArrayList; import java.util.ArrayList;
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;
@ -73,6 +77,109 @@ public abstract class VehicleEntity extends Entity {
public int repairCoolDown = maxRepairCoolDown(); public int repairCoolDown = maxRepairCoolDown();
public boolean crash; public boolean crash;
// 自定义骑乘
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;
}
/**
* 获取按顺序排列的成员列表
*
* @return 按顺序排列的成员列表
*/
public List<Entity> getOrderedPassengers() {
return orderedPassengers;
}
@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 living) return living;
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);
}
}
/**
* 获取第index个乘客
*
* @param index 目标座位
* @return 目标座位的乘客
*/
public Entity getNthEntity(int index) {
return orderedPassengers.get(index);
}
/**
* 尝试切换座位
*
* @param entity 乘客
* @param index 目标座位
* @return 是否切换成功
*/
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;
}
/**
* 获取乘客所在座位索引
*
* @param entity 乘客
* @return 座位索引
*/
public int getSeatIndex(Entity entity) {
return orderedPassengers.indexOf(entity);
}
public float getRoll() { public float getRoll() {
return roll; return roll;
} }

View file

@ -1,6 +1,6 @@
package com.atsuishio.superbwarfare.network.message; package com.atsuishio.superbwarfare.network.message;
import com.atsuishio.superbwarfare.entity.vehicle.base.MultiSeatVehicleEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.network.NetworkEvent; import net.minecraftforge.network.NetworkEvent;
@ -26,7 +26,7 @@ public class ChangeVehicleSeatMessage {
public static void handler(ChangeVehicleSeatMessage message, Supplier<NetworkEvent.Context> context) { public static void handler(ChangeVehicleSeatMessage message, Supplier<NetworkEvent.Context> context) {
context.get().enqueueWork(() -> { context.get().enqueueWork(() -> {
ServerPlayer player = context.get().getSender(); ServerPlayer player = context.get().getSender();
if (player == null || !(player.getVehicle() instanceof MultiSeatVehicleEntity vehicle)) { if (player == null || !(player.getVehicle() instanceof VehicleEntity vehicle)) {
return; return;
} }