重构perk安装条件

This commit is contained in:
17146 2025-05-07 16:20:48 +08:00 committed by Light_Quanta
parent f8767596d2
commit 5f52d7981f
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
5 changed files with 91 additions and 12 deletions

View file

@ -6,6 +6,7 @@ import com.atsuishio.superbwarfare.perk.Perk;
import com.atsuishio.superbwarfare.perk.ammo.*; import com.atsuishio.superbwarfare.perk.ammo.*;
import com.atsuishio.superbwarfare.perk.damage.*; import com.atsuishio.superbwarfare.perk.damage.*;
import com.atsuishio.superbwarfare.perk.functional.*; import com.atsuishio.superbwarfare.perk.functional.*;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.world.effect.MobEffects; import net.minecraft.world.effect.MobEffects;
import net.neoforged.bus.api.IEventBus; import net.neoforged.bus.api.IEventBus;
@ -20,6 +21,8 @@ import net.neoforged.neoforge.registries.RegistryBuilder;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class ModPerks { public class ModPerks {
public static final ResourceKey<Registry<Perk>> PERK_KEY = ResourceKey.createRegistryKey(Mod.loc("perk"));
@SubscribeEvent @SubscribeEvent
public static void registry(NewRegistryEvent event) { public static void registry(NewRegistryEvent event) {
event.create(new RegistryBuilder<Perk>(ResourceKey.createRegistryKey(Mod.loc("perk")))); event.create(new RegistryBuilder<Perk>(ResourceKey.createRegistryKey(Mod.loc("perk"))));

View file

@ -2,6 +2,8 @@ package com.atsuishio.superbwarfare.item.gun.data;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import java.util.List;
public class DefaultGunData { public class DefaultGunData {
@SerializedName("RecoilX") @SerializedName("RecoilX")
@ -72,4 +74,7 @@ public class DefaultGunData {
@SerializedName("HeatPerShoot") @SerializedName("HeatPerShoot")
public double heatPerShoot = 0; public double heatPerShoot = 0;
@SerializedName("AvailablePerks")
public List<String> availablePerks;
} }

View file

@ -1,5 +1,7 @@
package com.atsuishio.superbwarfare.item.gun.data; package com.atsuishio.superbwarfare.item.gun.data;
import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.init.ModPerks;
import com.atsuishio.superbwarfare.item.gun.GunItem; import com.atsuishio.superbwarfare.item.gun.GunItem;
import com.atsuishio.superbwarfare.item.gun.data.subdata.*; import com.atsuishio.superbwarfare.item.gun.data.subdata.*;
import com.atsuishio.superbwarfare.item.gun.data.value.*; import com.atsuishio.superbwarfare.item.gun.data.value.*;
@ -21,13 +23,17 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.component.CustomData; import net.minecraft.world.item.component.CustomData;
import net.neoforged.neoforge.registries.DeferredHolder;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
public class GunData { public class GunData {
public final ItemStack stack; public final ItemStack stack;
public final GunItem item; public final GunItem item;
public final CompoundTag tag; public final CompoundTag tag;
@ -140,9 +146,7 @@ public class GunData {
return GunsTool.gunsData.getOrDefault(id, new DefaultGunData()); return GunsTool.gunsData.getOrDefault(id, new DefaultGunData());
} }
// 枪械本体属性开始 // 枪械本体属性开始
public double rawDamage() { public double rawDamage() {
return defaultGunData().damage; return defaultGunData().damage;
} }
@ -428,8 +432,72 @@ public class GunData {
reload.setState(ReloadState.NOT_RELOADING); reload.setState(ReloadState.NOT_RELOADING);
} }
// 可持久化属性开始 private static int getPriority(String s) {
if (s == null || s.isEmpty()) return 2;
if (s.startsWith("@")) return 0;
else if (s.startsWith("!")) return 2;
else return 1;
}
public List<Perk> availablePerks() {
List<Perk> availablePerks = new ArrayList<>();
var perkNames = defaultGunData().availablePerks;
perkNames.sort((s1, s2) -> {
int p1 = getPriority(s1);
int p2 = getPriority(s2);
if (p1 != p2) {
return Integer.compare(p1, p2);
} else {
return s1.compareTo(s2);
}
});
// TODO 正确实现注册项读取
var perks = new ArrayList<DeferredHolder<Perk, ? extends Perk>>();
perks.addAll(ModPerks.AMMO_PERKS.getEntries());
perks.addAll(ModPerks.DAMAGE_PERKS.getEntries());
perks.addAll(ModPerks.FUNC_PERKS.getEntries());
var perkValues = perks.stream().map(DeferredHolder::get).toList();
var perkKeys = perks.stream().map(perk -> perk.getKey().location().toString()).toList();
for (String name : perkNames) {
if (name.startsWith("@")) {
String type = name.substring(1);
switch (type) {
case "Ammo" ->
availablePerks.addAll(perkValues.stream().filter(perk -> perk.type == Perk.Type.AMMO).toList());
case "Functional" ->
availablePerks.addAll(perkValues.stream().filter(perk -> perk.type == Perk.Type.FUNCTIONAL).toList());
case "Damage" ->
availablePerks.addAll(perkValues.stream().filter(perk -> perk.type == Perk.Type.DAMAGE).toList());
}
} else if (name.startsWith("!")) {
String n = name.substring(1);
var index = perkKeys.indexOf(n);
if (index != -1) {
availablePerks.remove(perkValues.get(index));
} else {
Mod.LOGGER.warn("Perk {} not found", n);
}
} else {
var index = perkKeys.indexOf(name);
if (index != -1) {
availablePerks.add(perkValues.get(index));
} else {
Mod.LOGGER.warn("Perk {} not found", name);
}
}
}
return availablePerks;
}
public boolean canApplyPerk(Perk perk) {
return availablePerks().contains(perk);
}
// 可持久化属性开始
public final IntValue ammo; public final IntValue ammo;
public final IntValue fireMode; public final IntValue fireMode;
public final IntValue level; public final IntValue level;
@ -447,7 +515,6 @@ public class GunData {
return item.canSwitchScope(stack); return item.canSwitchScope(stack);
} }
public final Reload reload; public final Reload reload;
public boolean reloading() { public boolean reloading() {
@ -472,7 +539,6 @@ public class GunData {
public final IntValue sensitivity; public final IntValue sensitivity;
// 其他子级属性 // 其他子级属性
public final Bolt bolt; public final Bolt bolt;
public final Attachment attachment; public final Attachment attachment;
public final Perks perk; public final Perks perk;

View file

@ -224,7 +224,7 @@ public class ReforgingTableMenu extends AbstractContainerMenu {
*/ */
public void generateResult() { public void generateResult() {
ItemStack gun = this.container.getItem(INPUT_SLOT); ItemStack gun = this.container.getItem(INPUT_SLOT);
if (!(gun.getItem() instanceof GunItem gunItem)) { if (!(gun.getItem() instanceof GunItem)) {
return; return;
} }
@ -241,7 +241,7 @@ public class ReforgingTableMenu extends AbstractContainerMenu {
List.of(ammo, func, damage).forEach(item -> { List.of(ammo, func, damage).forEach(item -> {
if (!item.isEmpty() if (!item.isEmpty()
&& item.getItem() instanceof PerkItem<?> perkItem && item.getItem() instanceof PerkItem<?> perkItem
&& gunItem.canApplyPerk(perkItem.getPerk()) && GunData.from(container.getItem(INPUT_SLOT)).canApplyPerk(perkItem.getPerk())
) { ) {
data.perk.set(new PerkInstance(perkItem.getPerk(), (short) switch (perkItem.getPerk().type) { data.perk.set(new PerkInstance(perkItem.getPerk(), (short) switch (perkItem.getPerk().type) {
case AMMO -> this.ammoPerkLevel.get(); case AMMO -> this.ammoPerkLevel.get();
@ -472,10 +472,8 @@ public class ReforgingTableMenu extends AbstractContainerMenu {
}; };
return pStack.getItem() instanceof PerkItem<?> perkItem && perkItem.getPerk().type == type return pStack.getItem() instanceof PerkItem<?> perkItem && perkItem.getPerk().type == type
&& !container.getItem(INPUT_SLOT).isEmpty() && !container.getItem(INPUT_SLOT).isEmpty() && container.getItem(INPUT_SLOT).getItem() instanceof GunItem
&& container.getItem(INPUT_SLOT).getItem() instanceof GunItem gunItem && GunData.from(container.getItem(INPUT_SLOT)).canApplyPerk(perkItem.getPerk()) && container.getItem(slot).isEmpty();
&& gunItem.canApplyPerk(perkItem.getPerk())
&& container.getItem(slot).isEmpty();
} }
public int getMaxStackSize() { public int getMaxStackSize() {

View file

@ -15,5 +15,12 @@
"BypassesArmor": 0.2, "BypassesArmor": 0.2,
"SoundRadius": 14, "SoundRadius": 14,
"RPM": 600, "RPM": 600,
"AmmoType": "@RifleAmmo" "AmmoType": "@RifleAmmo",
"AvailablePerks": [
"superbwarfare:heal_clip",
"superbwarfare:kill_clip",
"@Ammo",
"!superbwarfare:micro_missile",
"!superbwarfare:longer_wire"
]
} }