292 lines
7.2 KiB
Java
292 lines
7.2 KiB
Java
package com.atsuishio.superbwarfare.item.gun;
|
|
|
|
import com.atsuishio.superbwarfare.tools.GunsTool;
|
|
import net.minecraft.core.component.DataComponents;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.world.item.component.CustomData;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.WeakHashMap;
|
|
|
|
public class GunData {
|
|
private final ItemStack stack;
|
|
private final GunItem item;
|
|
private CompoundTag tag;
|
|
private CompoundTag data;
|
|
private final String id;
|
|
|
|
private static final WeakHashMap<ItemStack, GunData> dataCache = new WeakHashMap<>();
|
|
|
|
private void loadTags() {
|
|
var customData = stack.get(DataComponents.CUSTOM_DATA);
|
|
this.tag = customData != null ? customData.copyTag() : new CompoundTag();
|
|
|
|
if (!tag.contains("GunData")) {
|
|
data = new CompoundTag();
|
|
tag.put("GunData", data);
|
|
} else {
|
|
data = tag.getCompound("GunData");
|
|
}
|
|
}
|
|
|
|
private GunData(ItemStack stack) {
|
|
if (!(stack.getItem() instanceof GunItem gunItem)) {
|
|
throw new IllegalArgumentException("stack is not GunItem!");
|
|
}
|
|
this.item = gunItem;
|
|
this.stack = stack;
|
|
var id = stack.getDescriptionId();
|
|
this.id = id.substring(id.lastIndexOf(".") + 1);
|
|
loadTags();
|
|
}
|
|
|
|
public static GunData from(ItemStack stack) {
|
|
if (!dataCache.containsKey(stack)) {
|
|
dataCache.put(stack, new GunData(stack));
|
|
}
|
|
return dataCache.get(stack);
|
|
}
|
|
|
|
public GunItem getItem() {
|
|
return item;
|
|
}
|
|
|
|
public ItemStack getStack() {
|
|
return stack;
|
|
}
|
|
|
|
public CompoundTag getTag() {
|
|
return tag;
|
|
}
|
|
|
|
public CompoundTag getData() {
|
|
return data;
|
|
}
|
|
|
|
private double getGunData(String key) {
|
|
return getGunData(key, 0);
|
|
}
|
|
|
|
private double getGunData(String key, double defaultValue) {
|
|
return GunsTool.gunsData.getOrDefault(id, new HashMap<>()).getOrDefault(key, defaultValue);
|
|
}
|
|
|
|
public double damage() {
|
|
return getGunData("Damage") + item.getCustomDamage(stack);
|
|
}
|
|
|
|
public double explosionDamage() {
|
|
return getGunData("ExplosionDamage");
|
|
}
|
|
|
|
public double explosionRadius() {
|
|
return getGunData("ExplosionRadius");
|
|
}
|
|
|
|
public double velocity() {
|
|
return getGunData("Velocity") + item.getCustomVelocity(stack);
|
|
}
|
|
|
|
public double spread() {
|
|
return getGunData("Spread");
|
|
}
|
|
|
|
public int magazine() {
|
|
return (int) (getGunData("Magazine") + item.getCustomMagazine(stack));
|
|
}
|
|
|
|
public int projectileAmount() {
|
|
return (int) getGunData("ProjectileAmount", 1);
|
|
}
|
|
|
|
public double headshot() {
|
|
return getGunData("Headshot", 1.5) + item.getCustomHeadshot(stack);
|
|
}
|
|
|
|
public int normalReloadTime() {
|
|
return (int) getGunData("NormalReloadTime");
|
|
}
|
|
|
|
public int emptyReloadTime() {
|
|
return (int) getGunData("EmptyReloadTime");
|
|
}
|
|
|
|
public int iterativeTime() {
|
|
return (int) getGunData("IterativeTime");
|
|
}
|
|
|
|
public int prepareTime() {
|
|
return (int) getGunData("PrepareTime");
|
|
}
|
|
|
|
public int prepareLoadTime() {
|
|
return (int) getGunData("PrepareLoadTime");
|
|
}
|
|
|
|
public int prepareEmptyTime() {
|
|
return (int) getGunData("PrepareEmptyTime");
|
|
}
|
|
|
|
public int boltActionTime() {
|
|
return (int) getGunData("BoltActionTime") + item.getCustomBoltActionTime(stack);
|
|
}
|
|
|
|
public int finishTime() {
|
|
return (int) getGunData("FinishTime");
|
|
}
|
|
|
|
public int reloadTime() {
|
|
var normalReload = normalReloadTime();
|
|
var emptyReload = emptyReloadTime();
|
|
|
|
if (normalReload == 0) return emptyReload;
|
|
if (emptyReload == 0) return normalReload;
|
|
|
|
return getAmmo() < magazine() ? normalReload : emptyReload;
|
|
}
|
|
|
|
public double soundRadius() {
|
|
return getGunData("SoundRadius", 15) + item.getCustomSoundRadius(stack);
|
|
}
|
|
|
|
public double bypassArmor() {
|
|
return getGunData("BypassesArmor") + item.getCustomBypassArmor(stack);
|
|
}
|
|
|
|
public double recoilX() {
|
|
return getGunData("RecoilX");
|
|
}
|
|
|
|
public double recoilY() {
|
|
return getGunData("RecoilY");
|
|
}
|
|
|
|
public double weight() {
|
|
return getGunData("Weight") + customWeight();
|
|
}
|
|
|
|
public double customWeight() {
|
|
return item.getCustomWeight(stack);
|
|
}
|
|
|
|
public int getAmmo() {
|
|
return data.getInt("Ammo");
|
|
}
|
|
|
|
public void setAmmo(int ammo) {
|
|
data.putInt("Ammo", ammo);
|
|
}
|
|
|
|
public boolean isReloading() {
|
|
return getReloadState() != ReloadState.NOT_RELOADING;
|
|
}
|
|
|
|
public double defaultZoom() {
|
|
return getGunData("DefaultZoom", 1);
|
|
}
|
|
|
|
public double minZoom() {
|
|
return getGunData("MinZoom", 1);
|
|
}
|
|
|
|
public double maxZoom() {
|
|
return getGunData("MaxZoom", 1);
|
|
}
|
|
|
|
public double zoom() {
|
|
if (minZoom() == maxZoom()) return defaultZoom();
|
|
|
|
return Mth.clamp(defaultZoom() + item.getCustomZoom(stack), minZoom(), maxZoom());
|
|
}
|
|
|
|
public int rpm() {
|
|
return (int) (getGunData("RPM") + item.getCustomRPM(stack));
|
|
}
|
|
|
|
public int burstAmount() {
|
|
return (int) getGunData("BurstAmount");
|
|
}
|
|
|
|
public int getFireMode() {
|
|
if (data.contains("FireMode")) {
|
|
return data.getInt("FireMode");
|
|
}
|
|
return (int) getGunData("FireMode");
|
|
}
|
|
|
|
public void setFireMode(int fireMode) {
|
|
data.putInt("FireMode", fireMode);
|
|
}
|
|
|
|
public int getLevel() {
|
|
return data.getInt("Level");
|
|
}
|
|
|
|
public void setLevel(int level) {
|
|
data.putInt("Level", level);
|
|
}
|
|
|
|
public double getExp() {
|
|
return data.getDouble("Exp");
|
|
}
|
|
|
|
public void setExp(double exp) {
|
|
data.putDouble("Exp", exp);
|
|
}
|
|
|
|
public double getUpgradePoint() {
|
|
return data.getDouble("UpgradePoint");
|
|
}
|
|
|
|
public void setUpgradePoint(double upgradePoint) {
|
|
data.putDouble("UpgradePoint", upgradePoint);
|
|
}
|
|
|
|
public boolean canAdjustZoom() {
|
|
return item.canAdjustZoom(stack);
|
|
}
|
|
|
|
public boolean canSwitchScope() {
|
|
return item.canSwitchScope(stack);
|
|
}
|
|
|
|
public enum ReloadState {
|
|
NOT_RELOADING,
|
|
NORMAL_RELOADING,
|
|
EMPTY_RELOADING,
|
|
}
|
|
|
|
public ReloadState getReloadState() {
|
|
return switch (data.getInt("ReloadState")) {
|
|
case 1 -> ReloadState.NORMAL_RELOADING;
|
|
case 2 -> ReloadState.EMPTY_RELOADING;
|
|
default -> ReloadState.NOT_RELOADING;
|
|
};
|
|
}
|
|
|
|
public boolean normalReloading() {
|
|
return getReloadState() == ReloadState.NORMAL_RELOADING;
|
|
}
|
|
|
|
public boolean emptyReloading() {
|
|
return getReloadState() == ReloadState.EMPTY_RELOADING;
|
|
}
|
|
|
|
public void setReloadState(ReloadState state) {
|
|
data.putInt("ReloadState", state.ordinal());
|
|
}
|
|
|
|
public int getReloadStage() {
|
|
return data.getInt("ReloadStage");
|
|
}
|
|
|
|
public void setReloadStage(int stage) {
|
|
data.putInt("ReloadStage", stage);
|
|
}
|
|
|
|
public void save() {
|
|
stack.set(DataComponents.CUSTOM_DATA, CustomData.of(tag));
|
|
}
|
|
}
|