实现无人机自定义投弹

This commit is contained in:
Light_Quanta 2025-07-03 15:06:50 +08:00
parent 5fc159ee3f
commit bf5900d1e0
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
8 changed files with 68 additions and 23 deletions

View file

@ -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;
}
/**
* 无人机显示的挂载实体的实体数据
*/

View file

@ -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

View file

@ -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));
}

View file

@ -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<String, Tag> tagModifier) {
public static CompoundTag parse(@Nullable JsonObject object, @Nullable Function<String, Tag> 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<String, Tag> tagModifier) {
public static @Nullable Tag parse(@NotNull JsonElement object, @Nullable Function<String, Tag> tagModifier) {
if (object.isJsonObject()) {
// 递归处理嵌套内容
var tag = new CompoundTag();

View file

@ -1,5 +1,5 @@
{
"ItemID": "superbwarfare:c4_bomb",
"Item": "superbwarfare:c4_bomb",
"Entity": "superbwarfare:c4",
"HitDamage": 150,
"ExplosionDamage": 300,

View file

@ -1,5 +1,5 @@
{
"ItemID": "superbwarfare:mortar_shell",
"Item": "superbwarfare:mortar_shell",
"Entity": "superbwarfare:mortar_shell",
"HitDamage": 200,
"ExplosionDamage": 160,

View file

@ -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,

View file

@ -1,5 +1,5 @@
{
"ItemID": "superbwarfare:rocket",
"Item": "superbwarfare:rocket",
"Entity": "superbwarfare:rpg_rocket",
"HitDamage": 270,
"ExplosionDamage": 130,