From 7b0f0959a220db8ddb3d9407f3df18b522855935 Mon Sep 17 00:00:00 2001 From: Light_Quanta Date: Tue, 1 Jul 2025 04:50:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=9D=E8=AF=95=E4=BD=BF=E7=94=A8=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=8C=85=E6=8E=A7=E5=88=B6=E6=97=A0=E4=BA=BA=E6=9C=BA?= =?UTF-8?q?=E6=8C=82=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/renderer/entity/DroneRenderer.java | 33 ++++++++++++- .../superbwarfare/data/CustomData.java | 10 ++-- .../superbwarfare/data/DataLoader.java | 2 +- .../drone_attachment/DroneAttachmentData.java | 46 +++++++++++++++++++ .../entity/vehicle/DroneEntity.java | 19 +++++++- .../drone_attachments/aerial_bomb.json | 14 ++++++ 6 files changed, 116 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/atsuishio/superbwarfare/data/drone_attachment/DroneAttachmentData.java create mode 100644 src/main/resources/data/superbwarfare/drone_attachments/aerial_bomb.json diff --git a/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/DroneRenderer.java b/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/DroneRenderer.java index 7d6f5ca78..394ed7154 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/DroneRenderer.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/DroneRenderer.java @@ -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 { } @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 { 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(); diff --git a/src/main/java/com/atsuishio/superbwarfare/data/CustomData.java b/src/main/java/com/atsuishio/superbwarfare/data/CustomData.java index aba7b1f60..54ae62528 100644 --- a/src/main/java/com/atsuishio/superbwarfare/data/CustomData.java +++ b/src/main/java/com/atsuishio/superbwarfare/data/CustomData.java @@ -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 LAUNCHABLE_ENTITY = DataLoader.createData("launchable", ProjectileInfo.class); - public static final HashMap VEHICLE = DataLoader.createData("vehicles", DefaultVehicleData.class, map -> VehicleData.dataCache.invalidateAll()); - public static final HashMap GUN = DataLoader.createData("guns", DefaultGunData.class, map -> GunData.dataCache.invalidateAll()); + public static final DataLoader.DataMap LAUNCHABLE_ENTITY = DataLoader.createData("launchable", ProjectileInfo.class); + public static final DataLoader.DataMap VEHICLE = DataLoader.createData("vehicles", DefaultVehicleData.class, map -> VehicleData.dataCache.invalidateAll()); + public static final DataLoader.DataMap GUN = DataLoader.createData("guns", DefaultGunData.class, map -> GunData.dataCache.invalidateAll()); + public static final DataLoader.DataMap DRONE_ATTACHMENT = DataLoader.createData("drone_attachments", DroneAttachmentData.class); // 务必在Mod加载时调用该方法,确保上面的静态数据加载成功 public static void load() { diff --git a/src/main/java/com/atsuishio/superbwarfare/data/DataLoader.java b/src/main/java/com/atsuishio/superbwarfare/data/DataLoader.java index 6965b59c1..86bda2307 100644 --- a/src/main/java/com/atsuishio/superbwarfare/data/DataLoader.java +++ b/src/main/java/com/atsuishio/superbwarfare/data/DataLoader.java @@ -29,7 +29,7 @@ public class DataLoader { ) { } - public static HashMap createData(String name, Class clazz) { + public static DataMap createData(String name, Class clazz) { return createData(name, clazz, null); } diff --git a/src/main/java/com/atsuishio/superbwarfare/data/drone_attachment/DroneAttachmentData.java b/src/main/java/com/atsuishio/superbwarfare/data/drone_attachment/DroneAttachmentData.java new file mode 100644 index 000000000..e4b7773e4 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/data/drone_attachment/DroneAttachmentData.java @@ -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; +} diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/DroneEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/DroneEntity.java index 59015339a..6806f53ca 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/DroneEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/DroneEntity.java @@ -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 LINKED = SynchedEntityData.defineId(DroneEntity.class, EntityDataSerializers.BOOLEAN); public static final EntityDataAccessor CONTROLLER = SynchedEntityData.defineId(DroneEntity.class, EntityDataSerializers.STRING); public static final EntityDataAccessor KAMIKAZE_MODE = SynchedEntityData.defineId(DroneEntity.class, EntityDataSerializers.INT); + public static final EntityDataAccessor ATTACHED = SynchedEntityData.defineId(DroneEntity.class, EntityDataSerializers.STRING); public static final EntityDataAccessor 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()); diff --git a/src/main/resources/data/superbwarfare/drone_attachments/aerial_bomb.json b/src/main/resources/data/superbwarfare/drone_attachments/aerial_bomb.json new file mode 100644 index 000000000..842b2a386 --- /dev/null +++ b/src/main/resources/data/superbwarfare/drone_attachments/aerial_bomb.json @@ -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 + ] +} \ No newline at end of file