尝试使用数据包控制无人机挂载

This commit is contained in:
Light_Quanta 2025-07-01 04:50:05 +08:00
parent cbc71d062a
commit 7b0f0959a2
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
6 changed files with 116 additions and 8 deletions

View file

@ -2,6 +2,7 @@
package com.atsuishio.superbwarfare.client.renderer.entity;
import com.atsuishio.superbwarfare.client.model.entity.DroneModel;
import com.atsuishio.superbwarfare.data.CustomData;
import com.atsuishio.superbwarfare.entity.projectile.MortarShellEntity;
import com.atsuishio.superbwarfare.entity.projectile.RgoGrenadeEntity;
import com.atsuishio.superbwarfare.entity.projectile.RpgRocketEntity;
@ -19,12 +20,15 @@ import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.NotNull;
import software.bernie.geckolib.cache.object.BakedGeoModel;
import software.bernie.geckolib.cache.object.GeoBone;
import software.bernie.geckolib.renderer.GeoEntityRenderer;
import static com.atsuishio.superbwarfare.entity.vehicle.DroneEntity.ATTACHED;
import static com.atsuishio.superbwarfare.entity.vehicle.DroneEntity.KAMIKAZE_MODE;
import static com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity.AMMO;
@ -48,7 +52,7 @@ public class DroneRenderer extends GeoEntityRenderer<DroneEntity> {
}
@Override
public void render(DroneEntity entityIn, float entityYaw, float partialTicks, PoseStack poseStack, MultiBufferSource bufferIn, int packedLightIn) {
public void render(DroneEntity entityIn, float entityYaw, float partialTicks, PoseStack poseStack, @NotNull MultiBufferSource bufferIn, int packedLightIn) {
poseStack.pushPose();
poseStack.mulPose(Axis.YP.rotationDegrees(-entityIn.getYaw(partialTicks)));
poseStack.mulPose(Axis.XP.rotationDegrees(entityIn.getBodyPitch(partialTicks)));
@ -110,12 +114,39 @@ public class DroneRenderer extends GeoEntityRenderer<DroneEntity> {
entityRenderDispatcher.render(entity, xOffset, yOffset, 0, entityYaw, partialTicks, poseStack, bufferIn, packedLightIn);
poseStack.popPose();
}
renderAttachments(entityIn, player, entityYaw, partialTicks, poseStack, bufferIn, packedLightIn);
}
}
poseStack.popPose();
}
// 统一渲染挂载实体
private void renderAttachments(DroneEntity entity, Player player, float entityYaw, float partialTicks, PoseStack poseStack, MultiBufferSource buffer, int packedLight) {
var attached = entity.getEntityData().get(ATTACHED);
if (attached.isEmpty()) return;
var attachmentData = CustomData.DRONE_ATTACHMENT.get(attached);
if (attachmentData == null) return;
var entityID = attachmentData.EntityID;
EntityType.byString(entityID).ifPresent(entityType -> {
var renderEntity = entityType.create(entity.level());
if (renderEntity == null) return;
var offset = (attachmentData.scale != null && attachmentData.offset.length < 3) ? new float[]{0, 0, 0} : attachmentData.offset;
var scale = (attachmentData.scale != null && attachmentData.scale.length < 3) ? new float[]{1, 1, 1} : attachmentData.scale;
poseStack.pushPose();
poseStack.scale(scale[0], scale[1], scale[2]);
entityRenderDispatcher.render(renderEntity, offset[0], offset[1], offset[2], entityYaw, partialTicks, poseStack, buffer, packedLight);
poseStack.popPose();
});
}
@Override
public void renderRecursively(PoseStack poseStack, DroneEntity animatable, GeoBone bone, RenderType renderType, MultiBufferSource bufferSource, VertexConsumer buffer, boolean isReRender, float partialTick, int packedLight, int packedOverlay, int color) {
String name = bone.getName();

View file

@ -1,17 +1,17 @@
package com.atsuishio.superbwarfare.data;
import com.atsuishio.superbwarfare.data.drone_attachment.DroneAttachmentData;
import com.atsuishio.superbwarfare.data.gun.DefaultGunData;
import com.atsuishio.superbwarfare.data.gun.GunData;
import com.atsuishio.superbwarfare.data.gun.ProjectileInfo;
import com.atsuishio.superbwarfare.data.vehicle.DefaultVehicleData;
import com.atsuishio.superbwarfare.data.vehicle.VehicleData;
import java.util.HashMap;
public class CustomData {
public static final HashMap<String, ProjectileInfo> LAUNCHABLE_ENTITY = DataLoader.createData("launchable", ProjectileInfo.class);
public static final HashMap<String, DefaultVehicleData> VEHICLE = DataLoader.createData("vehicles", DefaultVehicleData.class, map -> VehicleData.dataCache.invalidateAll());
public static final HashMap<String, DefaultGunData> GUN = DataLoader.createData("guns", DefaultGunData.class, map -> GunData.dataCache.invalidateAll());
public static final DataLoader.DataMap<ProjectileInfo> LAUNCHABLE_ENTITY = DataLoader.createData("launchable", ProjectileInfo.class);
public static final DataLoader.DataMap<DefaultVehicleData> VEHICLE = DataLoader.createData("vehicles", DefaultVehicleData.class, map -> VehicleData.dataCache.invalidateAll());
public static final DataLoader.DataMap<DefaultGunData> GUN = DataLoader.createData("guns", DefaultGunData.class, map -> GunData.dataCache.invalidateAll());
public static final DataLoader.DataMap<DroneAttachmentData> DRONE_ATTACHMENT = DataLoader.createData("drone_attachments", DroneAttachmentData.class);
// 务必在Mod加载时调用该方法确保上面的静态数据加载成功
public static void load() {

View file

@ -29,7 +29,7 @@ public class DataLoader {
) {
}
public static <T extends IDBasedData> HashMap<String, T> createData(String name, Class<T> clazz) {
public static <T extends IDBasedData> DataMap<T> createData(String name, Class<T> clazz) {
return createData(name, clazz, null);
}

View file

@ -0,0 +1,46 @@
package com.atsuishio.superbwarfare.data.drone_attachment;
import com.atsuishio.superbwarfare.data.IDBasedData;
import com.google.gson.JsonObject;
import com.google.gson.annotations.SerializedName;
public class DroneAttachmentData implements IDBasedData {
@SerializedName("ItemID")
public String itemID = "";
@SerializedName("EntityID")
public String EntityID = "";
@Override
public String getId() {
return this.itemID;
}
@SerializedName("Count")
public int count = 1;
@SerializedName("IsKamikaze")
public boolean isKamikaze = true;
@SerializedName("ExplosionDamage")
public float explosionDamage = 0;
@SerializedName("ExplosionRadius")
public float explosionRadius = 0;
// TODO 其他挂载设置
// display settings
@SerializedName("Scale")
public float[] scale = new float[]{1, 1, 1};
@SerializedName("Offset")
public float[] offset = new float[]{0, 0, 0};
@SerializedName("Rotation")
public float[] rotation = new float[]{0, 0, 0};
@SerializedName("Data")
public JsonObject data;
}

View file

@ -1,6 +1,7 @@
package com.atsuishio.superbwarfare.entity.vehicle;
import com.atsuishio.superbwarfare.config.server.ExplosionConfig;
import com.atsuishio.superbwarfare.data.CustomData;
import com.atsuishio.superbwarfare.entity.projectile.*;
import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity;
import com.atsuishio.superbwarfare.init.ModDamageTypes;
@ -65,6 +66,7 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity {
public static final EntityDataAccessor<Boolean> LINKED = SynchedEntityData.defineId(DroneEntity.class, EntityDataSerializers.BOOLEAN);
public static final EntityDataAccessor<String> CONTROLLER = SynchedEntityData.defineId(DroneEntity.class, EntityDataSerializers.STRING);
public static final EntityDataAccessor<Integer> KAMIKAZE_MODE = SynchedEntityData.defineId(DroneEntity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<String> ATTACHED = SynchedEntityData.defineId(DroneEntity.class, EntityDataSerializers.STRING);
public static final EntityDataAccessor<Float> DELTA_X_ROT = SynchedEntityData.defineId(DroneEntity.class, EntityDataSerializers.FLOAT);
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
@ -104,7 +106,8 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity {
builder.define(DELTA_X_ROT, 0f)
.define(CONTROLLER, "undefined")
.define(LINKED, false)
.define(KAMIKAZE_MODE, 0);
.define(KAMIKAZE_MODE, 0)
.define(ATTACHED, "");
}
@Override
@ -354,6 +357,20 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity {
if (player instanceof ServerPlayer serverPlayer) {
serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.BULLET_SUPPLY.get(), SoundSource.PLAYERS, 0.5F, 1);
}
} else {
// 自定义挂载
var itemID = stack.getItem().toString();
var attachmentData = CustomData.DRONE_ATTACHMENT.get(itemID);
if (attachmentData != null && !this.entityData.get(ATTACHED).equals(itemID)) {
if (!player.isCreative()) {
stack.shrink(1);
}
this.entityData.set(ATTACHED, attachmentData.itemID);
// TODO 设置其他挂载数据
}
}
return InteractionResult.sidedSuccess(this.level().isClientSide());

View file

@ -0,0 +1,14 @@
{
"ItemID": "superbwarfare:medium_aerial_bomb",
"EntityID": "superbwarfare:mk_82",
"Offset": [
0,
-0.1,
0
],
"Scale": [
0.4,
0.4,
0.4
]
}