Compare commits
No commits in common. "ba147903dde30b6a52d0e83a0ee0c9f1a3290bb0" and "035017846d7dba416b66dcecc6ae97970b2ee79b" have entirely different histories.
ba147903dd
...
035017846d
49 changed files with 514 additions and 684 deletions
|
@ -12,7 +12,6 @@ import com.atsuishio.superbwarfare.component.ModDataComponents;
|
|||
import com.atsuishio.superbwarfare.config.ClientConfig;
|
||||
import com.atsuishio.superbwarfare.config.CommonConfig;
|
||||
import com.atsuishio.superbwarfare.config.ServerConfig;
|
||||
import com.atsuishio.superbwarfare.data.CustomData;
|
||||
import com.atsuishio.superbwarfare.init.*;
|
||||
import com.atsuishio.superbwarfare.network.NetworkRegistry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
@ -87,8 +86,6 @@ public class Mod {
|
|||
}
|
||||
|
||||
NeoForge.EVENT_BUS.register(this);
|
||||
|
||||
CustomData.load();
|
||||
}
|
||||
|
||||
public static ResourceLocation loc(String path) {
|
||||
|
|
|
@ -4,6 +4,7 @@ package com.atsuishio.superbwarfare.client.renderer.entity;
|
|||
import com.atsuishio.superbwarfare.client.model.entity.DroneModel;
|
||||
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;
|
||||
|
@ -18,15 +19,13 @@ 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.*;
|
||||
import static com.atsuishio.superbwarfare.entity.vehicle.DroneEntity.KAMIKAZE_MODE;
|
||||
import static com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity.AMMO;
|
||||
|
||||
public class DroneRenderer extends GeoEntityRenderer<DroneEntity> {
|
||||
|
@ -49,7 +48,7 @@ public class DroneRenderer extends GeoEntityRenderer<DroneEntity> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void render(DroneEntity entityIn, float entityYaw, float partialTicks, PoseStack poseStack, @NotNull MultiBufferSource bufferIn, int packedLightIn) {
|
||||
public void render(DroneEntity entityIn, float entityYaw, float partialTicks, PoseStack poseStack, MultiBufferSource bufferIn, int packedLightIn) {
|
||||
poseStack.pushPose();
|
||||
poseStack.mulPose(Axis.YP.rotationDegrees(-entityIn.getYaw(partialTicks)));
|
||||
poseStack.mulPose(Axis.XP.rotationDegrees(entityIn.getBodyPitch(partialTicks)));
|
||||
|
@ -68,6 +67,12 @@ public class DroneRenderer extends GeoEntityRenderer<DroneEntity> {
|
|||
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);
|
||||
}
|
||||
|
||||
for (int i = 0; i < entityIn.getEntityData().get(AMMO); i++) {
|
||||
double yOffset = 0;
|
||||
double xOffset = 0;
|
||||
|
@ -105,54 +110,12 @@ public class DroneRenderer extends GeoEntityRenderer<DroneEntity> {
|
|||
entityRenderDispatcher.render(entity, xOffset, yOffset, 0, entityYaw, partialTicks, poseStack, bufferIn, packedLightIn);
|
||||
poseStack.popPose();
|
||||
}
|
||||
|
||||
renderAttachments(entityIn, entityYaw, partialTicks, poseStack, bufferIn, packedLightIn);
|
||||
}
|
||||
}
|
||||
|
||||
poseStack.popPose();
|
||||
}
|
||||
|
||||
private String entityNameCache = "";
|
||||
private Entity entityCache = null;
|
||||
|
||||
// 统一渲染挂载实体
|
||||
private void renderAttachments(DroneEntity entity, float entityYaw, float partialTicks, PoseStack poseStack, MultiBufferSource buffer, int packedLight) {
|
||||
var attached = entity.getEntityData().get(ATTACHED_ENTITY);
|
||||
if (attached.isEmpty()) return;
|
||||
|
||||
Entity renderEntity;
|
||||
|
||||
if (entityNameCache.equals(attached) && entityCache != null) {
|
||||
renderEntity = entityCache;
|
||||
} else {
|
||||
renderEntity = EntityType.byString(attached)
|
||||
.map(type -> type.create(entity.level()))
|
||||
.orElse(null);
|
||||
if (renderEntity == null) return;
|
||||
|
||||
entityNameCache = attached;
|
||||
entityCache = renderEntity;
|
||||
}
|
||||
|
||||
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, 0, 0, 0, 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();
|
||||
|
@ -171,6 +134,24 @@ public class DroneRenderer extends GeoEntityRenderer<DroneEntity> {
|
|||
}
|
||||
}
|
||||
|
||||
if (name.equals("c4")) {
|
||||
bone.setHidden(animatable.getEntityData().get(KAMIKAZE_MODE) != 2);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Player player = Minecraft.getInstance().player;
|
||||
// if (player != null && animatable.getEntityData().get(KAMIKAZE_MODE) == 2 && name.equals("c4")) {
|
||||
// ItemStack stack = player.getMainHandItem();
|
||||
// DroneEntity drone = EntityFindUtil.findDrone(player.level(), stack.getOrCreateTag().getString("LinkedDrone"));
|
||||
//
|
||||
// if (!(stack.is(ModItems.MONITOR.get()) && stack.getOrCreateTag().getBoolean("Using") && stack.getOrCreateTag().getBoolean("Linked") && drone != null && drone.getUUID() == animatable.getUUID())) {
|
||||
// bone.setHidden(true);
|
||||
// } else {
|
||||
// bone.setHidden(false);
|
||||
// }
|
||||
// }
|
||||
|
||||
super.renderRecursively(poseStack, animatable, bone, renderType, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay, color);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package com.atsuishio.superbwarfare.compat.clothconfig;
|
||||
|
||||
import com.atsuishio.superbwarfare.compat.clothconfig.client.ControlClothConfig;
|
||||
import com.atsuishio.superbwarfare.compat.clothconfig.client.DisplayClothConfig;
|
||||
import com.atsuishio.superbwarfare.compat.clothconfig.client.KillMessageClothConfig;
|
||||
import com.atsuishio.superbwarfare.compat.clothconfig.client.ReloadClothConfig;
|
||||
import com.atsuishio.superbwarfare.compat.clothconfig.client.VehicleControlClothConfig;
|
||||
import com.atsuishio.superbwarfare.compat.clothconfig.common.GameplayClothConfig;
|
||||
import me.shedaniel.clothconfig2.api.ConfigBuilder;
|
||||
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
|
||||
|
@ -27,7 +27,7 @@ public class ClothConfigHelper {
|
|||
ReloadClothConfig.init(root, entryBuilder);
|
||||
KillMessageClothConfig.init(root, entryBuilder);
|
||||
DisplayClothConfig.init(root, entryBuilder);
|
||||
ControlClothConfig.init(root, entryBuilder);
|
||||
VehicleControlClothConfig.init(root, entryBuilder);
|
||||
|
||||
GameplayClothConfig.init(root, entryBuilder);
|
||||
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
package com.atsuishio.superbwarfare.compat.clothconfig.client;
|
||||
|
||||
import com.atsuishio.superbwarfare.config.client.ControlConfig;
|
||||
import me.shedaniel.clothconfig2.api.ConfigBuilder;
|
||||
import me.shedaniel.clothconfig2.api.ConfigCategory;
|
||||
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
import static com.atsuishio.superbwarfare.compat.clothconfig.ClothConfigHelper.save;
|
||||
|
||||
public class ControlClothConfig {
|
||||
|
||||
public static void init(ConfigBuilder root, ConfigEntryBuilder entryBuilder) {
|
||||
ConfigCategory category = root.getOrCreateCategory(Component.translatable("config.superbwarfare.client.control"));
|
||||
|
||||
category.addEntry(entryBuilder
|
||||
.startBooleanToggle(Component.translatable("config.superbwarfare.client.control.invert_aircraft_control"), ControlConfig.INVERT_AIRCRAFT_CONTROL.get())
|
||||
.setDefaultValue(true)
|
||||
.setSaveConsumer(save(ControlConfig.INVERT_AIRCRAFT_CONTROL))
|
||||
.setTooltip(Component.translatable("config.superbwarfare.client.control.invert_aircraft_control.des")).build()
|
||||
);
|
||||
|
||||
category.addEntry(entryBuilder
|
||||
.startIntSlider(Component.translatable("config.superbwarfare.client.control.mouse_sensitivity"), ControlConfig.MOUSE_SENSITIVITY.get(),
|
||||
10, 200)
|
||||
.setDefaultValue(100)
|
||||
.setSaveConsumer(save(ControlConfig.MOUSE_SENSITIVITY))
|
||||
.setTooltip(Component.translatable("config.superbwarfare.client.control.mouse_sensitivity.des")).build()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.atsuishio.superbwarfare.compat.clothconfig.client;
|
||||
|
||||
import com.atsuishio.superbwarfare.config.client.VehicleControlConfig;
|
||||
import me.shedaniel.clothconfig2.api.ConfigBuilder;
|
||||
import me.shedaniel.clothconfig2.api.ConfigCategory;
|
||||
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
import static com.atsuishio.superbwarfare.compat.clothconfig.ClothConfigHelper.save;
|
||||
|
||||
public class VehicleControlClothConfig {
|
||||
|
||||
public static void init(ConfigBuilder root, ConfigEntryBuilder entryBuilder) {
|
||||
ConfigCategory category = root.getOrCreateCategory(Component.translatable("config.superbwarfare.client.vehicle"));
|
||||
|
||||
category.addEntry(entryBuilder
|
||||
.startBooleanToggle(Component.translatable("config.superbwarfare.client.vehicle.invert_aircraft_control"), VehicleControlConfig.INVERT_AIRCRAFT_CONTROL.get())
|
||||
.setDefaultValue(true)
|
||||
.setSaveConsumer(save(VehicleControlConfig.INVERT_AIRCRAFT_CONTROL))
|
||||
.setTooltip(Component.translatable("config.superbwarfare.client.vehicle.left_click_reload.des")).build()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ public class ClientConfig {
|
|||
ReloadConfig.init(builder);
|
||||
KillMessageConfig.init(builder);
|
||||
DisplayConfig.init(builder);
|
||||
ControlConfig.init(builder);
|
||||
VehicleControlConfig.init(builder);
|
||||
EnvironmentChecksumConfig.init(builder);
|
||||
|
||||
return builder.build();
|
||||
|
|
|
@ -2,20 +2,16 @@ package com.atsuishio.superbwarfare.config.client;
|
|||
|
||||
import net.neoforged.neoforge.common.ModConfigSpec;
|
||||
|
||||
public class ControlConfig {
|
||||
public class VehicleControlConfig {
|
||||
|
||||
public static ModConfigSpec.BooleanValue INVERT_AIRCRAFT_CONTROL;
|
||||
public static ModConfigSpec.IntValue MOUSE_SENSITIVITY;
|
||||
|
||||
public static void init(ModConfigSpec.Builder builder) {
|
||||
builder.push("control");
|
||||
builder.push("invert_aircraft_control");
|
||||
|
||||
builder.comment("Set true to invert aircraft control");
|
||||
INVERT_AIRCRAFT_CONTROL = builder.define("invert_aircraft_control", false);
|
||||
|
||||
builder.comment("Sensitivity of mouse");
|
||||
MOUSE_SENSITIVITY = builder.defineInRange("mouse_sensitivity", 100, 10, 200);
|
||||
|
||||
builder.pop();
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
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;
|
||||
|
||||
public class CustomData {
|
||||
public static final DataLoader.DataMap<ProjectileInfo> LAUNCHABLE_ENTITY = DataLoader.createData("launchable", ProjectileInfo.class);
|
||||
public static final DataLoader.DataMap<DefaultVehicleData> VEHICLE = DataLoader.createData("vehicles", DefaultVehicleData.class, map -> VehicleData.dataCache.invalidateAll());
|
||||
public static final DataLoader.DataMap<DefaultGunData> GUN = DataLoader.createData("guns", DefaultGunData.class, map -> GunData.dataCache.invalidateAll());
|
||||
public static final DataLoader.DataMap<DroneAttachmentData> DRONE_ATTACHMENT = DataLoader.createData("drone_attachments", DroneAttachmentData.class);
|
||||
|
||||
// 务必在Mod加载时调用该方法,确保上面的静态数据加载成功
|
||||
public static void load() {
|
||||
}
|
||||
}
|
|
@ -1,176 +0,0 @@
|
|||
package com.atsuishio.superbwarfare.data;
|
||||
|
||||
import com.atsuishio.superbwarfare.Mod;
|
||||
import com.google.gson.Gson;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.neoforged.bus.api.EventPriority;
|
||||
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.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@EventBusSubscriber(modid = Mod.MODID)
|
||||
public class DataLoader {
|
||||
|
||||
private static final HashMap<String, GeneralData<?>> loadedData = new HashMap<>();
|
||||
|
||||
private record GeneralData<T extends IDBasedData>(
|
||||
Class<?> type, DataMap<T> proxyMap,
|
||||
HashMap<String, Object> data,
|
||||
@Nullable Consumer<Map<String, Object>> onReload
|
||||
) {
|
||||
}
|
||||
|
||||
public static <T extends IDBasedData> DataMap<T> createData(String name, Class<T> clazz) {
|
||||
return createData(name, clazz, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends IDBasedData> DataMap<T> createData(String name, Class<T> clazz, @Nullable Consumer<Map<String, Object>> onReload) {
|
||||
if (loadedData.containsKey(name)) {
|
||||
return (DataMap<T>) loadedData.get(name).proxyMap;
|
||||
} else {
|
||||
var proxyMap = new DataMap<T>(name);
|
||||
loadedData.put(name, new GeneralData<>(clazz, proxyMap, new HashMap<>(), onReload));
|
||||
return proxyMap;
|
||||
}
|
||||
}
|
||||
|
||||
private static void reloadAllData(ResourceManager manager) {
|
||||
loadedData.forEach((name, value) -> {
|
||||
var map = value.data;
|
||||
map.clear();
|
||||
|
||||
for (var entry : manager.listResources(name, file -> file.getPath().endsWith(".json")).entrySet()) {
|
||||
var attribute = entry.getValue();
|
||||
try {
|
||||
Gson gson = new Gson();
|
||||
var data = (IDBasedData) gson.fromJson(new InputStreamReader(attribute.open()), value.type);
|
||||
|
||||
String id;
|
||||
if (!data.getId().isEmpty()) {
|
||||
id = data.getId();
|
||||
} else {
|
||||
var path = entry.getKey().getPath();
|
||||
id = Mod.MODID + ":" + path.substring(name.length() + 1, path.length() - name.length() - 1);
|
||||
Mod.LOGGER.warn("{} ID for {} is empty, try using {} as id", name, id, path);
|
||||
}
|
||||
|
||||
map.put(id, data);
|
||||
} catch (Exception e) {
|
||||
Mod.LOGGER.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (value.onReload != null) {
|
||||
value.onReload.accept(map);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void serverStarted(ServerStartedEvent event) {
|
||||
reloadAllData(event.getServer().getResourceManager());
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void onDataPackSync(OnDatapackSyncEvent event) {
|
||||
reloadAllData(event.getPlayerList().getServer().getResourceManager());
|
||||
}
|
||||
|
||||
// read-only custom data map
|
||||
|
||||
public static class DataMap<T extends IDBasedData> extends HashMap<String, T> {
|
||||
private final String name;
|
||||
|
||||
private DataMap(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
if (!loadedData.containsKey(name)) return 0;
|
||||
return loadedData.get(name).data.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
if (!loadedData.containsKey(name)) return true;
|
||||
return loadedData.get(name).data.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public T get(Object key) {
|
||||
if (!loadedData.containsKey(name)) return null;
|
||||
return (T) loadedData.get(name).data.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getOrDefault(Object key, T defaultValue) {
|
||||
var value = get(key);
|
||||
return value == null ? defaultValue : value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
if (!loadedData.containsKey(name)) return false;
|
||||
return loadedData.get(name).data.containsKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T put(String key, T value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<? extends String, ? extends T> m) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T remove(Object key) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
if (!loadedData.containsKey(name)) return false;
|
||||
return loadedData.get(name).data.containsValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Set<String> keySet() {
|
||||
if (!loadedData.containsKey(name)) return Set.of();
|
||||
return loadedData.get(name).data.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public @NotNull Collection<T> 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<Entry<String, T>> 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));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
package com.atsuishio.superbwarfare.data;
|
||||
|
||||
public interface IDBasedData {
|
||||
String getId();
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
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")
|
||||
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;
|
||||
|
||||
@SerializedName("ExplosionRadius")
|
||||
public float explosionRadius = 0;
|
||||
|
||||
// TODO 其他挂载设置
|
||||
|
||||
// display settings
|
||||
|
||||
@SerializedName("Scale")
|
||||
private float[] scale = new float[]{1, 1, 1};
|
||||
|
||||
@SerializedName("Offset")
|
||||
private float[] offset = new float[]{0, 0, 0};
|
||||
|
||||
@SerializedName("Rotation")
|
||||
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;
|
||||
}
|
|
@ -1,21 +1,15 @@
|
|||
package com.atsuishio.superbwarfare.data.gun;
|
||||
|
||||
import com.atsuishio.superbwarfare.annotation.ServerOnly;
|
||||
import com.atsuishio.superbwarfare.data.IDBasedData;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class DefaultGunData implements IDBasedData {
|
||||
public class DefaultGunData {
|
||||
@SerializedName("ID")
|
||||
public String id = "";
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@SerializedName("RecoilX")
|
||||
public double recoilX;
|
||||
@SerializedName("RecoilY")
|
||||
|
|
|
@ -1,19 +1,13 @@
|
|||
package com.atsuishio.superbwarfare.data.gun;
|
||||
|
||||
import com.atsuishio.superbwarfare.data.IDBasedData;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class ProjectileInfo implements IDBasedData {
|
||||
public class ProjectileInfo {
|
||||
|
||||
@SerializedName("Type")
|
||||
public String type = "superbwarfare:projectile";
|
||||
|
||||
@SerializedName("Data")
|
||||
public JsonObject data;
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +1,51 @@
|
|||
package com.atsuishio.superbwarfare.data.launchable;
|
||||
|
||||
import com.atsuishio.superbwarfare.data.CustomData;
|
||||
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;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
@EventBusSubscriber(modid = Mod.MODID)
|
||||
public class LaunchableEntityTool {
|
||||
public static Map<String, ProjectileInfo> launchableEntitiesData = CustomData.LAUNCHABLE_ENTITY;
|
||||
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).data;
|
||||
launchableData = launchableEntitiesData.get(projectileInfo.type);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
@ -77,4 +104,14 @@ public class LaunchableEntityTool {
|
|||
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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,21 +2,15 @@ package com.atsuishio.superbwarfare.data.vehicle;
|
|||
|
||||
import com.atsuishio.superbwarfare.annotation.ServerOnly;
|
||||
import com.atsuishio.superbwarfare.config.server.VehicleConfig;
|
||||
import com.atsuishio.superbwarfare.data.IDBasedData;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModify;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DefaultVehicleData implements IDBasedData {
|
||||
public class DefaultVehicleData {
|
||||
@SerializedName("ID")
|
||||
public String id = "";
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@SerializedName("MaxHealth")
|
||||
public float maxHealth = 50;
|
||||
|
||||
|
|
|
@ -1,21 +1,55 @@
|
|||
package com.atsuishio.superbwarfare.data.vehicle;
|
||||
|
||||
import com.atsuishio.superbwarfare.Mod;
|
||||
import com.atsuishio.superbwarfare.data.CustomData;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.VehiclesDataMessage;
|
||||
import com.google.gson.Gson;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
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.entity.player.PlayerEvent;
|
||||
import net.neoforged.neoforge.event.server.ServerStartedEvent;
|
||||
import net.neoforged.neoforge.network.PacketDistributor;
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.HashMap;
|
||||
|
||||
@EventBusSubscriber(modid = Mod.MODID)
|
||||
public class VehicleDataTool {
|
||||
public static HashMap<String, DefaultVehicleData> vehicleData = new HashMap<>();
|
||||
|
||||
public static HashMap<String, DefaultVehicleData> vehicleData = CustomData.VEHICLE;
|
||||
public static final String VEHICLE_DATA_FOLDER = "vehicles";
|
||||
|
||||
public static void initJsonData(ResourceManager manager) {
|
||||
vehicleData.clear();
|
||||
VehicleData.dataCache.invalidateAll();
|
||||
|
||||
for (var entry : manager.listResources(VEHICLE_DATA_FOLDER, file -> file.getPath().endsWith(".json")).entrySet()) {
|
||||
var attribute = entry.getValue();
|
||||
|
||||
try {
|
||||
Gson gson = new Gson();
|
||||
var data = gson.fromJson(new InputStreamReader(attribute.open()), DefaultVehicleData.class);
|
||||
|
||||
String id;
|
||||
if (!data.id.isEmpty()) {
|
||||
id = data.id;
|
||||
} else {
|
||||
var path = entry.getKey().getPath();
|
||||
id = Mod.MODID + ":" + path.substring(VEHICLE_DATA_FOLDER.length() + 1, path.length() - VEHICLE_DATA_FOLDER.length() - 1);
|
||||
Mod.LOGGER.warn("Vehicle ID for {} is empty, try using {} as id", id, path);
|
||||
data.id = id;
|
||||
}
|
||||
|
||||
if (!vehicleData.containsKey(id)) {
|
||||
vehicleData.put(id, data);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Mod.LOGGER.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onPlayerLogin(PlayerEvent.PlayerLoggedInEvent event) {
|
||||
|
@ -29,9 +63,15 @@ public class VehicleDataTool {
|
|||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void serverStarted(ServerStartedEvent event) {
|
||||
initJsonData(event.getServer().getResourceManager());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onDataPackSync(OnDatapackSyncEvent event) {
|
||||
var server = event.getPlayerList().getServer();
|
||||
initJsonData(server.getResourceManager());
|
||||
|
||||
var message = VehiclesDataMessage.create();
|
||||
for (var player : event.getRelevantPlayers().toList()) {
|
||||
|
|
|
@ -7,7 +7,6 @@ import net.minecraft.core.HolderLookup;
|
|||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.data.tags.DamageTypeTagsProvider;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.DamageTypeTags;
|
||||
import net.minecraft.world.damagesource.DamageTypes;
|
||||
import net.neoforged.neoforge.common.data.ExistingFileHelper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -40,22 +39,5 @@ public class ModDamageTypeTagProvider extends DamageTypeTagsProvider {
|
|||
.addOptional(ResourceLocation.fromNamespaceAndPath("sona", "injury"));
|
||||
this.tag(ModTags.DamageTypes.VEHICLE_NOT_ABSORB)
|
||||
.add(DamageTypes.EXPLOSION, DamageTypes.PLAYER_EXPLOSION, ModDamageTypes.CUSTOM_EXPLOSION, ModDamageTypes.MINE, ModDamageTypes.PROJECTILE_BOOM);
|
||||
|
||||
this.tag(DamageTypeTags.ALWAYS_HURTS_ENDER_DRAGONS).add(ModDamageTypes.PROJECTILE_BOOM, ModDamageTypes.CUSTOM_EXPLOSION,
|
||||
ModDamageTypes.CANNON_FIRE, ModDamageTypes.LASER, ModDamageTypes.LASER_HEADSHOT, ModDamageTypes.LASER_STATIC);
|
||||
this.tag(DamageTypeTags.BYPASSES_ARMOR).add(ModDamageTypes.GUN_FIRE_ABSOLUTE, ModDamageTypes.GUN_FIRE_HEADSHOT_ABSOLUTE,
|
||||
ModDamageTypes.SHOCK, ModDamageTypes.CANNON_FIRE, ModDamageTypes.LASER, ModDamageTypes.LASER_HEADSHOT, ModDamageTypes.LASER_STATIC,
|
||||
ModDamageTypes.VEHICLE_STRIKE, ModDamageTypes.VEHICLE_EXPLOSION, ModDamageTypes.AIR_CRASH);
|
||||
this.tag(DamageTypeTags.BYPASSES_EFFECTS).add(ModDamageTypes.GUN_FIRE_ABSOLUTE, ModDamageTypes.GUN_FIRE_HEADSHOT_ABSOLUTE,
|
||||
ModDamageTypes.SHOCK, ModDamageTypes.CANNON_FIRE, ModDamageTypes.LASER, ModDamageTypes.LASER_HEADSHOT, ModDamageTypes.LASER_STATIC,
|
||||
ModDamageTypes.VEHICLE_STRIKE, ModDamageTypes.VEHICLE_EXPLOSION, ModDamageTypes.AIR_CRASH);
|
||||
this.tag(DamageTypeTags.BYPASSES_ENCHANTMENTS).add(ModDamageTypes.GUN_FIRE_ABSOLUTE, ModDamageTypes.GUN_FIRE_HEADSHOT_ABSOLUTE,
|
||||
ModDamageTypes.SHOCK, ModDamageTypes.CANNON_FIRE, ModDamageTypes.LASER, ModDamageTypes.LASER_HEADSHOT, ModDamageTypes.LASER_STATIC,
|
||||
ModDamageTypes.VEHICLE_STRIKE, ModDamageTypes.VEHICLE_EXPLOSION, ModDamageTypes.AIR_CRASH);
|
||||
this.tag(DamageTypeTags.BYPASSES_RESISTANCE).add(ModDamageTypes.GUN_FIRE_ABSOLUTE, ModDamageTypes.GUN_FIRE_HEADSHOT_ABSOLUTE,
|
||||
ModDamageTypes.SHOCK, ModDamageTypes.CANNON_FIRE, ModDamageTypes.LASER, ModDamageTypes.LASER_HEADSHOT, ModDamageTypes.LASER_STATIC,
|
||||
ModDamageTypes.VEHICLE_STRIKE, ModDamageTypes.VEHICLE_EXPLOSION, ModDamageTypes.AIR_CRASH);
|
||||
this.tag(DamageTypeTags.IS_EXPLOSION).add(ModDamageTypes.PROJECTILE_BOOM, ModDamageTypes.CUSTOM_EXPLOSION, ModDamageTypes.LUNGE_MINE);
|
||||
this.tag(DamageTypeTags.IS_FIRE).add(ModDamageTypes.BURN);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@ import net.minecraft.core.Direction;
|
|||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.particles.BlockParticleOption;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.game.ClientboundSoundPacket;
|
||||
import net.minecraft.network.syncher.EntityDataAccessor;
|
||||
|
@ -37,8 +39,11 @@ import net.minecraft.world.effect.MobEffects;
|
|||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
import net.minecraft.world.entity.monster.Monster;
|
||||
import net.minecraft.world.entity.monster.Ravager;
|
||||
import net.minecraft.world.entity.monster.Vex;
|
||||
import net.minecraft.world.entity.monster.Witch;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.projectile.Projectile;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
@ -50,6 +55,7 @@ import net.minecraft.world.level.material.FluidState;
|
|||
import net.minecraft.world.phys.*;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import net.neoforged.neoforge.common.Tags;
|
||||
import net.neoforged.neoforge.entity.IEntityWithComplexSpawn;
|
||||
import net.neoforged.neoforge.entity.PartEntity;
|
||||
import net.neoforged.neoforge.event.EventHooks;
|
||||
import net.neoforged.neoforge.network.PacketDistributor;
|
||||
|
@ -68,7 +74,7 @@ import java.util.function.Predicate;
|
|||
import static com.atsuishio.superbwarfare.tools.ParticleTool.sendParticle;
|
||||
|
||||
@SuppressWarnings({"unused", "UnusedReturnValue", "SuspiciousNameCombination"})
|
||||
public class ProjectileEntity extends Projectile implements GeoEntity, CustomSyncMotionEntity {
|
||||
public class ProjectileEntity extends Projectile implements IEntityWithComplexSpawn, GeoEntity, CustomSyncMotionEntity {
|
||||
|
||||
public static final EntityDataAccessor<Float> COLOR_R = SynchedEntityData.defineId(ProjectileEntity.class, EntityDataSerializers.FLOAT);
|
||||
public static final EntityDataAccessor<Float> COLOR_G = SynchedEntityData.defineId(ProjectileEntity.class, EntityDataSerializers.FLOAT);
|
||||
|
@ -92,10 +98,15 @@ public class ProjectileEntity extends Projectile implements GeoEntity, CustomSyn
|
|||
protected int shooterId;
|
||||
private float damage = 1f;
|
||||
private float headShot = 1f;
|
||||
private float monsterMultiplier = 0.0f;
|
||||
private float legShot = 0.5f;
|
||||
private boolean beast = false;
|
||||
private boolean zoom = false;
|
||||
private float bypassArmorRate = 0.0f;
|
||||
private float undeadMultiple = 1.0f;
|
||||
private float illagerMultiple = 1.0f;
|
||||
private int riotLevel = 0;
|
||||
private int jhpLevel = 0;
|
||||
private int heLevel = 0;
|
||||
private int fireLevel = 0;
|
||||
private boolean dragonBreath = false;
|
||||
|
@ -104,12 +115,6 @@ public class ProjectileEntity extends Projectile implements GeoEntity, CustomSyn
|
|||
private final ArrayList<MobEffectInstance> mobEffects = new ArrayList<>();
|
||||
private String gunItemId;
|
||||
|
||||
public static final Predicate<Entity> MONSTER_PREDICATE = entity -> entity instanceof Monster;
|
||||
public static final Predicate<Entity> UNDEAD_PREDICATE = entity -> entity.getType().is(EntityTypeTags.UNDEAD);
|
||||
public static final Predicate<Entity> RAIDERS_PREDICATE = entity -> entity.getType().is(EntityTypeTags.RAIDERS) || entity instanceof Vex;
|
||||
|
||||
private final Map<Predicate<Entity>, Float> damageModifiers = new HashMap<>(Map.of(MONSTER_PREDICATE, 1.0f));
|
||||
|
||||
public ProjectileEntity(EntityType<? extends ProjectileEntity> entityType, Level level) {
|
||||
super(entityType, level);
|
||||
this.noCulling = true;
|
||||
|
@ -255,7 +260,7 @@ public class ProjectileEntity extends Projectile implements GeoEntity, CustomSyn
|
|||
}
|
||||
|
||||
if (heLevel > 0) {
|
||||
explosionBullet(this, this.damage, heLevel, this.damageModifiers.get(MONSTER_PREDICATE), hitPos);
|
||||
explosionBullet(this, this.damage, heLevel, monsterMultiplier + 1, hitPos);
|
||||
}
|
||||
|
||||
return new EntityResult(entity, hitPos, headshot, legShot);
|
||||
|
@ -345,6 +350,44 @@ public class ProjectileEntity extends Projectile implements GeoEntity, CustomSyn
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readAdditionalSaveData(CompoundTag tag) {
|
||||
this.damage = tag.getFloat("Damage");
|
||||
this.headShot = tag.getFloat("HeadShot");
|
||||
this.monsterMultiplier = tag.getFloat("MonsterMultiplier");
|
||||
this.legShot = tag.getFloat("LegShot");
|
||||
this.bypassArmorRate = tag.getFloat("BypassArmorRate");
|
||||
this.undeadMultiple = tag.getFloat("UndeadMultiple");
|
||||
this.illagerMultiple = tag.getFloat("IllagerMultiple");
|
||||
this.knockback = tag.getFloat("Knockback");
|
||||
|
||||
this.beast = tag.getBoolean("Beast");
|
||||
this.forceKnockback = tag.getBoolean("ForceKnockback");
|
||||
|
||||
if (tag.contains("GunId")) {
|
||||
this.gunItemId = tag.getString("GunId");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addAdditionalSaveData(CompoundTag tag) {
|
||||
tag.putFloat("Damage", this.damage);
|
||||
tag.putFloat("HeadShot", this.headShot);
|
||||
tag.putFloat("MonsterMultiplier", this.monsterMultiplier);
|
||||
tag.putFloat("LegShot", this.legShot);
|
||||
tag.putFloat("BypassArmorRate", this.bypassArmorRate);
|
||||
tag.putFloat("UndeadMultiple", this.undeadMultiple);
|
||||
tag.putFloat("IllagerMultiple", this.illagerMultiple);
|
||||
tag.putFloat("Knockback", this.knockback);
|
||||
|
||||
tag.putBoolean("Beast", this.beast);
|
||||
tag.putBoolean("ForceKnockback", this.forceKnockback);
|
||||
|
||||
if (this.gunItemId != null) {
|
||||
tag.putString("GunId", this.gunItemId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHit(@Nullable HitResult result) {
|
||||
if (result instanceof BlockHitResult blockHitResult) {
|
||||
|
@ -377,7 +420,7 @@ public class ProjectileEntity extends Projectile implements GeoEntity, CustomSyn
|
|||
|
||||
this.onHitBlock(hitVec, blockHitResult);
|
||||
if (heLevel > 0) {
|
||||
explosionBullet(this, this.damage, heLevel, this.damageModifiers.get(MONSTER_PREDICATE), hitVec);
|
||||
explosionBullet(this, this.damage, heLevel, monsterMultiplier + 1, hitVec);
|
||||
}
|
||||
if (fireLevel > 0 && this.level() instanceof ServerLevel serverLevel) {
|
||||
ParticleTool.sendParticle(serverLevel, ParticleTypes.LAVA, hitVec.x, hitVec.y, hitVec.z,
|
||||
|
@ -490,6 +533,8 @@ public class ProjectileEntity extends Projectile implements GeoEntity, CustomSyn
|
|||
protected void onHitEntity(Entity entity, boolean headshot, boolean legShot) {
|
||||
if (this.shooter == null) return;
|
||||
|
||||
float mMultiple = 1 + this.monsterMultiplier;
|
||||
|
||||
if (entity == null) return;
|
||||
|
||||
if (entity instanceof PartEntity<?> part) {
|
||||
|
@ -497,17 +542,38 @@ public class ProjectileEntity extends Projectile implements GeoEntity, CustomSyn
|
|||
}
|
||||
|
||||
if (entity instanceof LivingEntity living) {
|
||||
living.level().playSound(null, living.getOnPos(), ModSounds.MELEE_HIT.get(), SoundSource.PLAYERS, 1, (float) (2 * Math.random() - 1) * 0.1f + 1.0f);
|
||||
|
||||
if (beast) {
|
||||
Beast.beastKill(this.shooter, living);
|
||||
return;
|
||||
}
|
||||
living.level().playSound(null, living.getOnPos(), ModSounds.MELEE_HIT.get(), SoundSource.PLAYERS, 1, (float) ((2 * org.joml.Math.random() - 1) * 0.1f + 1.0f));
|
||||
}
|
||||
|
||||
for (var entry : this.damageModifiers.entrySet()) {
|
||||
if (entry.getKey().test(entity)) {
|
||||
this.damage *= entry.getValue();
|
||||
if (beast && entity instanceof LivingEntity living) {
|
||||
Beast.beastKill(this.shooter, living);
|
||||
return;
|
||||
}
|
||||
|
||||
if (entity instanceof Monster) {
|
||||
this.damage *= mMultiple;
|
||||
}
|
||||
|
||||
if (entity instanceof LivingEntity living && living.getType().is(EntityTypeTags.UNDEAD)) {
|
||||
this.damage *= this.undeadMultiple;
|
||||
}
|
||||
|
||||
if (entity instanceof LivingEntity living && (living.getType().is(EntityTypeTags.ILLAGER) || living instanceof Vex || living instanceof Ravager || living instanceof Witch)) {
|
||||
this.damage *= this.illagerMultiple;
|
||||
}
|
||||
|
||||
if (entity instanceof LivingEntity living && riotLevel > 0 && !entity.level().isClientSide()) {
|
||||
living.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, 20 + riotLevel * 10, (int) (riotLevel * 0.25), false, false), this.shooter);
|
||||
living.addEffect(new MobEffectInstance(MobEffects.WEAKNESS, 20 + riotLevel * 10, (int) (riotLevel * 0.25), false, false), this.shooter);
|
||||
}
|
||||
|
||||
if (entity instanceof LivingEntity living && jhpLevel > 0) {
|
||||
this.damage *= (1.0f + 0.12f * jhpLevel) * ((float) (10 / (living.getAttributeValue(Attributes.ARMOR) + 10)) + 0.25f);
|
||||
}
|
||||
|
||||
if (fireLevel > 0) {
|
||||
if (!entity.level().isClientSide() && entity instanceof LivingEntity living) {
|
||||
living.addEffect(new MobEffectInstance(ModMobEffects.BURN, 60 + fireLevel * 20, fireLevel, false, false), this.shooter);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -721,6 +787,15 @@ public class ProjectileEntity extends Projectile implements GeoEntity, CustomSyn
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void readSpawnData(@NotNull RegistryFriendlyByteBuf additionalData) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSpawnData(@NotNull RegistryFriendlyByteBuf buffer) {
|
||||
}
|
||||
|
||||
public static class EntityResult {
|
||||
private final Entity entity;
|
||||
private final Vec3 hitVec;
|
||||
|
@ -778,10 +853,6 @@ public class ProjectileEntity extends Projectile implements GeoEntity, CustomSyn
|
|||
return this.gunItemId;
|
||||
}
|
||||
|
||||
public Map<Predicate<Entity>, Float> getDamageModifiers() {
|
||||
return damageModifiers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builders
|
||||
*/
|
||||
|
@ -800,6 +871,11 @@ public class ProjectileEntity extends Projectile implements GeoEntity, CustomSyn
|
|||
return this;
|
||||
}
|
||||
|
||||
public ProjectileEntity setMonsterMultiplier(float monsterMultiplier) {
|
||||
this.monsterMultiplier = monsterMultiplier;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProjectileEntity legShot(float legShot) {
|
||||
this.legShot = legShot;
|
||||
return this;
|
||||
|
@ -810,6 +886,16 @@ public class ProjectileEntity extends Projectile implements GeoEntity, CustomSyn
|
|||
return this;
|
||||
}
|
||||
|
||||
public ProjectileEntity riotBullet(int riotLevel) {
|
||||
this.riotLevel = riotLevel;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProjectileEntity jhpBullet(int jhpLevel) {
|
||||
this.jhpLevel = jhpLevel;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProjectileEntity heBullet(int heLevel) {
|
||||
this.heLevel = heLevel;
|
||||
return this;
|
||||
|
@ -831,6 +917,16 @@ public class ProjectileEntity extends Projectile implements GeoEntity, CustomSyn
|
|||
return this;
|
||||
}
|
||||
|
||||
public ProjectileEntity undeadMultiple(float undeadMultiple) {
|
||||
this.undeadMultiple = undeadMultiple;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProjectileEntity illagerMultiple(float illagerMultiple) {
|
||||
this.illagerMultiple = illagerMultiple;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProjectileEntity effect(ArrayList<MobEffectInstance> mobEffectInstances) {
|
||||
this.mobEffects.addAll(mobEffectInstances);
|
||||
return this;
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
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.*;
|
||||
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.item.Monitor;
|
||||
import com.atsuishio.superbwarfare.item.common.ammo.MortarShell;
|
||||
import com.atsuishio.superbwarfare.tools.CustomExplosion;
|
||||
|
@ -55,7 +57,6 @@ 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;
|
||||
|
||||
|
@ -65,10 +66,6 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity {
|
|||
public static final EntityDataAccessor<String> CONTROLLER = SynchedEntityData.defineId(DroneEntity.class, EntityDataSerializers.STRING);
|
||||
public static final EntityDataAccessor<Integer> KAMIKAZE_MODE = SynchedEntityData.defineId(DroneEntity.class, EntityDataSerializers.INT);
|
||||
public static final EntityDataAccessor<Float> DELTA_X_ROT = SynchedEntityData.defineId(DroneEntity.class, EntityDataSerializers.FLOAT);
|
||||
public static final EntityDataAccessor<String> ATTACHED_ENTITY = SynchedEntityData.defineId(DroneEntity.class, EntityDataSerializers.STRING);
|
||||
|
||||
// scale[3], offset[3], rotation[3]
|
||||
public static final EntityDataAccessor<List<Float>> ATTACHMENT_DISPLAY = SynchedEntityData.defineId(DroneEntity.class, ModSerializers.FLOAT_LIST_SERIALIZER.get());
|
||||
|
||||
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
|
||||
|
||||
|
@ -107,9 +104,7 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity {
|
|||
builder.define(DELTA_X_ROT, 0f)
|
||||
.define(CONTROLLER, "undefined")
|
||||
.define(LINKED, false)
|
||||
.define(KAMIKAZE_MODE, 0)
|
||||
.define(ATTACHED_ENTITY, "")
|
||||
.define(ATTACHMENT_DISPLAY, List.of(1f, 1f, 1f, 0f, 0f, 0f, 0f, 0f, 0f));
|
||||
.define(KAMIKAZE_MODE, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -291,7 +286,6 @@ 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()));
|
||||
|
@ -314,7 +308,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()) {
|
||||
|
@ -325,7 +319,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;
|
||||
|
@ -338,66 +332,28 @@ 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 {
|
||||
// 自定义挂载
|
||||
var itemID = stack.getItem().toString();
|
||||
var attachmentData = CustomData.DRONE_ATTACHMENT.get(itemID);
|
||||
} 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 (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);
|
||||
|
||||
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]));
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
return InteractionResult.sidedSuccess(this.level().isClientSide());
|
||||
|
@ -501,41 +457,20 @@ 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();
|
||||
|
@ -608,8 +543,8 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity {
|
|||
level().explode(null, this.getX(), this.getY(), this.getZ(), 0, Level.ExplosionInteraction.NONE);
|
||||
}
|
||||
|
||||
// TODO 清理 神风自爆
|
||||
if (this.entityData.get(KAMIKAZE_MODE) != 0 || !this.entityData.get(ATTACHED_ENTITY).isEmpty()) {
|
||||
// 神风自爆
|
||||
if (this.entityData.get(KAMIKAZE_MODE) != 0) {
|
||||
kamikazeExplosion(this.entityData.get(KAMIKAZE_MODE));
|
||||
}
|
||||
|
||||
|
@ -651,50 +586,26 @@ 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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (explosion == null) return;
|
||||
|
||||
explosion.explode();
|
||||
EventHooks.onExplosionStart(this.level(), explosion);
|
||||
|
|
|
@ -122,14 +122,8 @@ public class DamageModify {
|
|||
}
|
||||
|
||||
return switch (sourceType) {
|
||||
case TAG_KEY -> {
|
||||
if (sourceTagKey == null) yield false;
|
||||
yield source.is(sourceTagKey);
|
||||
}
|
||||
case RESOURCE_KEY -> {
|
||||
if (sourceKey == null) yield false;
|
||||
yield source.is(sourceKey);
|
||||
}
|
||||
case TAG_KEY -> source.is(sourceTagKey);
|
||||
case RESOURCE_KEY -> source.is(sourceKey);
|
||||
case FUNCTION -> condition.apply(source);
|
||||
case ENTITY_ID -> {
|
||||
var directEntity = source.getDirectEntity();
|
||||
|
@ -147,7 +141,7 @@ public class DamageModify {
|
|||
case ENTITY_TAG -> {
|
||||
var directEntity = source.getDirectEntity();
|
||||
if (directEntity == null) yield false;
|
||||
if (entityTag == null) yield false;
|
||||
|
||||
yield directEntity.getType().is(entityTag);
|
||||
}
|
||||
case ALL -> true;
|
||||
|
|
|
@ -7,6 +7,7 @@ public class ProjectileWeapon extends VehicleWeapon {
|
|||
|
||||
public float headShot, damage, bypassArmorRate;
|
||||
public boolean zoom;
|
||||
public int jhpLevel, heLevel;
|
||||
|
||||
public ProjectileWeapon headShot(float headShot) {
|
||||
this.headShot = headShot;
|
||||
|
@ -33,12 +34,24 @@ public class ProjectileWeapon extends VehicleWeapon {
|
|||
return this;
|
||||
}
|
||||
|
||||
public ProjectileWeapon jhpBullet(int jhpLevel) {
|
||||
this.jhpLevel = jhpLevel;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProjectileWeapon heBullet(int heLevel) {
|
||||
this.heLevel = heLevel;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProjectileEntity create(LivingEntity shooter) {
|
||||
return new ProjectileEntity(shooter.level())
|
||||
.shooter(shooter)
|
||||
.headShot(headShot)
|
||||
.damage(damage)
|
||||
.bypassArmorRate(bypassArmorRate)
|
||||
.zoom(zoom);
|
||||
.zoom(zoom)
|
||||
.jhpBullet(jhpLevel)
|
||||
.heBullet(heLevel);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.atsuishio.superbwarfare.event;
|
||||
|
||||
import com.atsuishio.superbwarfare.client.MouseMovementHandler;
|
||||
import com.atsuishio.superbwarfare.config.client.ControlConfig;
|
||||
import com.atsuishio.superbwarfare.config.client.VehicleControlConfig;
|
||||
import com.atsuishio.superbwarfare.data.gun.GunData;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.DroneEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.AirEntity;
|
||||
|
@ -100,7 +100,7 @@ public class ClientMouseHandler {
|
|||
|
||||
int y = 1;
|
||||
|
||||
if (vehicle instanceof AirEntity && ControlConfig.INVERT_AIRCRAFT_CONTROL.get()) {
|
||||
if (vehicle instanceof AirEntity && VehicleControlConfig.INVERT_AIRCRAFT_CONTROL.get()) {
|
||||
y = -1;
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,7 @@ public class ClientMouseHandler {
|
|||
if (player == null) return 1;
|
||||
|
||||
if (player.getVehicle() instanceof VehicleEntity vehicle && vehicle instanceof AirEntity && vehicle.getFirstPassenger() == player) {
|
||||
return ControlConfig.INVERT_AIRCRAFT_CONTROL.get() ? -1 : 1;
|
||||
return VehicleControlConfig.INVERT_AIRCRAFT_CONTROL.get() ? -1 : 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ public class ClientMouseHandler {
|
|||
float customSens = data.sensitivity.get();
|
||||
|
||||
if (!player.getMainHandItem().isEmpty() && mc.options.getCameraType() == CameraType.FIRST_PERSON) {
|
||||
return original / Math.max((1 + (0.2 * (data.zoom() - (0.3 * customSens)) * ClientEventHandler.zoomTime)), 0.1) * (ControlConfig.MOUSE_SENSITIVITY.get() / 100f);
|
||||
return original / Math.max((1 + (0.2 * (data.zoom() - (0.3 * customSens)) * ClientEventHandler.zoomTime)), 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,4 @@ public class ModSerializers {
|
|||
public static final DeferredHolder<EntityDataSerializer<?>, EntityDataSerializer<List<Integer>>> INT_LIST_SERIALIZER = REGISTRY.register("int_list_serializer",
|
||||
() -> EntityDataSerializer.forValueType(ByteBufCodecs.VAR_INT.apply(ByteBufCodecs.list()))
|
||||
);
|
||||
public static final DeferredHolder<EntityDataSerializer<?>, EntityDataSerializer<List<Float>>> FLOAT_LIST_SERIALIZER = REGISTRY.register("float_list_serializer",
|
||||
() -> EntityDataSerializer.forValueType(ByteBufCodecs.FLOAT.apply(ByteBufCodecs.list()))
|
||||
);
|
||||
}
|
||||
|
|
|
@ -654,7 +654,7 @@ public abstract class GunItem extends Item implements CustomRendererItem, GeoIte
|
|||
|
||||
} else if (LaunchableEntityTool.launchableEntitiesData.containsKey(projectileType)) {
|
||||
var newInfo = new ProjectileInfo();
|
||||
newInfo.data = LaunchableEntityTool.launchableEntitiesData.get(projectileType).data;
|
||||
newInfo.data = LaunchableEntityTool.launchableEntitiesData.get(projectileType);
|
||||
newInfo.type = projectileType;
|
||||
|
||||
var tag = LaunchableEntityTool.getModifiedTag(
|
||||
|
|
|
@ -47,10 +47,9 @@ public class AmmoPerk extends Perk {
|
|||
}
|
||||
if (!this.mobEffects.get().isEmpty()) {
|
||||
int amplifier = this.getEffectAmplifier(instance);
|
||||
int duration = this.getEffectDuration(instance);
|
||||
ArrayList<MobEffectInstance> mobEffectInstances = new ArrayList<>();
|
||||
for (MobEffect effect : this.mobEffects.get()) {
|
||||
mobEffectInstances.add(new MobEffectInstance(Holder.direct(effect), duration, amplifier));
|
||||
mobEffectInstances.add(new MobEffectInstance(Holder.direct(effect), 70 + 30 * level, amplifier));
|
||||
}
|
||||
projectile.effect(mobEffectInstances);
|
||||
}
|
||||
|
@ -60,10 +59,6 @@ public class AmmoPerk extends Perk {
|
|||
return instance.level() - 1;
|
||||
}
|
||||
|
||||
public int getEffectDuration(PerkInstance instance) {
|
||||
return 70 + 30 * instance.level();
|
||||
}
|
||||
|
||||
public double getModifiedVelocity(GunData data, PerkInstance instance) {
|
||||
return data.velocity() * this.speedRate;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.atsuishio.superbwarfare.perk.ammo;
|
|||
|
||||
import com.atsuishio.superbwarfare.data.gun.GunData;
|
||||
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
|
||||
import com.atsuishio.superbwarfare.init.ModMobEffects;
|
||||
import com.atsuishio.superbwarfare.init.ModTags;
|
||||
import com.atsuishio.superbwarfare.perk.AmmoPerk;
|
||||
import com.atsuishio.superbwarfare.perk.Perk;
|
||||
|
@ -12,13 +11,7 @@ import net.minecraft.world.entity.Entity;
|
|||
public class IncendiaryBullet extends AmmoPerk {
|
||||
|
||||
public IncendiaryBullet() {
|
||||
super(new AmmoPerk.Builder("incendiary_bullet", Perk.Type.AMMO).bypassArmorRate(-0.4f).damageRate(0.7f).speedRate(0.75f).slug(false).rgb(230, 131, 65)
|
||||
.mobEffect(ModMobEffects.BURN));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEffectDuration(PerkInstance instance) {
|
||||
return 60 + 20 * instance.level();
|
||||
super(new AmmoPerk.Builder("incendiary_bullet", Perk.Type.AMMO).bypassArmorRate(-0.4f).damageRate(0.7f).speedRate(0.75f).slug(false).rgb(230, 131, 65));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
package com.atsuishio.superbwarfare.perk.ammo;
|
||||
|
||||
import com.atsuishio.superbwarfare.data.gun.GunData;
|
||||
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
|
||||
import com.atsuishio.superbwarfare.perk.AmmoPerk;
|
||||
import com.atsuishio.superbwarfare.perk.Perk;
|
||||
import com.atsuishio.superbwarfare.perk.PerkInstance;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
|
||||
public class JHPBullet extends AmmoPerk {
|
||||
|
||||
|
@ -16,10 +14,9 @@ public class JHPBullet extends AmmoPerk {
|
|||
}
|
||||
|
||||
@Override
|
||||
public float getModifiedDamage(float damage, GunData data, PerkInstance instance, @Nullable LivingEntity target, DamageSource source) {
|
||||
if (target != null) {
|
||||
return damage * (1.0f + 0.12f * instance.level()) * ((float) (10 / (target.getAttributeValue(Attributes.ARMOR) + 10)) + 0.25f);
|
||||
}
|
||||
return super.getModifiedDamage(damage, data, instance, null, source);
|
||||
public void modifyProjectile(GunData data, PerkInstance instance, Entity entity) {
|
||||
super.modifyProjectile(data, instance, entity);
|
||||
if (!(entity instanceof ProjectileEntity projectile)) return;
|
||||
projectile.jhpBullet(instance.level());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,30 +4,19 @@ import com.atsuishio.superbwarfare.data.gun.GunData;
|
|||
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
|
||||
import com.atsuishio.superbwarfare.perk.AmmoPerk;
|
||||
import com.atsuishio.superbwarfare.perk.PerkInstance;
|
||||
import net.minecraft.world.effect.MobEffects;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
|
||||
public class RiotBullet extends AmmoPerk {
|
||||
|
||||
public RiotBullet() {
|
||||
super(new Builder("riot_bullet", Type.AMMO).bypassArmorRate(-0.3f).damageRate(0.9f).speedRate(0.8f).slug(true).rgb(70, 35, 230)
|
||||
.mobEffect(MobEffects.MOVEMENT_SLOWDOWN::value).mobEffect(MobEffects.WEAKNESS::value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEffectAmplifier(PerkInstance instance) {
|
||||
return (int) (instance.level() * 0.25);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEffectDuration(PerkInstance instance) {
|
||||
return 20 + instance.level() * 10;
|
||||
super(new Builder("riot_bullet", Type.AMMO).bypassArmorRate(-0.3f).damageRate(0.9f).speedRate(0.8f).slug(true).rgb(70, 35, 230));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modifyProjectile(GunData data, PerkInstance instance, Entity entity) {
|
||||
super.modifyProjectile(data, instance, entity);
|
||||
if (!(entity instanceof ProjectileEntity projectile)) return;
|
||||
projectile.getDamageModifiers().put(ProjectileEntity.RAIDERS_PREDICATE, 1.0f + 0.5f * instance.level());
|
||||
projectile.riotBullet(instance.level());
|
||||
projectile.illagerMultiple(1.0f + 0.5f * instance.level());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.atsuishio.superbwarfare.perk.ammo;
|
||||
|
||||
import com.atsuishio.superbwarfare.data.gun.GunData;
|
||||
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
|
||||
import com.atsuishio.superbwarfare.data.gun.GunData;
|
||||
import com.atsuishio.superbwarfare.perk.AmmoPerk;
|
||||
import com.atsuishio.superbwarfare.perk.Perk;
|
||||
import com.atsuishio.superbwarfare.perk.PerkInstance;
|
||||
|
@ -17,6 +17,6 @@ public class SilverBullet extends AmmoPerk {
|
|||
public void modifyProjectile(GunData data, PerkInstance instance, Entity entity) {
|
||||
super.modifyProjectile(data, instance, entity);
|
||||
if (!(entity instanceof ProjectileEntity projectile)) return;
|
||||
projectile.getDamageModifiers().put(ProjectileEntity.UNDEAD_PREDICATE, 1.0f + 0.5f * instance.level());
|
||||
projectile.undeadMultiple(1.0f + 0.5f * instance.level());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,9 +17,9 @@ public class MonsterHunter extends Perk {
|
|||
|
||||
@Override
|
||||
public void modifyProjectile(GunData data, PerkInstance instance, Entity entity) {
|
||||
float multiplier = 1.1f + 0.1f * instance.level();
|
||||
float multiplier = 0.1f + 0.1f * instance.level();
|
||||
if (entity instanceof ProjectileEntity projectile) {
|
||||
projectile.getDamageModifiers().put(ProjectileEntity.MONSTER_PREDICATE, multiplier);
|
||||
projectile.setMonsterMultiplier(multiplier);
|
||||
} else if (entity instanceof JavelinMissileEntity projectile) {
|
||||
projectile.setMonsterMultiplier(multiplier);
|
||||
} else if (entity instanceof GunGrenadeEntity projectile) {
|
||||
|
|
|
@ -1,25 +1,64 @@
|
|||
package com.atsuishio.superbwarfare.tools;
|
||||
|
||||
import com.atsuishio.superbwarfare.Mod;
|
||||
import com.atsuishio.superbwarfare.data.CustomData;
|
||||
import com.atsuishio.superbwarfare.data.gun.DefaultGunData;
|
||||
import com.atsuishio.superbwarfare.data.gun.GunData;
|
||||
import com.atsuishio.superbwarfare.network.message.receive.GunsDataMessage;
|
||||
import com.google.gson.Gson;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
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.entity.player.PlayerEvent;
|
||||
import net.neoforged.neoforge.event.server.ServerStartedEvent;
|
||||
import net.neoforged.neoforge.network.PacketDistributor;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
@EventBusSubscriber(modid = Mod.MODID)
|
||||
public class GunsTool {
|
||||
|
||||
public static HashMap<String, DefaultGunData> gunsData = CustomData.GUN;
|
||||
public static HashMap<String, DefaultGunData> gunsData = new HashMap<>();
|
||||
|
||||
public static final String GUN_DATA_FOLDER = "guns";
|
||||
|
||||
/**
|
||||
* 初始化数据,从data中读取数据json文件
|
||||
*/
|
||||
public static void initJsonData(ResourceManager manager) {
|
||||
gunsData.clear();
|
||||
GunData.dataCache.invalidateAll();
|
||||
|
||||
for (var entry : manager.listResources(GUN_DATA_FOLDER, file -> file.getPath().endsWith(".json")).entrySet()) {
|
||||
var attribute = entry.getValue();
|
||||
|
||||
try {
|
||||
Gson gson = new Gson();
|
||||
var data = gson.fromJson(new InputStreamReader(attribute.open()), DefaultGunData.class);
|
||||
|
||||
String id;
|
||||
if (!data.id.trim().isEmpty()) {
|
||||
id = data.id;
|
||||
} else {
|
||||
var path = entry.getKey().getPath();
|
||||
id = Mod.MODID + ":" + path.substring(GUN_DATA_FOLDER.length() + 1, path.length() - GUN_DATA_FOLDER.length() - 1);
|
||||
Mod.LOGGER.warn("Gun ID for {} is empty, try using {} as id", path, id);
|
||||
data.id = id;
|
||||
}
|
||||
|
||||
if (!gunsData.containsKey(id)) {
|
||||
gunsData.put(id, data);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Mod.LOGGER.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onPlayerLogin(PlayerEvent.PlayerLoggedInEvent event) {
|
||||
|
@ -33,9 +72,15 @@ public class GunsTool {
|
|||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void serverStarted(ServerStartedEvent event) {
|
||||
initJsonData(event.getServer().getResourceManager());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onDataPackSync(OnDatapackSyncEvent event) {
|
||||
var server = event.getPlayerList().getServer();
|
||||
initJsonData(server.getResourceManager());
|
||||
|
||||
var message = GunsDataMessage.create();
|
||||
for (var player : event.getRelevantPlayers().toList()) {
|
||||
|
|
|
@ -587,6 +587,89 @@
|
|||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Weapon",
|
||||
"parent": "0",
|
||||
"pivot": [0, 2.2, 0]
|
||||
},
|
||||
{
|
||||
"name": "c4",
|
||||
"parent": "Weapon",
|
||||
"pivot": [0.03633, 0.475, -0.41605],
|
||||
"rotation": [0, -90, 180],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-1.42244, -0.29277, -2.10516],
|
||||
"size": [4.60664, 0.92133, 3.3782],
|
||||
"uv": {
|
||||
"north": {"uv": [7, 3], "uv_size": [4.5, 1]},
|
||||
"east": {"uv": [4, 9], "uv_size": [3.5, 1]},
|
||||
"south": {"uv": [7, 4], "uv_size": [4.5, 1]},
|
||||
"west": {"uv": [9, 7], "uv_size": [3.5, 1]},
|
||||
"up": {"uv": [0, 0], "uv_size": [4.5, 3.5]},
|
||||
"down": {"uv": [0, 7.5], "uv_size": [4.5, -3.5]}
|
||||
}
|
||||
},
|
||||
{
|
||||
"origin": [-1.11533, 0.62855, -1.79805],
|
||||
"size": [0.61422, 0.30711, 2.76398],
|
||||
"uv": {
|
||||
"north": {"uv": [29, 25], "uv_size": [0.5, 0.25]},
|
||||
"east": {"uv": [23, 2], "uv_size": [2.75, 0.25]},
|
||||
"south": {"uv": [26, 29], "uv_size": [0.5, 0.25]},
|
||||
"west": {"uv": [24, 0], "uv_size": [2.75, 0.25]},
|
||||
"up": {"uv": [20, 0], "uv_size": [0.5, 2.75]}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "button_group",
|
||||
"parent": "c4",
|
||||
"pivot": [0.11311, 0.62855, -1.49094],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [0.11311, 0.62855, -1.49094],
|
||||
"size": [2.14976, 0.30711, 2.14976],
|
||||
"uv": {
|
||||
"north": {"uv": [25, 22], "uv_size": [2.25, 0.25]},
|
||||
"east": {"uv": [23, 25], "uv_size": [2.25, 0.25]},
|
||||
"south": {"uv": [25, 23], "uv_size": [2.25, 0.25]},
|
||||
"west": {"uv": [25, 24], "uv_size": [2.25, 0.25]},
|
||||
"up": {"uv": [7, 0], "uv_size": [2.25, 2.25]}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "triggers",
|
||||
"parent": "c4",
|
||||
"pivot": [0.72732, -0.29277, -0.56961],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [0.11311, 0.01434, -2.41226],
|
||||
"size": [1.53555, 0.30711, 0.30711],
|
||||
"uv": {
|
||||
"north": {"uv": [27, 11], "uv_size": [1.5, 0.25]},
|
||||
"east": {"uv": [30, 4], "uv_size": [0.25, 0.25]},
|
||||
"west": {"uv": [5, 30], "uv_size": [0.25, 0.25]},
|
||||
"up": {"uv": [27, 12], "uv_size": [1.5, 0.25]},
|
||||
"down": {"uv": [27, 13.25], "uv_size": [1.5, -0.25]}
|
||||
}
|
||||
},
|
||||
{
|
||||
"origin": [-1.11533, 0.01434, -2.41226],
|
||||
"size": [0.61422, 0.30711, 0.30711],
|
||||
"uv": {
|
||||
"north": {"uv": [29, 26], "uv_size": [0.5, 0.25]},
|
||||
"east": {"uv": [30, 5], "uv_size": [0.25, 0.25]},
|
||||
"west": {"uv": [6, 30], "uv_size": [0.25, 0.25]},
|
||||
"up": {"uv": [27, 29], "uv_size": [0.5, 0.25]},
|
||||
"down": {"uv": [29, 27.25], "uv_size": [0.5, -0.25]}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -627,11 +627,9 @@
|
|||
"config.superbwarfare.client.display.weapon_hud_y_offset.des": "The vertical offset of weapon HUD",
|
||||
"config.superbwarfare.client.display.vehicle_info": "Vehicle Info",
|
||||
"config.superbwarfare.client.display.vehicle_info.des": "Whether to display vehicle info when aiming at a vehicle",
|
||||
"config.superbwarfare.client.control": "Control Config",
|
||||
"config.superbwarfare.client.control.invert_aircraft_control": "Invert Aircraft Control",
|
||||
"config.superbwarfare.client.control.invert_aircraft_control.des": "Set TRUE to invert aircraft control",
|
||||
"config.superbwarfare.client.control.mouse_sensitivity": "Mouse Sensitivity",
|
||||
"config.superbwarfare.client.control.mouse_sensitivity.des": "Adjust mouse sensitivity while holding a gun",
|
||||
"config.superbwarfare.client.vehicle": "Control Vehicle",
|
||||
"config.superbwarfare.client.vehicle.invert_aircraft_control": "Invert Aircraft Control",
|
||||
"config.superbwarfare.client.vehicle.left_click_reload.des": "Set TRUE to invert aircraft control",
|
||||
|
||||
"config.superbwarfare.common.gameplay": "Gameplay Config",
|
||||
"config.superbwarfare.common.gameplay.respawn_reload": "Respawn Reload",
|
||||
|
|
|
@ -522,9 +522,9 @@
|
|||
"config.superbwarfare.client.display.camera_rotate.des": "Visión ligeramente inestable al sostener un arma de fuego en la mano",
|
||||
"config.superbwarfare.client.display.armor_plate_hud": "HUD de placas de blindaje",
|
||||
"config.superbwarfare.client.display.armor_plate_hud.des": "Muestra la durabilidad del inserto antibalas equipado actualmente en la armadura pectoral en la esquina inferior izquierda cuando está activado.",
|
||||
"config.superbwarfare.client.control": "Vehículos de control",
|
||||
"config.superbwarfare.client.control.invert_aircraft_control": "Invertir el control del avión",
|
||||
"config.superbwarfare.client.control.invert_aircraft_control.des": "Establece TRUE para invertir el control de la aeronave",
|
||||
"config.superbwarfare.client.vehicle": "Vehículos de control",
|
||||
"config.superbwarfare.client.vehicle.invert_aircraft_control": "Invertir el control del avión",
|
||||
"config.superbwarfare.client.vehicle.left_click_reload.des": "Establece TRUE para invertir el control de la aeronave",
|
||||
|
||||
"config.superbwarfare.common.gameplay": "Configuración del juego",
|
||||
"config.superbwarfare.common.gameplay.respawn_reload": "Recarga de Reinicio",
|
||||
|
|
|
@ -514,9 +514,9 @@
|
|||
"config.superbwarfare.client.display.camera_rotate.des": "Vue légèrement secouée lorsque vous tenez une arme à feu",
|
||||
"config.superbwarfare.client.display.armor_plate_hud": "HUD de la plaque d'armure",
|
||||
"config.superbwarfare.client.display.armor_plate_hud.des": "Affiche la durabilité de la plaque pare-balles actuellement équipée sur l'armure de poitrine dans le coin inférieur gauche lorsqu'il est activé",
|
||||
"config.superbwarfare.client.control": "Contrôler le véhicule",
|
||||
"config.superbwarfare.client.control.invert_aircraft_control": "Inverser le contrôle de l'aéronef",
|
||||
"config.superbwarfare.client.control.invert_aircraft_control.des": "Définir sur VRAI pour inverser le contrôle de l'aéronef",
|
||||
"config.superbwarfare.client.vehicle": "Contrôler le véhicule",
|
||||
"config.superbwarfare.client.vehicle.invert_aircraft_control": "Inverser le contrôle de l'aéronef",
|
||||
"config.superbwarfare.client.vehicle.left_click_reload.des": "Définir sur VRAI pour inverser le contrôle de l'aéronef",
|
||||
|
||||
"config.superbwarfare.common.gameplay": "Configuration du gameplay",
|
||||
"config.superbwarfare.common.gameplay.respawn_reload": "Rechargement après réapparition",
|
||||
|
|
|
@ -542,9 +542,9 @@
|
|||
"config.superbwarfare.client.display.armor_plate_hud.des": "オンにすると、胸部アーマーに装備されている防弾インサートの耐久性を左下隅に表示します",
|
||||
"config.superbwarfare.client.display.stamina_hud": "スタミナHUD",
|
||||
"config.superbwarfare.client.display.stamina_hud.des": "タクティカルスプリントや息止めの際にスタミナHUDを表示する",
|
||||
"config.superbwarfare.client.control": "車両制御",
|
||||
"config.superbwarfare.client.control.invert_aircraft_control": "航空機制御の反転",
|
||||
"config.superbwarfare.client.control.invert_aircraft_control.des": "航空機の制御を反転するにはTRUEを設定します",
|
||||
"config.superbwarfare.client.vehicle": "車両制御",
|
||||
"config.superbwarfare.client.vehicle.invert_aircraft_control": "航空機制御の反転",
|
||||
"config.superbwarfare.client.vehicle.left_click_reload.des": "航空機の制御を反転するにはTRUEを設定します",
|
||||
|
||||
"config.superbwarfare.common.gameplay": "ゲームプレイ設定",
|
||||
"config.superbwarfare.common.gameplay.respawn_reload": "リスポーンリロード",
|
||||
|
|
|
@ -492,9 +492,9 @@
|
|||
"config.superbwarfare.client.display.camera_rotate.des": "Немного трясёт экран при использовании оружия в руках",
|
||||
"config.superbwarfare.client.display.armor_plate_hud": "HUD бронепластины",
|
||||
"config.superbwarfare.client.display.armor_plate_hud.des": "Если включено, полоска прочности бронежилета надетого в слот нагрудника появится в нижнем левом углу",
|
||||
"config.superbwarfare.client.control": "Управление транспортом",
|
||||
"config.superbwarfare.client.control.invert_aircraft_control": "Инвертировать управление воздушным транспортом",
|
||||
"config.superbwarfare.client.control.invert_aircraft_control.des": "Если включено, управление воздушным транспортом инвертировано",
|
||||
"config.superbwarfare.client.vehicle": "Управление транспортом",
|
||||
"config.superbwarfare.client.vehicle.invert_aircraft_control": "Инвертировать управление воздушным транспортом",
|
||||
"config.superbwarfare.client.vehicle.left_click_reload.des": "Если включено, управление воздушным транспортом инвертировано",
|
||||
"config.superbwarfare.common.gameplay": "Настройки геймплея",
|
||||
"config.superbwarfare.common.gameplay.respawn_reload": "Перезарядка при возрождении",
|
||||
"config.superbwarfare.common.gameplay.respawn_reload.des": "Перезаряжает все оружие в инвентаре после возрождения автоматически",
|
||||
|
|
|
@ -627,11 +627,9 @@
|
|||
"config.superbwarfare.client.display.weapon_hud_y_offset.des": "武器HUD位置的竖直方向偏移量",
|
||||
"config.superbwarfare.client.display.vehicle_info": "载具信息显示",
|
||||
"config.superbwarfare.client.display.vehicle_info.des": "是否在看向载具的时候,显示该载具的信息",
|
||||
"config.superbwarfare.client.control": "控制配置",
|
||||
"config.superbwarfare.client.control.invert_aircraft_control": "飞行器鼠标反转",
|
||||
"config.superbwarfare.client.control.invert_aircraft_control.des": "开启飞行器鼠标反转",
|
||||
"config.superbwarfare.client.control.mouse_sensitivity": "鼠标灵敏度",
|
||||
"config.superbwarfare.client.control.mouse_sensitivity.des": "调整持枪时的鼠标灵敏度",
|
||||
"config.superbwarfare.client.vehicle": "载具控制",
|
||||
"config.superbwarfare.client.vehicle.invert_aircraft_control": "飞行器鼠标反转",
|
||||
"config.superbwarfare.client.vehicle.left_click_reload.des": "开启飞行器鼠标反转",
|
||||
|
||||
"config.superbwarfare.common.gameplay": "游戏内容配置",
|
||||
"config.superbwarfare.common.gameplay.respawn_reload": "重生换弹",
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"superbwarfare:projectile_boom",
|
||||
"superbwarfare:custom_explosion",
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"superbwarfare:gunfire_absolute",
|
||||
"superbwarfare:gunfire_headshot_absolute",
|
||||
|
@ -6,9 +7,9 @@
|
|||
"superbwarfare:cannon_fire",
|
||||
"superbwarfare:laser",
|
||||
"superbwarfare:laser_headshot",
|
||||
"superbwarfare:laser_static",
|
||||
"superbwarfare:vehicle_strike",
|
||||
"superbwarfare:vehicle_explosion",
|
||||
"superbwarfare:air_crash"
|
||||
"superbwarfare:air_crash",
|
||||
"superbwarfare:laser_static"
|
||||
]
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"superbwarfare:gunfire_absolute",
|
||||
"superbwarfare:gunfire_headshot_absolute",
|
||||
|
@ -6,9 +7,9 @@
|
|||
"superbwarfare:cannon_fire",
|
||||
"superbwarfare:laser",
|
||||
"superbwarfare:laser_headshot",
|
||||
"superbwarfare:laser_static",
|
||||
"superbwarfare:vehicle_strike",
|
||||
"superbwarfare:air_crash",
|
||||
"superbwarfare:vehicle_explosion",
|
||||
"superbwarfare:air_crash"
|
||||
"superbwarfare:laser_static"
|
||||
]
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"superbwarfare:gunfire_absolute",
|
||||
"superbwarfare:gunfire_headshot_absolute",
|
||||
|
@ -6,9 +7,9 @@
|
|||
"superbwarfare:cannon_fire",
|
||||
"superbwarfare:laser",
|
||||
"superbwarfare:laser_headshot",
|
||||
"superbwarfare:laser_static",
|
||||
"superbwarfare:vehicle_strike",
|
||||
"superbwarfare:air_crash",
|
||||
"superbwarfare:vehicle_explosion",
|
||||
"superbwarfare:air_crash"
|
||||
"superbwarfare:laser_static"
|
||||
]
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"superbwarfare:gunfire_absolute",
|
||||
"superbwarfare:gunfire_headshot_absolute",
|
||||
|
@ -6,9 +7,9 @@
|
|||
"superbwarfare:cannon_fire",
|
||||
"superbwarfare:laser",
|
||||
"superbwarfare:laser_headshot",
|
||||
"superbwarfare:laser_static",
|
||||
"superbwarfare:vehicle_strike",
|
||||
"superbwarfare:air_crash",
|
||||
"superbwarfare:vehicle_explosion",
|
||||
"superbwarfare:air_crash"
|
||||
"superbwarfare:laser_static"
|
||||
]
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"superbwarfare:projectile_boom",
|
||||
"superbwarfare:custom_explosion",
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"superbwarfare:burn"
|
||||
]
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"superbwarfare:projectile_boom",
|
||||
"superbwarfare:custom_explosion",
|
||||
"superbwarfare:laser",
|
||||
"superbwarfare:laser_headshot",
|
||||
"superbwarfare:laser_static"
|
||||
]
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"ItemID": "superbwarfare:medium_aerial_bomb",
|
||||
"EntityID": "superbwarfare:mk_82",
|
||||
"Offset": [
|
||||
0,
|
||||
-0.1,
|
||||
0
|
||||
],
|
||||
"Scale": [
|
||||
0.4,
|
||||
0.4,
|
||||
0.4
|
||||
]
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"ItemID": "superbwarfare:c4_bomb",
|
||||
"EntityID": "superbwarfare:c4",
|
||||
"HitDamage": 150,
|
||||
"ExplosionDamage": 300,
|
||||
"ExplosionRadius": 10,
|
||||
"Offset": [
|
||||
0,
|
||||
-0.1,
|
||||
0
|
||||
]
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"ItemID": "superbwarfare:rocket",
|
||||
"EntityID": "superbwarfare:rpg_rocket",
|
||||
"HitDamage": 270,
|
||||
"ExplosionDamage": 130,
|
||||
"ExplosionRadius": 10,
|
||||
"Offset": [
|
||||
0,
|
||||
-0.03,
|
||||
-1.8
|
||||
]
|
||||
}
|
Loading…
Add table
Reference in a new issue