重构部分ammo perk

This commit is contained in:
17146 2025-05-07 14:04:55 +08:00 committed by Light_Quanta
parent 995a043731
commit c6798522f1
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
13 changed files with 171 additions and 94 deletions

View file

@ -2,6 +2,7 @@ package com.atsuishio.superbwarfare.client.tooltip;
import com.atsuishio.superbwarfare.client.TooltipTool;
import com.atsuishio.superbwarfare.client.tooltip.component.GunImageComponent;
import com.atsuishio.superbwarfare.item.gun.data.GunData;
import com.atsuishio.superbwarfare.perk.AmmoPerk;
import com.atsuishio.superbwarfare.perk.Perk;
import com.atsuishio.superbwarfare.tools.FormatTool;
@ -18,6 +19,7 @@ public class ClientBocekImageTooltip extends ClientGunImageTooltip {
protected Component getDamageComponent() {
boolean slug = false;
var data = GunData.from(stack);
var perk = data.perk.get(Perk.Type.AMMO);
if (perk instanceof AmmoPerk ammoPerk && ammoPerk.slug) {
slug = true;

View file

@ -15,8 +15,7 @@ public class ClientLauncherImageTooltip extends ClientGunImageTooltip {
@Override
protected Component getDamageComponent() {
double damage = data.damage();
var perkInstance = data.perk.getInstance(ModPerks.MICRO_MISSILE.get());
int perkLevel = perkInstance == null ? 0 : perkInstance.level();
int perkLevel = data.perk.getLevel(ModPerks.MICRO_MISSILE);
if (perkLevel > 0) damage *= 1.1f + perkLevel * 0.1f;
double explosionDamage = data.explosionDamage();

View file

@ -15,8 +15,7 @@ public class ClientSecondaryCataclysmImageTooltip extends ClientEnergyImageToolt
@Override
protected Component getDamageComponent() {
double damage = data.damage();
var perkInstance = data.perk.getInstance(ModPerks.MICRO_MISSILE.get());
int perkLevel = perkInstance == null ? 0 : perkInstance.level();
int perkLevel = data.perk.getLevel(ModPerks.MICRO_MISSILE);
if (perkLevel > 0) damage *= 1.1f + perkLevel * 0.1f;
double explosionDamage = data.explosionDamage();

View file

@ -3,6 +3,9 @@ package com.atsuishio.superbwarfare.init;
import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.perk.AmmoPerk;
import com.atsuishio.superbwarfare.perk.Perk;
import com.atsuishio.superbwarfare.perk.ammo.APBullet;
import com.atsuishio.superbwarfare.perk.ammo.BeastBullet;
import com.atsuishio.superbwarfare.perk.ammo.SilverBullet;
import com.atsuishio.superbwarfare.perk.damage.*;
import com.atsuishio.superbwarfare.perk.functional.*;
import net.minecraft.resources.ResourceKey;
@ -29,26 +32,22 @@ public class ModPerks {
*/
public static final DeferredRegister<Perk> AMMO_PERKS = DeferredRegister.create(Mod.loc("perk"), Mod.MODID);
public static final DeferredHolder<Perk, Perk> AP_BULLET = AMMO_PERKS.register("ap_bullet",
() -> new AmmoPerk(new AmmoPerk.Builder("ap_bullet", Perk.Type.AMMO).bypassArmorRate(0.4f).damageRate(0.9f).speedRate(1.2f).slug(true).rgb(230, 70, 35)));
public static final DeferredHolder<Perk, Perk> AP_BULLET = AMMO_PERKS.register("ap_bullet", APBullet::new);
public static final DeferredHolder<Perk, Perk> JHP_BULLET = AMMO_PERKS.register("jhp_bullet",
() -> new AmmoPerk(new AmmoPerk.Builder("jhp_bullet", Perk.Type.AMMO).bypassArmorRate(-0.2f).damageRate(1.1f).speedRate(0.95f).slug(true).rgb(230, 131, 65)));
public static final DeferredHolder<Perk, Perk> HE_BULLET = AMMO_PERKS.register("he_bullet",
() -> new AmmoPerk(new AmmoPerk.Builder("he_bullet", Perk.Type.AMMO).bypassArmorRate(-0.3f).damageRate(0.5f).speedRate(0.85f).slug(true).rgb(240, 20, 10)));
public static final DeferredHolder<Perk, Perk> SILVER_BULLET = AMMO_PERKS.register("silver_bullet",
() -> new AmmoPerk(new AmmoPerk.Builder("silver_bullet", Perk.Type.AMMO).bypassArmorRate(0.05f).damageRate(0.8f).speedRate(1.1f).rgb(87, 166, 219)));
public static final DeferredHolder<Perk, Perk> SILVER_BULLET = AMMO_PERKS.register("silver_bullet", SilverBullet::new);
public static final DeferredHolder<Perk, Perk> POISONOUS_BULLET = AMMO_PERKS.register("poisonous_bullet",
() -> new AmmoPerk(new AmmoPerk.Builder("poisonous_bullet", Perk.Type.AMMO).bypassArmorRate(0.0f).damageRate(1.0f).speedRate(1.0f).rgb(48, 131, 6)
.mobEffect(MobEffects.POISON::value)));
public static final DeferredHolder<Perk, Perk> BEAST_BULLET = AMMO_PERKS.register("beast_bullet",
() -> new AmmoPerk(new AmmoPerk.Builder("beast_bullet", Perk.Type.AMMO).bypassArmorRate(0.0f).rgb(134, 65, 14)));
public static final DeferredHolder<Perk, Perk> BEAST_BULLET = AMMO_PERKS.register("beast_bullet", BeastBullet::new);
public static final DeferredHolder<Perk, Perk> LONGER_WIRE = AMMO_PERKS.register("longer_wire", () -> new Perk("longer_wire", Perk.Type.AMMO));
public static final DeferredHolder<Perk, Perk> INCENDIARY_BULLET = AMMO_PERKS.register("incendiary_bullet",
() -> new AmmoPerk(new AmmoPerk.Builder("incendiary_bullet", Perk.Type.AMMO).bypassArmorRate(-0.4f).damageRate(0.7f).speedRate(0.75f).slug(false).rgb(230, 131, 65)));
public static final DeferredHolder<Perk, Perk> MICRO_MISSILE = AMMO_PERKS.register("micro_missile",
() -> new AmmoPerk(new AmmoPerk.Builder("micro_missile", Perk.Type.AMMO).speedRate(1.2f)));
/**
* Functional Perks
*/
@ -79,10 +78,8 @@ public class ModPerks {
// public static void registerCompatPerks() {
// if (ModList.get().isLoaded(CompatHolder.DMV)) {
// AMMO_PERKS.register("blade_bullet", () -> new AmmoPerk(new AmmoPerk.Builder("blade_bullet", Perk.Type.AMMO)
// .bypassArmorRate(-0.2f).damageRate(0.7f).speedRate(0.8f).rgb(0xB4, 0x4B, 0x88).mobEffect(() -> CompatHolder.DMV_BLEEDING)));
// AMMO_PERKS.register("bread_bullet", () -> new AmmoPerk(new AmmoPerk.Builder("bread_bullet", Perk.Type.AMMO)
// .bypassArmorRate(1.0f).damageRate(0.5f).speedRate(0.6f).rgb(0xde, 0xab, 0x82).mobEffect(() -> MobEffects.MOVEMENT_SLOWDOWN)));
// AMMO_PERKS.register("blade_bullet", BladeBullet::new);
// AMMO_PERKS.register("bread_bullet", BreadBullet::new);
// }
// if (ModList.get().isLoaded(CompatHolder.VRC)) {
// AMMO_PERKS.register("curse_flame_bullet", () -> new AmmoPerk(new AmmoPerk.Builder("curse_flame_bullet", Perk.Type.AMMO)

View file

@ -21,8 +21,6 @@ import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlotGroup;
import net.minecraft.world.entity.LivingEntity;
@ -634,56 +632,26 @@ public abstract class GunItem extends Item implements CustomRendererItem {
float headshot = (float) data.headshot();
float damage = (float) data.damage();
float velocity = (float) (data.velocity() * perkSpeed(data));
int projectileAmount = data.projectileAmount();
float bypassArmorRate = (float) data.bypassArmor();
var perkInstance = data.perk.getInstance(Perk.Type.AMMO);
var perk = perkInstance != null ? perkInstance.perk() : null;
ProjectileEntity projectile = new ProjectileEntity(player.level())
.shooter(player)
.damage(perk instanceof AmmoPerk ammoPerk && ammoPerk.slug ? projectileAmount * damage : damage)
.damage(damage)
.headShot(headshot)
.zoom(zoom)
.bypassArmorRate(bypassArmorRate)
.setGunItemId(stack);
if (perk instanceof AmmoPerk ammoPerk) {
int level = data.perk.getLevel(perk);
bypassArmorRate += ammoPerk.bypassArmorRate + (perk == ModPerks.AP_BULLET.get() ? 0.05f * (level - 1) : 0);
projectile.setRGB(ammoPerk.rgb);
if (!ammoPerk.mobEffects.get().isEmpty()) {
int amplifier;
if (perk.descriptionId.equals("blade_bullet")) {
amplifier = level / 3;
} else if (perk.descriptionId.equals("bread_bullet")) {
amplifier = 1;
} else {
amplifier = level - 1;
}
ArrayList<MobEffectInstance> mobEffectInstances = new ArrayList<>();
for (MobEffect effect : ammoPerk.mobEffects.get()) {
mobEffectInstances.add(new MobEffectInstance(Holder.direct(effect), 70 + 30 * level, amplifier));
}
projectile.effect(mobEffectInstances);
}
if (perk.descriptionId.equals("bread_bullet")) {
projectile.knockback(level * 0.3f);
projectile.forceKnockback();
for (Perk.Type type : Perk.Type.values()) {
var instance = data.perk.getInstance(type);
if (instance != null) {
instance.perk().modifyProjectile(data, instance, projectile);
}
}
bypassArmorRate = Math.max(bypassArmorRate, 0);
projectile.bypassArmorRate(bypassArmorRate);
if (perk == ModPerks.SILVER_BULLET.get()) {
int level = data.perk.getLevel(perk);
projectile.undeadMultiple(1.0f + 0.5f * level);
} else if (perk == ModPerks.BEAST_BULLET.get()) {
projectile.beast();
} else if (perk == ModPerks.JHP_BULLET.get()) {
if (perk == ModPerks.JHP_BULLET.get()) {
int level = data.perk.getLevel(perk);
projectile.jhpBullet(level);
} else if (perk == ModPerks.HE_BULLET.get()) {

View file

@ -16,12 +16,9 @@ import com.atsuishio.superbwarfare.tools.GunsTool;
import com.atsuishio.superbwarfare.tools.SoundTool;
import net.minecraft.client.Minecraft;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.core.Holder;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.tooltip.TooltipComponent;
@ -39,7 +36,6 @@ import software.bernie.geckolib.renderer.GeoItemRenderer;
import software.bernie.geckolib.util.GeckoLibUtil;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
import java.util.Optional;
import java.util.function.Supplier;
@ -215,7 +211,6 @@ public class BocekItem extends GunItem implements GeoItem {
}
}
public void spawnBullet(GunData data, Player player, double power, boolean zoom) {
ItemStack stack = data.stack;
@ -240,46 +235,17 @@ public class BocekItem extends GunItem implements GeoItem {
.shooter(player)
.headShot(headshot)
.zoom(zoom)
.bypassArmorRate(bypassArmorRate)
.setGunItemId(stack);
if (perk instanceof AmmoPerk ammoPerk) {
int level = data.perk.getLevel(perk);
bypassArmorRate += ammoPerk.bypassArmorRate + (perk == ModPerks.AP_BULLET.get() ? 0.05f * (level - 1) : 0);
projectile.setRGB(ammoPerk.rgb);
if (!ammoPerk.mobEffects.get().isEmpty()) {
int amplifier;
if (perk.descriptionId.equals("blade_bullet")) {
amplifier = level / 3;
} else if (perk.descriptionId.equals("bread_bullet")) {
amplifier = 1;
} else {
amplifier = level - 1;
}
ArrayList<MobEffectInstance> mobEffectInstances = new ArrayList<>();
for (MobEffect effect : ammoPerk.mobEffects.get()) {
mobEffectInstances.add(new MobEffectInstance(Holder.direct(effect), 70 + 30 * level, amplifier));
}
projectile.effect(mobEffectInstances);
}
if (perk.descriptionId.equals("bread_bullet")) {
projectile.knockback(level * 0.3f);
projectile.forceKnockback();
for (Perk.Type type : Perk.Type.values()) {
var instance = data.perk.getInstance(type);
if (instance != null) {
instance.perk().modifyProjectile(data, instance, projectile);
}
}
bypassArmorRate = Math.max(bypassArmorRate, 0);
projectile.bypassArmorRate(bypassArmorRate);
if (perk == ModPerks.SILVER_BULLET.get()) {
int level = data.perk.getLevel(perk);
projectile.undeadMultiple(1.0f + 0.5f * level);
} else if (perk == ModPerks.BEAST_BULLET.get()) {
projectile.beast();
} else if (perk == ModPerks.JHP_BULLET.get()) {
if (perk == ModPerks.JHP_BULLET.get()) {
int level = data.perk.getLevel(perk);
projectile.jhpBullet(level);
} else if (perk == ModPerks.HE_BULLET.get()) {

View file

@ -1,7 +1,12 @@
package com.atsuishio.superbwarfare.perk;
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
import com.atsuishio.superbwarfare.item.gun.data.GunData;
import net.minecraft.core.Holder;
import net.minecraft.util.Mth;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity;
import java.util.ArrayList;
import java.util.function.Supplier;
@ -25,6 +30,28 @@ public class AmmoPerk extends Perk {
this.mobEffects = () -> builder.mobEffects;
}
@Override
public void modifyProjectile(GunData data, PerkInstance instance, Entity entity) {
if (!(entity instanceof ProjectileEntity projectile)) return;
projectile.setRGB(this.rgb);
projectile.bypassArmorRate((float) Math.max(this.bypassArmorRate + data.bypassArmor(), 0));
if (this.slug) {
projectile.setDamage((float) (data.damage() * data.projectileAmount()));
}
if (!this.mobEffects.get().isEmpty()) {
int amplifier = this.getEffectAmplifier(instance);
ArrayList<MobEffectInstance> mobEffectInstances = new ArrayList<>();
for (MobEffect effect : this.mobEffects.get()) {
mobEffectInstances.add(new MobEffectInstance(Holder.direct(effect), 70 + 30 * level, amplifier));
}
projectile.effect(mobEffectInstances);
}
}
public int getEffectAmplifier(PerkInstance instance) {
return instance.level() - 1;
}
public static class Builder {
String descriptionId;

View file

@ -5,6 +5,7 @@ import com.atsuishio.superbwarfare.item.PerkItem;
import com.atsuishio.superbwarfare.item.gun.data.GunData;
import net.minecraft.ChatFormatting;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.Item;
import net.neoforged.neoforge.registries.DeferredHolder;
@ -87,6 +88,9 @@ public class Perk {
return false;
}
public void modifyProjectile(GunData data, PerkInstance instance, Entity projectile) {
}
public enum Type {
AMMO("Ammo", ChatFormatting.YELLOW),
FUNCTIONAL("Functional", ChatFormatting.GREEN),

View file

@ -0,0 +1,22 @@
package com.atsuishio.superbwarfare.perk.ammo;
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
import com.atsuishio.superbwarfare.item.gun.data.GunData;
import com.atsuishio.superbwarfare.perk.AmmoPerk;
import com.atsuishio.superbwarfare.perk.Perk;
import com.atsuishio.superbwarfare.perk.PerkInstance;
import net.minecraft.world.entity.Entity;
public class APBullet extends AmmoPerk {
public APBullet() {
super(new AmmoPerk.Builder("ap_bullet", Perk.Type.AMMO).bypassArmorRate(0.4f).damageRate(0.9f).speedRate(1.2f).slug(true).rgb(230, 70, 35));
}
@Override
public void modifyProjectile(GunData data, PerkInstance instance, Entity entity) {
super.modifyProjectile(data, instance, entity);
if (!(entity instanceof ProjectileEntity projectile)) return;
projectile.bypassArmorRate((float) Math.max(data.bypassArmor() + this.bypassArmorRate + 0.05f * (instance.level() - 1), 0));
}
}

View file

@ -0,0 +1,22 @@
package com.atsuishio.superbwarfare.perk.ammo;
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
import com.atsuishio.superbwarfare.item.gun.data.GunData;
import com.atsuishio.superbwarfare.perk.AmmoPerk;
import com.atsuishio.superbwarfare.perk.Perk;
import com.atsuishio.superbwarfare.perk.PerkInstance;
import net.minecraft.world.entity.Entity;
public class BeastBullet extends AmmoPerk {
public BeastBullet() {
super(new AmmoPerk.Builder("beast_bullet", Perk.Type.AMMO).bypassArmorRate(0.0f).rgb(134, 65, 14));
}
@Override
public void modifyProjectile(GunData data, PerkInstance instance, Entity entity) {
super.modifyProjectile(data, instance, entity);
if (!(entity instanceof ProjectileEntity projectile)) return;
projectile.beast();
}
}

View file

@ -0,0 +1,19 @@
package com.atsuishio.superbwarfare.perk.ammo;
import com.atsuishio.superbwarfare.perk.AmmoPerk;
import com.atsuishio.superbwarfare.perk.Perk;
import com.atsuishio.superbwarfare.perk.PerkInstance;
public class BladeBullet extends AmmoPerk {
public BladeBullet() {
super(new AmmoPerk.Builder("blade_bullet", Perk.Type.AMMO)
// .bypassArmorRate(-0.2f).damageRate(0.7f).speedRate(0.8f).rgb(0xB4, 0x4B, 0x88).mobEffect(() -> CompatHolder.DMV_BLEEDING)
);
}
@Override
public int getEffectAmplifier(PerkInstance instance) {
return instance.level() / 3;
}
}

View file

@ -0,0 +1,30 @@
package com.atsuishio.superbwarfare.perk.ammo;
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
import com.atsuishio.superbwarfare.item.gun.data.GunData;
import com.atsuishio.superbwarfare.perk.AmmoPerk;
import com.atsuishio.superbwarfare.perk.Perk;
import com.atsuishio.superbwarfare.perk.PerkInstance;
import net.minecraft.world.entity.Entity;
public class BreadBullet extends AmmoPerk {
public BreadBullet() {
super(new AmmoPerk.Builder("bread_bullet", Perk.Type.AMMO)
// .bypassArmorRate(1.0f).damageRate(0.5f).speedRate(0.6f).rgb(0xde, 0xab, 0x82).mobEffect(() -> MobEffects.MOVEMENT_SLOWDOWN)
);
}
@Override
public int getEffectAmplifier(PerkInstance instance) {
return 1;
}
@Override
public void modifyProjectile(GunData data, PerkInstance instance, Entity entity) {
super.modifyProjectile(data, instance, entity);
if (!(entity instanceof ProjectileEntity projectile)) return;
projectile.knockback(instance.level() * 0.3f);
projectile.forceKnockback();
}
}

View file

@ -0,0 +1,22 @@
package com.atsuishio.superbwarfare.perk.ammo;
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
import com.atsuishio.superbwarfare.item.gun.data.GunData;
import com.atsuishio.superbwarfare.perk.AmmoPerk;
import com.atsuishio.superbwarfare.perk.Perk;
import com.atsuishio.superbwarfare.perk.PerkInstance;
import net.minecraft.world.entity.Entity;
public class SilverBullet extends AmmoPerk {
public SilverBullet() {
super(new AmmoPerk.Builder("silver_bullet", Perk.Type.AMMO).bypassArmorRate(0.05f).damageRate(0.8f).speedRate(1.1f).rgb(87, 166, 219));
}
@Override
public void modifyProjectile(GunData data, PerkInstance instance, Entity entity) {
super.modifyProjectile(data, instance, entity);
if (!(entity instanceof ProjectileEntity projectile)) return;
projectile.undeadMultiple(1.0f + 0.5f * instance.level());
}
}