添加Projectile属性和相关自定义接口
This commit is contained in:
parent
b5951a237e
commit
ebd70d7dfe
13 changed files with 215 additions and 11 deletions
|
@ -30,8 +30,8 @@ public class DefaultGunData {
|
|||
@SerializedName("Magazine")
|
||||
public int magazine;
|
||||
|
||||
@SerializedName("ProjectileType")
|
||||
public String projectileType = "superbwarfare:projectile";
|
||||
@SerializedName("Projectile")
|
||||
public ProjectileInfo projectile = new ProjectileInfo();
|
||||
|
||||
@SerializedName("ProjectileAmount")
|
||||
public int projectileAmount = 1;
|
||||
|
|
|
@ -187,8 +187,12 @@ public class GunData {
|
|||
return magazine() <= 0;
|
||||
}
|
||||
|
||||
public ProjectileInfo projectileInfo() {
|
||||
return defaultGunData().projectile;
|
||||
}
|
||||
|
||||
public String projectileType() {
|
||||
return defaultGunData().projectileType;
|
||||
return projectileInfo().type;
|
||||
}
|
||||
|
||||
public int projectileAmount() {
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package com.atsuishio.superbwarfare.data.gun;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class ProjectileInfo {
|
||||
|
||||
@SerializedName("Type")
|
||||
public String type = "superbwarfare:projectile";
|
||||
|
||||
@SerializedName("Data")
|
||||
public JsonObject data;
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
package com.atsuishio.superbwarfare.data.launchable;
|
||||
|
||||
import com.atsuishio.superbwarfare.Mod;
|
||||
import com.atsuishio.superbwarfare.data.gun.ProjectileInfo;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.nbt.*;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.event.OnDatapackSyncEvent;
|
||||
import net.neoforged.neoforge.event.server.ServerStartedEvent;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.HashMap;
|
||||
|
||||
@EventBusSubscriber(modid = Mod.MODID)
|
||||
public class LaunchableEntityTool {
|
||||
public static HashMap<String, JsonObject> launchableEntitiesData = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 初始化数据,从data中读取数据json文件
|
||||
*/
|
||||
public static void initJsonData(ResourceManager manager) {
|
||||
launchableEntitiesData.clear();
|
||||
for (var entry : manager.listResources("launchable", file -> file.getPath().endsWith(".json")).entrySet()) {
|
||||
var attribute = entry.getValue();
|
||||
try {
|
||||
Gson gson = new Gson();
|
||||
var data = gson.fromJson(new InputStreamReader(attribute.open()), JsonObject.class);
|
||||
|
||||
launchableEntitiesData.put(data.get("Type").getAsString(), data.get("Data").getAsJsonObject());
|
||||
} catch (Exception e) {
|
||||
Mod.LOGGER.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static @Nullable CompoundTag getModifiedTag(ProjectileInfo projectileInfo, ShootData data) {
|
||||
JsonObject launchableData;
|
||||
if (projectileInfo.data != null) {
|
||||
launchableData = projectileInfo.data;
|
||||
} else if (launchableEntitiesData.containsKey(projectileInfo.type)) {
|
||||
launchableData = launchableEntitiesData.get(projectileInfo.type);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
var tag = new CompoundTag();
|
||||
|
||||
for (var d : launchableData.entrySet()) {
|
||||
var parsed = parseData(d.getValue(), data);
|
||||
if (parsed == null) continue;
|
||||
tag.put(d.getKey(), parsed);
|
||||
}
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
private static @Nullable Tag parseData(JsonElement object, ShootData data) {
|
||||
if (object.isJsonObject()) {
|
||||
var tag = new CompoundTag();
|
||||
for (var d : object.getAsJsonObject().entrySet()) {
|
||||
var parsed = parseData(d.getValue(), data);
|
||||
if (parsed == null) continue;
|
||||
tag.put(d.getKey(), parsed);
|
||||
}
|
||||
return tag;
|
||||
} else if (object.isJsonArray()) {
|
||||
var tag = new ListTag();
|
||||
for (var d : object.getAsJsonArray()) {
|
||||
tag.add(parseData(d, data));
|
||||
}
|
||||
return tag;
|
||||
} else if (object.isJsonPrimitive()) {
|
||||
var prime = object.getAsJsonPrimitive();
|
||||
if (prime.isString()) {
|
||||
return modifyStringTag(prime.getAsString(), data);
|
||||
} else if (prime.isNumber()) {
|
||||
return DoubleTag.valueOf(prime.getAsLong());
|
||||
} else if (prime.isBoolean()) {
|
||||
return ByteTag.valueOf(prime.getAsBoolean());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Tag modifyStringTag(String value, ShootData data) {
|
||||
return switch (value) {
|
||||
case "@sbw:damage" -> DoubleTag.valueOf(data.damage());
|
||||
case "@sbw:owner" -> NbtUtils.createUUID(data.shooter());
|
||||
case "@sbw:owner_string_lower" ->
|
||||
StringTag.valueOf(data.shooter().toString().replace("-", "").toLowerCase());
|
||||
case "@sbw:owner_string_upper" ->
|
||||
StringTag.valueOf(data.shooter().toString().replace("-", "").toUpperCase());
|
||||
case "@sbw:explosion_damage" -> DoubleTag.valueOf(data.explosionDamage());
|
||||
case "@sbw:explosion_radius" -> DoubleTag.valueOf(data.explosionRadius());
|
||||
case "@sbw:spread" -> DoubleTag.valueOf(data.spread());
|
||||
default -> StringTag.valueOf(value);
|
||||
};
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void serverStarted(ServerStartedEvent event) {
|
||||
initJsonData(event.getServer().getResourceManager());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onDataPackSync(OnDatapackSyncEvent event) {
|
||||
initJsonData(event.getPlayerList().getServer().getResourceManager());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.atsuishio.superbwarfare.data.launchable;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
// 开火时的信息
|
||||
public record ShootData(
|
||||
UUID shooter,
|
||||
double damage,
|
||||
double explosionDamage,
|
||||
double explosionRadius,
|
||||
double spread
|
||||
) {
|
||||
}
|
|
@ -4,7 +4,10 @@ import com.atsuishio.superbwarfare.Mod;
|
|||
import com.atsuishio.superbwarfare.client.PoseTool;
|
||||
import com.atsuishio.superbwarfare.client.tooltip.component.GunImageComponent;
|
||||
import com.atsuishio.superbwarfare.data.gun.GunData;
|
||||
import com.atsuishio.superbwarfare.data.gun.ProjectileInfo;
|
||||
import com.atsuishio.superbwarfare.data.gun.value.AttachmentType;
|
||||
import com.atsuishio.superbwarfare.data.launchable.LaunchableEntityTool;
|
||||
import com.atsuishio.superbwarfare.data.launchable.ShootData;
|
||||
import com.atsuishio.superbwarfare.entity.projectile.ExplosiveProjectile;
|
||||
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
|
||||
import com.atsuishio.superbwarfare.init.ModAttachments;
|
||||
|
@ -575,12 +578,14 @@ public abstract class GunItem extends Item implements CustomRendererItem {
|
|||
float bypassArmorRate = (float) data.bypassArmor();
|
||||
|
||||
var projectileType = data.projectileType();
|
||||
var projectileInfo = data.projectileInfo();
|
||||
AtomicReference<Projectile> projectileHolder = new AtomicReference<>();
|
||||
EntityType.byString(projectileType).ifPresent(entityType -> {
|
||||
var entity = entityType.create(level);
|
||||
if (!(entity instanceof Projectile)) return;
|
||||
((Projectile) entity).setOwner(player);
|
||||
|
||||
// SBW子弹弹射物专属属性
|
||||
if (entity instanceof ProjectileEntity projectile) {
|
||||
projectile.shooter(player)
|
||||
.damage(damage)
|
||||
|
@ -590,12 +595,36 @@ public abstract class GunItem extends Item implements CustomRendererItem {
|
|||
.setGunItemId(stack);
|
||||
}
|
||||
|
||||
// SBW爆炸物专属属性
|
||||
if (entity instanceof ExplosiveProjectile explosive) {
|
||||
explosive.setDamage(damage);
|
||||
explosive.setExplosionDamage((float) data.explosionDamage());
|
||||
explosive.setExplosionRadius((float) data.explosionRadius());
|
||||
}
|
||||
|
||||
// 填充其他自定义NBT数据
|
||||
if (projectileInfo.data != null) {
|
||||
var tag = LaunchableEntityTool.getModifiedTag(projectileInfo,
|
||||
new ShootData(player.getUUID(), damage, data.explosionDamage(), data.explosionRadius(), data.spread())
|
||||
);
|
||||
if (tag != null) {
|
||||
entity.load(tag);
|
||||
}
|
||||
|
||||
} else if (LaunchableEntityTool.launchableEntitiesData.containsKey(projectileType)) {
|
||||
var newInfo = new ProjectileInfo();
|
||||
newInfo.data = LaunchableEntityTool.launchableEntitiesData.get(projectileType);
|
||||
newInfo.type = projectileType;
|
||||
|
||||
var tag = LaunchableEntityTool.getModifiedTag(
|
||||
newInfo,
|
||||
new ShootData(player.getUUID(), damage, data.explosionDamage(), data.explosionRadius(), data.spread())
|
||||
);
|
||||
if (tag != null) {
|
||||
entity.load(tag);
|
||||
}
|
||||
}
|
||||
|
||||
projectileHolder.set((Projectile) entity);
|
||||
});
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package com.atsuishio.superbwarfare.perk.ammo;
|
||||
|
||||
import com.atsuishio.superbwarfare.data.gun.GunData;
|
||||
import com.atsuishio.superbwarfare.entity.projectile.GunGrenadeEntity;
|
||||
import com.atsuishio.superbwarfare.entity.projectile.RpgRocketEntity;
|
||||
import com.atsuishio.superbwarfare.entity.projectile.ExplosiveProjectile;
|
||||
import com.atsuishio.superbwarfare.perk.AmmoPerk;
|
||||
import com.atsuishio.superbwarfare.perk.Perk;
|
||||
import com.atsuishio.superbwarfare.perk.PerkInstance;
|
||||
|
@ -14,15 +13,13 @@ public class MicroMissile extends AmmoPerk {
|
|||
super(new AmmoPerk.Builder("micro_missile", Perk.Type.AMMO).speedRate(1.2f));
|
||||
}
|
||||
|
||||
// TODO 正确设计和实现伤害修改
|
||||
@Override
|
||||
public void modifyProjectile(GunData data, PerkInstance instance, Entity entity) {
|
||||
float radius = (float) (data.explosionRadius() * 0.5f);
|
||||
float damage = (float) data.explosionDamage() * (1.1f + instance.level() * 0.1f);
|
||||
entity.setNoGravity(true);
|
||||
if (entity instanceof GunGrenadeEntity projectile) {
|
||||
projectile.setExplosionRadius(radius);
|
||||
projectile.setExplosionDamage(damage);
|
||||
} else if (entity instanceof RpgRocketEntity projectile) {
|
||||
if (entity instanceof ExplosiveProjectile projectile) {
|
||||
projectile.setExplosionRadius(radius);
|
||||
projectile.setExplosionDamage(damage);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
"RecoilX": 0.004,
|
||||
"RecoilY": 0.023,
|
||||
"Damage": 40,
|
||||
"ProjectileType": "superbwarfare:gun_grenade",
|
||||
"Projectile": {
|
||||
"Type": "superbwarfare:gun_grenade"
|
||||
},
|
||||
"ExplosionDamage": 80,
|
||||
"ExplosionRadius": 5,
|
||||
"Velocity": 3.75,
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
"RecoilX": 0.008,
|
||||
"RecoilY": 0.018,
|
||||
"Damage": 270,
|
||||
"ProjectileType": "superbwarfare:rpg_rocket",
|
||||
"Projectile": {
|
||||
"Type": "superbwarfare:rpg_rocket"
|
||||
},
|
||||
"ExplosionDamage": 130,
|
||||
"ExplosionRadius": 10,
|
||||
"Velocity": 4,
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"Type": "minecraft:arrow",
|
||||
"Data": {
|
||||
"damage": "@sbw:damage",
|
||||
"pickup": 2,
|
||||
"crit": false
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"Type": "minecraft:fireball",
|
||||
"Data": {
|
||||
"ExplosionPower": "@sbw:explosion_damage"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"Type": "minecraft:spectral_arrow",
|
||||
"Data": {
|
||||
"damage": "@sbw:damage",
|
||||
"pickup": 2,
|
||||
"crit": false
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"Type": "minecraft:trident",
|
||||
"Data": {
|
||||
"pickup": 2,
|
||||
"crit": false
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue