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 394ed7154..3f7d1a71c 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,10 +2,8 @@ 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; import com.atsuishio.superbwarfare.entity.vehicle.DroneEntity; import com.atsuishio.superbwarfare.init.ModEntities; import com.atsuishio.superbwarfare.init.ModItems; @@ -28,8 +26,7 @@ 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.DroneEntity.*; import static com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity.AMMO; public class DroneRenderer extends GeoEntityRenderer { @@ -71,11 +68,11 @@ public class DroneRenderer extends GeoEntityRenderer { entityRenderDispatcher.render(entity, 0, 0.03, 0.25, entityYaw, partialTicks, poseStack, bufferIn, packedLightIn); } - if (entityIn.getEntityData().get(KAMIKAZE_MODE) == 3) { - Entity entity = new RpgRocketEntity(ModEntities.RPG_ROCKET.get(), entityIn.level()); - - entityRenderDispatcher.render(entity, 0, -0.03, -1.8, entityYaw, partialTicks, poseStack, bufferIn, packedLightIn); - } +// if (entityIn.getEntityData().get(KAMIKAZE_MODE) == 3) { +// Entity entity = new RpgRocketEntity(ModEntities.RPG_ROCKET.get(), entityIn.level()); +// +// entityRenderDispatcher.render(entity, 0, -0.03, -1.8, entityYaw, partialTicks, poseStack, bufferIn, packedLightIn); +// } for (int i = 0; i < entityIn.getEntityData().get(AMMO); i++) { double yOffset = 0; @@ -124,24 +121,27 @@ public class DroneRenderer extends GeoEntityRenderer { // 统一渲染挂载实体 private void renderAttachments(DroneEntity entity, Player player, float entityYaw, float partialTicks, PoseStack poseStack, MultiBufferSource buffer, int packedLight) { - var attached = entity.getEntityData().get(ATTACHED); + var attached = entity.getEntityData().get(ATTACHED_ENTITY); if (attached.isEmpty()) return; - var attachmentData = CustomData.DRONE_ATTACHMENT.get(attached); - if (attachmentData == null) return; - - var entityID = attachmentData.EntityID; - EntityType.byString(entityID).ifPresent(entityType -> { + EntityType.byString(attached).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; + var displayData = entity.getEntityData().get(ATTACHMENT_DISPLAY); + + var scale = new float[]{displayData.get(0), displayData.get(1), displayData.get(2)}; + var offset = new float[]{displayData.get(3), displayData.get(4), displayData.get(5)}; + var rotation = new float[]{displayData.get(6), displayData.get(7), displayData.get(8)}; poseStack.pushPose(); + poseStack.translate(offset[0], offset[1], offset[2]); poseStack.scale(scale[0], scale[1], scale[2]); + poseStack.mulPose(Axis.XP.rotationDegrees(rotation[0])); + poseStack.mulPose(Axis.YP.rotationDegrees(rotation[2])); + poseStack.mulPose(Axis.ZP.rotationDegrees(rotation[1])); - entityRenderDispatcher.render(renderEntity, offset[0], offset[1], offset[2], entityYaw, partialTicks, poseStack, buffer, packedLight); + entityRenderDispatcher.render(renderEntity, 0, 0, 0, entityYaw, partialTicks, poseStack, buffer, packedLight); poseStack.popPose(); }); @@ -165,10 +165,10 @@ public class DroneRenderer extends GeoEntityRenderer { } } - if (name.equals("c4")) { - bone.setHidden(animatable.getEntityData().get(KAMIKAZE_MODE) != 2); - - } +// if (name.equals("c4")) { +// bone.setHidden(animatable.getEntityData().get(KAMIKAZE_MODE) != 2); +// +// } // Player player = Minecraft.getInstance().player; diff --git a/src/main/java/com/atsuishio/superbwarfare/data/DataLoader.java b/src/main/java/com/atsuishio/superbwarfare/data/DataLoader.java index 86bda2307..9cfc4687b 100644 --- a/src/main/java/com/atsuishio/superbwarfare/data/DataLoader.java +++ b/src/main/java/com/atsuishio/superbwarfare/data/DataLoader.java @@ -12,10 +12,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.InputStreamReader; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.function.Consumer; +import java.util.stream.Collectors; @EventBusSubscriber(modid = Mod.MODID) public class DataLoader { @@ -157,5 +156,21 @@ public class DataLoader { if (!loadedData.containsKey(name)) return Set.of(); return loadedData.get(name).data.keySet(); } + + @Override + @SuppressWarnings("unchecked") + public @NotNull Collection values() { + if (!loadedData.containsKey(name)) return Set.of(); + return loadedData.get(name).data.values().stream().map(v -> (T) v).toList(); + } + + @Override + @SuppressWarnings("unchecked") + public @NotNull Set> entrySet() { + if (!loadedData.containsKey(name)) return Set.of(); + return loadedData.get(name).data.entrySet().stream() + .map(e -> new AbstractMap.SimpleImmutableEntry<>(e.getKey(), (T) e.getValue())) + .collect(Collectors.toCollection(HashSet::new)); + } } } 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 index e4b7773e4..e854eeffe 100644 --- a/src/main/java/com/atsuishio/superbwarfare/data/drone_attachment/DroneAttachmentData.java +++ b/src/main/java/com/atsuishio/superbwarfare/data/drone_attachment/DroneAttachmentData.java @@ -9,7 +9,7 @@ public class DroneAttachmentData implements IDBasedData { public String itemID = ""; @SerializedName("EntityID") - public String EntityID = ""; + public String entityID = ""; @Override public String getId() { @@ -17,11 +17,18 @@ public class DroneAttachmentData implements IDBasedData { } @SerializedName("Count") - public int count = 1; + private int count = 1; + + public int count() { + return Math.min(1, this.count); + } @SerializedName("IsKamikaze") public boolean isKamikaze = true; + @SerializedName("HitDamage") + public float hitDamage = 0; + @SerializedName("ExplosionDamage") public float explosionDamage = 0; @@ -33,13 +40,25 @@ public class DroneAttachmentData implements IDBasedData { // display settings @SerializedName("Scale") - public float[] scale = new float[]{1, 1, 1}; + private float[] scale = new float[]{1, 1, 1}; @SerializedName("Offset") - public float[] offset = new float[]{0, 0, 0}; + private float[] offset = new float[]{0, 0, 0}; @SerializedName("Rotation") - public float[] rotation = new float[]{0, 0, 0}; + private float[] rotation = new float[]{0, 0, 0}; + + public float[] scale() { + return (this.scale != null && this.scale.length < 3) ? new float[]{1, 1, 1} : this.scale; + } + + public float[] offset() { + return (this.offset != null && this.offset.length < 3) ? new float[]{0, 0, 0} : this.offset; + } + + public float[] rotation() { + return (this.rotation != null && this.rotation.length < 3) ? new float[]{0, 0, 0} : this.rotation; + } @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 6806f53ca..415409e20 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/DroneEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/DroneEntity.java @@ -4,10 +4,7 @@ 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; -import com.atsuishio.superbwarfare.init.ModItems; -import com.atsuishio.superbwarfare.init.ModSounds; -import com.atsuishio.superbwarfare.init.ModTags; +import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.item.Monitor; import com.atsuishio.superbwarfare.item.common.ammo.MortarShell; import com.atsuishio.superbwarfare.tools.CustomExplosion; @@ -58,6 +55,7 @@ import software.bernie.geckolib.animation.AnimatableManager; import software.bernie.geckolib.util.GeckoLibUtil; import java.util.ArrayList; +import java.util.List; import java.util.Objects; import java.util.UUID; @@ -66,8 +64,11 @@ 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); + public static final EntityDataAccessor ATTACHED_ENTITY = SynchedEntityData.defineId(DroneEntity.class, EntityDataSerializers.STRING); + + // scale[3], offset[3], rotation[3] + public static final EntityDataAccessor> ATTACHMENT_DISPLAY = SynchedEntityData.defineId(DroneEntity.class, ModSerializers.FLOAT_LIST_SERIALIZER.get()); private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); @@ -107,7 +108,8 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity { .define(CONTROLLER, "undefined") .define(LINKED, false) .define(KAMIKAZE_MODE, 0) - .define(ATTACHED, ""); + .define(ATTACHED_ENTITY, "") + .define(ATTACHMENT_DISPLAY, List.of(1f, 1f, 1f, 0f, 0f, 0f, 0f, 0f, 0f)); } @Override @@ -289,6 +291,7 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity { // 返还物品 ItemHandlerHelper.giveItemToPlayer(player, new ItemStack(ModItems.DRONE.get())); + // TODO 返还弹药 // 返还普通弹药 for (int index0 = 0; index0 < this.entityData.get(AMMO); index0++) { ItemHandlerHelper.giveItemToPlayer(player, new ItemStack(ModItems.RGO_GRENADE.get())); @@ -311,7 +314,7 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity { this.discard(); } } else if (stack.getItem() == ModItems.RGO_GRENADE.get() && this.entityData.get(KAMIKAZE_MODE) == 0) { - // 装载普通弹药 + // TODO 清理 装载普通弹药 if (this.entityData.get(AMMO) < 6) { this.entityData.set(AMMO, this.entityData.get(AMMO) + 1); if (!player.isCreative()) { @@ -322,7 +325,7 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity { } } } else if (stack.getItem() instanceof MortarShell && this.entityData.get(AMMO) == 0 && this.entityData.get(KAMIKAZE_MODE) == 0) { - // 迫击炮神风 + // TODO 清理 迫击炮神风 var copy = stack.copy(); copy.setCount(1); this.currentItem = copy; @@ -335,40 +338,64 @@ 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 if (stack.getItem() == ModItems.C4_BOMB.get() && this.entityData.get(AMMO) == 0 && this.entityData.get(KAMIKAZE_MODE) == 0) { - // C4神风 - this.currentItem = new ItemStack(stack.getItem(), 1); - - if (!player.isCreative()) { - stack.shrink(1); - } - this.entityData.set(KAMIKAZE_MODE, 2); - if (player instanceof ServerPlayer serverPlayer) { - serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.BULLET_SUPPLY.get(), SoundSource.PLAYERS, 0.5F, 1); - } - } else if (stack.getItem() == ModItems.ROCKET.get() && this.entityData.get(AMMO) == 0 && this.entityData.get(KAMIKAZE_MODE) == 0) { - // RPG神风 - this.currentItem = new ItemStack(stack.getItem(), 1); - - if (!player.isCreative()) { - stack.shrink(1); - } - this.entityData.set(KAMIKAZE_MODE, 3); - if (player instanceof ServerPlayer serverPlayer) { - serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.BULLET_SUPPLY.get(), SoundSource.PLAYERS, 0.5F, 1); - } +// } else if (stack.getItem() == ModItems.C4_BOMB.get() && this.entityData.get(AMMO) == 0 && this.entityData.get(KAMIKAZE_MODE) == 0) { +// // C4神风 +// this.currentItem = new ItemStack(stack.getItem(), 1); +// +// if (!player.isCreative()) { +// stack.shrink(1); +// } +// this.entityData.set(KAMIKAZE_MODE, 2); +// if (player instanceof ServerPlayer serverPlayer) { +// serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.BULLET_SUPPLY.get(), SoundSource.PLAYERS, 0.5F, 1); +// } +// } else if (stack.getItem() == ModItems.ROCKET.get() && this.entityData.get(AMMO) == 0 && this.entityData.get(KAMIKAZE_MODE) == 0) { +// // RPG神风 +// this.currentItem = new ItemStack(stack.getItem(), 1); +// +// if (!player.isCreative()) { +// stack.shrink(1); +// } +// this.entityData.set(KAMIKAZE_MODE, 3); +// 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); - } + // 是否能挂载该物品 + if (attachmentData != null && this.entityData.get(AMMO) < attachmentData.count()) { + if (this.entityData.get(ATTACHED_ENTITY).equals(attachmentData.entityID)) { + // 同种物品挂载 + this.entityData.set(AMMO, this.entityData.get(AMMO) + 1); - this.entityData.set(ATTACHED, attachmentData.itemID); - // TODO 设置其他挂载数据 + if (!player.isCreative()) { + stack.shrink(1); + } + if (player instanceof ServerPlayer serverPlayer) { + serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.BULLET_SUPPLY.get(), SoundSource.PLAYERS, 0.5F, 1); + } + } else if (this.entityData.get(AMMO) == 0) { + // 不同种物品挂载 + this.entityData.set(ATTACHED_ENTITY, attachmentData.entityID); + // TODO 正确处理和渲染AMMO +// this.entityData.set(AMMO, this.entityData.get(AMMO) + 1); + + if (!player.isCreative()) { + stack.shrink(1); + } + if (player instanceof ServerPlayer serverPlayer) { + serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.BULLET_SUPPLY.get(), SoundSource.PLAYERS, 0.5F, 1); + } + + var scale = attachmentData.scale(); + var offset = attachmentData.offset(); + var rotation = attachmentData.rotation(); + + this.entityData.set(ATTACHMENT_DISPLAY, List.of(scale[0], scale[1], scale[2], offset[0], offset[1], offset[2], rotation[0], rotation[1], rotation[2])); + } } } @@ -474,20 +501,41 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity { public void hitEntityCrash(Player player, Entity target) { if (lastTickSpeed > 0.12) { + + var attachedEntity = this.entityData.get(ATTACHED_ENTITY); + if (!attachedEntity.isEmpty() && 20 * lastTickSpeed > this.getHealth()) { + var data = CustomData.DRONE_ATTACHMENT.values().stream().filter(d -> attachedEntity.equals(d.entityID)) + .findAny() + .orElse(null); + if (data != null) { + if (data.isKamikaze) { + EntityType.byString(attachedEntity).ifPresent(entityType -> { + var bomb = entityType.create(this.level()); + target.hurt(ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), bomb, player), data.hitDamage); + target.invulnerableTime = 0; + }); + } else { + // TODO 非神风模式? + } + } + } + + // TODO 清理这一坨 if (this.entityData.get(KAMIKAZE_MODE) != 0 && 20 * lastTickSpeed > this.getHealth()) { if (this.entityData.get(KAMIKAZE_MODE) == 1) { var mortarShell = new MortarShellEntity(player, this.level()); target.hurt(ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), mortarShell, player), ExplosionConfig.DRONE_KAMIKAZE_HIT_DAMAGE.get()); target.invulnerableTime = 0; - } else if (this.entityData.get(KAMIKAZE_MODE) == 2) { - var c4 = new C4Entity(player, this.level()); - target.hurt(ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), c4, player), ExplosionConfig.DRONE_KAMIKAZE_HIT_DAMAGE_C4.get()); - target.invulnerableTime = 0; - } else if (this.entityData.get(KAMIKAZE_MODE) == 3) { - var rpg = new RpgRocketEntity(player, this.level()); - target.hurt(ModDamageTypes.causeCannonFireDamage(this.level().registryAccess(), rpg, player), ExplosionConfig.DRONE_KAMIKAZE_HIT_DAMAGE_RPG.get()); - target.invulnerableTime = 0; } +// } else if (this.entityData.get(KAMIKAZE_MODE) == 2) { +// var c4 = new C4Entity(player, this.level()); +// target.hurt(ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), c4, player), ExplosionConfig.DRONE_KAMIKAZE_HIT_DAMAGE_C4.get()); +// target.invulnerableTime = 0; +// else if (this.entityData.get(KAMIKAZE_MODE) == 3) { +// var rpg = new RpgRocketEntity(player, this.level()); +// target.hurt(ModDamageTypes.causeCannonFireDamage(this.level().registryAccess(), rpg, player), ExplosionConfig.DRONE_KAMIKAZE_HIT_DAMAGE_RPG.get()); +// target.invulnerableTime = 0; +// } if (player != null && player.getMainHandItem().is(ModItems.MONITOR.get())) { var stack = player.getMainHandItem(); @@ -560,8 +608,8 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity { level().explode(null, this.getX(), this.getY(), this.getZ(), 0, Level.ExplosionInteraction.NONE); } - // 神风自爆 - if (this.entityData.get(KAMIKAZE_MODE) != 0) { + // TODO 清理 神风自爆 + if (this.entityData.get(KAMIKAZE_MODE) != 0 || !this.entityData.get(ATTACHED_ENTITY).isEmpty()) { kamikazeExplosion(this.entityData.get(KAMIKAZE_MODE)); } @@ -603,26 +651,50 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity { assert controller != null; Entity mortarShell = new MortarShellEntity(controller, level()); - Entity c4 = new C4Entity(controller, level()); - Entity rpg = new RpgRocketEntity(controller, level()); +// Entity c4 = new C4Entity(controller, level()); +// Entity rpg = new RpgRocketEntity(controller, level()); + // TODO 清理这一坨 CustomExplosion explosion = switch (mode) { case 1 -> new CustomExplosion(this.level(), this, ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), mortarShell, attacker), ExplosionConfig.DRONE_KAMIKAZE_EXPLOSION_DAMAGE.get(), this.getX(), this.getY(), this.getZ(), ExplosionConfig.DRONE_KAMIKAZE_EXPLOSION_RADIUS.get(), ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP, true).setDamageMultiplier(1); - case 2 -> new CustomExplosion(this.level(), this, - ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), c4, attacker), ExplosionConfig.C4_EXPLOSION_DAMAGE.get(), - this.getX(), this.getY(), this.getZ(), ExplosionConfig.C4_EXPLOSION_RADIUS.get(), ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP, true).setDamageMultiplier(1); +// case 2 -> new CustomExplosion(this.level(), this, +// ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), c4, attacker), ExplosionConfig.C4_EXPLOSION_DAMAGE.get(), +// this.getX(), this.getY(), this.getZ(), ExplosionConfig.C4_EXPLOSION_RADIUS.get(), ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP, true).setDamageMultiplier(1); - case 3 -> new CustomExplosion(this.level(), this, - ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), rpg, attacker), ExplosionConfig.RPG_EXPLOSION_DAMAGE.get(), - this.getX(), this.getY(), this.getZ(), ExplosionConfig.RPG_EXPLOSION_RADIUS.get(), ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP, true).setDamageMultiplier(1); +// case 3 -> new CustomExplosion(this.level(), this, +// ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), rpg, attacker), ExplosionConfig.RPG_EXPLOSION_DAMAGE.get(), +// this.getX(), this.getY(), this.getZ(), ExplosionConfig.RPG_EXPLOSION_RADIUS.get(), ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP, true).setDamageMultiplier(1); default -> null; }; - if (explosion == null) return; + // 自定义实体挂载 + if (explosion == null) { + var attachedEntity = this.entityData.get(ATTACHED_ENTITY); + if (attachedEntity.isEmpty()) return; + + var data = CustomData.DRONE_ATTACHMENT.values().stream().filter(d -> attachedEntity.equals(d.entityID)) + .findAny() + .orElse(null); + if (data == null) return; + + if (data.isKamikaze) { + var bomb = EntityType.byString(attachedEntity).map(entityType -> + entityType.create(this.level()) + ).orElse(null); + if (bomb == null) return; + + explosion = new CustomExplosion(this.level(), this, + ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), bomb, attacker), data.explosionDamage, + this.getX(), this.getY(), this.getZ(), data.explosionRadius, ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP, true).setDamageMultiplier(1); + } else { + // TODO 非神风自爆 + return; + } + } explosion.explode(); EventHooks.onExplosionStart(this.level(), explosion); diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModSerializers.java b/src/main/java/com/atsuishio/superbwarfare/init/ModSerializers.java index 46ed91a28..2f7f83cff 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModSerializers.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModSerializers.java @@ -16,4 +16,7 @@ public class ModSerializers { public static final DeferredHolder, EntityDataSerializer>> INT_LIST_SERIALIZER = REGISTRY.register("int_list_serializer", () -> EntityDataSerializer.forValueType(ByteBufCodecs.VAR_INT.apply(ByteBufCodecs.list())) ); + public static final DeferredHolder, EntityDataSerializer>> FLOAT_LIST_SERIALIZER = REGISTRY.register("float_list_serializer", + () -> EntityDataSerializer.forValueType(ByteBufCodecs.FLOAT.apply(ByteBufCodecs.list())) + ); } diff --git a/src/main/resources/data/superbwarfare/drone_attachments/c4.json b/src/main/resources/data/superbwarfare/drone_attachments/c4.json new file mode 100644 index 000000000..547ba084f --- /dev/null +++ b/src/main/resources/data/superbwarfare/drone_attachments/c4.json @@ -0,0 +1,12 @@ +{ + "ItemID": "superbwarfare:c4_bomb", + "EntityID": "superbwarfare:c4", + "HitDamage": 150, + "ExplosionDamage": 300, + "ExplosionRadius": 10, + "Offset": [ + 0, + -0.1, + 0 + ] +} \ No newline at end of file diff --git a/src/main/resources/data/superbwarfare/drone_attachments/rpg.json b/src/main/resources/data/superbwarfare/drone_attachments/rpg.json new file mode 100644 index 000000000..ce05682dc --- /dev/null +++ b/src/main/resources/data/superbwarfare/drone_attachments/rpg.json @@ -0,0 +1,12 @@ +{ + "ItemID": "superbwarfare:rocket", + "EntityID": "superbwarfare:rpg_rocket", + "HitDamage": 270, + "ExplosionDamage": 130, + "ExplosionRadius": 10, + "Offset": [ + 0, + -0.03, + -1.8 + ] +} \ No newline at end of file