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 39db86c55..36a7a66e4 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 @@ -5,7 +5,7 @@ import com.google.gson.JsonObject; import com.google.gson.annotations.SerializedName; public class DroneAttachmentData implements IDBasedData { - @SerializedName("ItemID") + @SerializedName("Item") public String itemID = ""; @SerializedName("Entity") @@ -31,6 +31,14 @@ public class DroneAttachmentData implements IDBasedData { } + @SerializedName("DropPosition") + private float[] dropPosition = new float[]{0, -0.09f, 0}; + + public float[] dropPosition() { + return (this.dropPosition != null && this.dropPosition.length < 3) ? new float[]{0, -0.09f, 0} : this.dropPosition; + } + + /** * 无人机显示的挂载实体的实体数据 */ diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/RgoGrenadeEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/RgoGrenadeEntity.java index 25c6947c7..c55b0d17c 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/RgoGrenadeEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/RgoGrenadeEntity.java @@ -56,14 +56,15 @@ public class RgoGrenadeEntity extends FastThrowableProjectile implements GeoEnti } @Override - public void addAdditionalSaveData(CompoundTag pCompound) { + public void addAdditionalSaveData(@NotNull CompoundTag pCompound) { super.addAdditionalSaveData(pCompound); pCompound.putFloat("ExplosionDamage", this.explosionDamage); pCompound.putFloat("Radius", this.explosionRadius); + pCompound.putFloat("Fuse", this.fuse); } @Override - public void readAdditionalSaveData(CompoundTag pCompound) { + public void readAdditionalSaveData(@NotNull CompoundTag pCompound) { super.readAdditionalSaveData(pCompound); if (pCompound.contains("ExplosionDamage")) { this.explosionDamage = pCompound.getFloat("ExplosionDamage"); @@ -71,6 +72,9 @@ public class RgoGrenadeEntity extends FastThrowableProjectile implements GeoEnti if (pCompound.contains("Radius")) { this.explosionRadius = pCompound.getFloat("Radius"); } + if (pCompound.contains("Fuse")) { + this.fuse = pCompound.getInt("Fuse"); + } } @Override 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 1f56fd0f7..4ab9014dc 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/DroneEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/DroneEntity.java @@ -6,7 +6,6 @@ import com.atsuishio.superbwarfare.data.drone_attachment.DroneAttachmentData; import com.atsuishio.superbwarfare.entity.projectile.C4Entity; import com.atsuishio.superbwarfare.entity.projectile.LaserEntity; import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; -import com.atsuishio.superbwarfare.entity.projectile.RgoGrenadeEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity; import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.item.Monitor; @@ -14,6 +13,8 @@ import com.atsuishio.superbwarfare.tools.*; import net.minecraft.ChatFormatting; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.nbt.StringTag; import net.minecraft.network.chat.Component; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; @@ -53,10 +54,7 @@ import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; 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; +import java.util.*; public class DroneEntity extends MobileVehicleEntity implements GeoEntity { @@ -224,7 +222,7 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity { if (this.fire) { if (this.entityData.get(AMMO) > 0) { this.entityData.set(AMMO, this.entityData.get(AMMO) - 1); - if (controller != null) { + if (controller != null && this.level() instanceof ServerLevel) { droneDrop(controller); } } @@ -247,12 +245,44 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity { } private void droneDrop(@Nullable Player player) { - if (!this.level().isClientSide()) { - RgoGrenadeEntity rgoGrenadeEntity = new RgoGrenadeEntity(player, this.level(), 160); - rgoGrenadeEntity.setPos(this.getX(), this.getEyeY() - 0.09, this.getZ()); - rgoGrenadeEntity.droneShoot(this); - this.level().addFreshEntity(rgoGrenadeEntity); + var data = CustomData.DRONE_ATTACHMENT.get(getItemId(this.currentItem)); + if (data == null) return; + var dropEntity = EntityType.byString(data.dropEntity()) + .map(type -> type.create(this.level())) + .orElse(null); + if (dropEntity == null) return; + + if (player != null && dropEntity instanceof Projectile projectile) { + projectile.setOwner(player); } + + var tag = TagDataParser.parse(data.dropData, name -> { + if (player == null) return StringTag.valueOf(name); + + var uuid = player.getUUID(); + return switch (name) { + case "@sbw:owner" -> NbtUtils.createUUID(uuid); + case "@sbw:owner_string_lower" -> + StringTag.valueOf(uuid.toString().replace("-", "").toLowerCase(Locale.ENGLISH)); + case "@sbw:owner_string_upper" -> + StringTag.valueOf(uuid.toString().replace("-", "").toUpperCase(Locale.ENGLISH)); + default -> StringTag.valueOf(name); + }; + }); + dropEntity.load(tag); + + var dropPos = data.dropPosition(); + dropEntity.setPos(this.getX() + dropPos[0], this.getY() + dropPos[1], this.getZ() + dropPos[2]); + + var vec3 = (new Vec3(0.2 * this.getDeltaMovement().x, 0.2 * this.getDeltaMovement().y, 0.2 * this.getDeltaMovement().z)); + dropEntity.setDeltaMovement(vec3); + double d0 = vec3.horizontalDistance(); + dropEntity.setYRot((float) (Mth.atan2(vec3.x, vec3.z) * (double) (180F / (float) java.lang.Math.PI))); + dropEntity.setXRot((float) (Mth.atan2(vec3.y, d0) * (double) (180F / (float) java.lang.Math.PI))); + dropEntity.yRotO = dropEntity.getYRot(); + dropEntity.xRotO = dropEntity.getXRot(); + + this.level().addFreshEntity(dropEntity); } @Override @@ -355,7 +385,6 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity { // 不同种物品挂载 this.currentItem = stack.copyWithCount(1); this.entityData.set(DISPLAY_ENTITY, attachmentData.displayEntity()); - // TODO 正确处理和渲染AMMO this.entityData.set(AMMO, this.entityData.get(AMMO) + 1); if (!player.isCreative()) { @@ -370,7 +399,6 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity { var rotation = attachmentData.rotation(); if (attachmentData.displayData != null) { - // TODO 数据替换 this.entityData.set(DISPLAY_ENTITY_TAG, TagDataParser.parse(attachmentData.displayData)); } diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/TagDataParser.java b/src/main/java/com/atsuishio/superbwarfare/tools/TagDataParser.java index 30544cc4a..03bd52032 100644 --- a/src/main/java/com/atsuishio/superbwarfare/tools/TagDataParser.java +++ b/src/main/java/com/atsuishio/superbwarfare/tools/TagDataParser.java @@ -3,6 +3,7 @@ package com.atsuishio.superbwarfare.tools; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import net.minecraft.nbt.*; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.function.Function; @@ -11,7 +12,7 @@ public class TagDataParser { /** * 将JsonObject转换为NBT Tag */ - public static CompoundTag parse(JsonObject object) { + public static CompoundTag parse(@Nullable JsonObject object) { return parse(object, null); } @@ -22,8 +23,9 @@ public class TagDataParser { * @param tagModifier 替换函数 * @return 替换后的NBT Tag */ - public static CompoundTag parse(JsonObject object, @Nullable Function tagModifier) { + public static CompoundTag parse(@Nullable JsonObject object, @Nullable Function tagModifier) { var tag = new CompoundTag(); + if (object == null) return tag; for (var d : object.entrySet()) { var parsed = parse(d.getValue(), tagModifier); @@ -41,7 +43,7 @@ public class TagDataParser { * @param tagModifier 替换函数 * @return 替换后的NBT Tag */ - public static @Nullable Tag parse(JsonElement object, @Nullable Function tagModifier) { + public static @Nullable Tag parse(@NotNull JsonElement object, @Nullable Function tagModifier) { if (object.isJsonObject()) { // 递归处理嵌套内容 var tag = new CompoundTag(); diff --git a/src/main/resources/data/superbwarfare/drone_attachments/c4.json b/src/main/resources/data/superbwarfare/drone_attachments/c4.json index 963bb689d..aebb2846c 100644 --- a/src/main/resources/data/superbwarfare/drone_attachments/c4.json +++ b/src/main/resources/data/superbwarfare/drone_attachments/c4.json @@ -1,5 +1,5 @@ { - "ItemID": "superbwarfare:c4_bomb", + "Item": "superbwarfare:c4_bomb", "Entity": "superbwarfare:c4", "HitDamage": 150, "ExplosionDamage": 300, diff --git a/src/main/resources/data/superbwarfare/drone_attachments/mortar.json b/src/main/resources/data/superbwarfare/drone_attachments/mortar.json index 73ad963bd..d6f93a486 100644 --- a/src/main/resources/data/superbwarfare/drone_attachments/mortar.json +++ b/src/main/resources/data/superbwarfare/drone_attachments/mortar.json @@ -1,5 +1,5 @@ { - "ItemID": "superbwarfare:mortar_shell", + "Item": "superbwarfare:mortar_shell", "Entity": "superbwarfare:mortar_shell", "HitDamage": 200, "ExplosionDamage": 160, diff --git a/src/main/resources/data/superbwarfare/drone_attachments/rgo.json b/src/main/resources/data/superbwarfare/drone_attachments/rgo.json index 845e8126c..3c2583b3c 100644 --- a/src/main/resources/data/superbwarfare/drone_attachments/rgo.json +++ b/src/main/resources/data/superbwarfare/drone_attachments/rgo.json @@ -1,11 +1,14 @@ { - "ItemID": "superbwarfare:rgo_grenade", + "Item": "superbwarfare:rgo_grenade", "Entity": "superbwarfare:rgo_grenade", "IsKamikaze": false, "Count": 6, "HitDamage": 270, "ExplosionDamage": 130, "ExplosionRadius": 10, + "DropData": { + "Fuse": 160 + }, "Offset": [ 0, -0.04, diff --git a/src/main/resources/data/superbwarfare/drone_attachments/rpg.json b/src/main/resources/data/superbwarfare/drone_attachments/rpg.json index a16104bb5..a8c4487e2 100644 --- a/src/main/resources/data/superbwarfare/drone_attachments/rpg.json +++ b/src/main/resources/data/superbwarfare/drone_attachments/rpg.json @@ -1,5 +1,5 @@ { - "ItemID": "superbwarfare:rocket", + "Item": "superbwarfare:rocket", "Entity": "superbwarfare:rpg_rocket", "HitDamage": 270, "ExplosionDamage": 130,