重制部分功能perk
This commit is contained in:
parent
30c114af35
commit
90e76d7c92
7 changed files with 172 additions and 102 deletions
|
@ -7,7 +7,6 @@ import com.atsuishio.superbwarfare.config.server.MiscConfig;
|
|||
import com.atsuishio.superbwarfare.config.server.VehicleConfig;
|
||||
import com.atsuishio.superbwarfare.entity.ICustomKnockback;
|
||||
import com.atsuishio.superbwarfare.entity.TargetEntity;
|
||||
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.LaserTowerEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.ArmedVehicleEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.ContainerMobileVehicleEntity;
|
||||
|
@ -496,22 +495,11 @@ public class LivingEventHandler {
|
|||
if (instance != null) {
|
||||
instance.perk().onHit(damage, data, instance, event.getEntity(), source);
|
||||
damage = instance.perk().getModifiedDamage(damage, data, instance, event.getEntity(), source);
|
||||
}
|
||||
}
|
||||
|
||||
if (source.getDirectEntity() instanceof ProjectileEntity projectile) {
|
||||
if (data.perk.getLevel(ModPerks.FOURTH_TIMES_CHARM) > 0) {
|
||||
float bypassArmorRate = projectile.getBypassArmorRate();
|
||||
if (bypassArmorRate >= 1.0f && source.is(ModDamageTypes.GUN_FIRE_HEADSHOT_ABSOLUTE)) {
|
||||
handleFourthTimesCharm(stack);
|
||||
} else if (source.is(ModDamageTypes.GUN_FIRE_HEADSHOT)) {
|
||||
handleFourthTimesCharm(stack);
|
||||
if (instance.perk().shouldCancelHurtEvent(damage, data, instance, event.getEntity(), source)) {
|
||||
event.setCanceled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!projectile.isZoom()) {
|
||||
handleFieldDoctor(stack, event, attacker);
|
||||
}
|
||||
}
|
||||
|
||||
event.setAmount(damage);
|
||||
|
@ -544,67 +532,6 @@ public class LivingEventHandler {
|
|||
instance.perk().onKill(data, instance, event.getEntity(), source);
|
||||
}
|
||||
}
|
||||
|
||||
if (DamageTypeTool.isGunDamage(source)) {
|
||||
handleSubsistence(stack, attacker);
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleFourthTimesCharm(ItemStack stack) {
|
||||
var data = GunData.from(stack);
|
||||
int level = data.perk.getLevel(ModPerks.FOURTH_TIMES_CHARM);
|
||||
if (level == 0) return;
|
||||
final var tag = data.perk.getTag(ModPerks.FOURTH_TIMES_CHARM);
|
||||
|
||||
int fourthTimesCharmTick = tag.getInt("FourthTimesCharmTick");
|
||||
if (fourthTimesCharmTick <= 0) {
|
||||
tag.putInt("FourthTimesCharmTick", 40 + 10 * level);
|
||||
tag.putInt("FourthTimesCharmCount", 1);
|
||||
} else {
|
||||
int count = tag.getInt("FourthTimesCharmCount");
|
||||
if (count < 4) {
|
||||
tag.putInt("FourthTimesCharmCount", Math.min(4, count + 1));
|
||||
}
|
||||
}
|
||||
|
||||
data.save();
|
||||
}
|
||||
|
||||
private static void handleSubsistence(ItemStack stack, Player player) {
|
||||
var data = GunData.from(stack);
|
||||
int level = data.perk.getLevel(ModPerks.SUBSISTENCE);
|
||||
if (level == 0) return;
|
||||
|
||||
float rate = level * 0.1f + (stack.is(ModTags.Items.SMG) || stack.is(ModTags.Items.RIFLE) ? 0.07f : 0f);
|
||||
|
||||
int mag = data.magazine();
|
||||
int ammo = data.ammo.get();
|
||||
int ammoReload = (int) Math.min(mag, mag * rate);
|
||||
int ammoNeed = Math.min(mag - ammo, ammoReload);
|
||||
|
||||
boolean flag = player.isCreative() || InventoryTool.hasCreativeAmmoBox(player);
|
||||
|
||||
int ammoFinal = Math.min(data.countBackupAmmo(player), ammoNeed);
|
||||
if (flag) {
|
||||
ammoFinal = ammoNeed;
|
||||
} else {
|
||||
data.consumeBackupAmmo(player, ammoFinal);
|
||||
}
|
||||
data.ammo.set(Math.min(mag, ammo + ammoFinal));
|
||||
|
||||
data.save();
|
||||
}
|
||||
|
||||
|
||||
private static void handleFieldDoctor(ItemStack stack, LivingIncomingDamageEvent event, Player player) {
|
||||
var data = GunData.from(stack);
|
||||
int level = data.perk.getLevel(ModPerks.FIELD_DOCTOR);
|
||||
if (level == 0) return;
|
||||
|
||||
if (event.getEntity().isAlliedTo(player)) {
|
||||
event.getEntity().heal(event.getAmount() * Math.min(1.0f, 0.25f + 0.05f * level));
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
|
|
@ -4,7 +4,10 @@ import com.atsuishio.superbwarfare.Mod;
|
|||
import com.atsuishio.superbwarfare.perk.AmmoPerk;
|
||||
import com.atsuishio.superbwarfare.perk.Perk;
|
||||
import com.atsuishio.superbwarfare.perk.damage.*;
|
||||
import com.atsuishio.superbwarfare.perk.functional.FieldDoctor;
|
||||
import com.atsuishio.superbwarfare.perk.functional.FourthTimesCharm;
|
||||
import com.atsuishio.superbwarfare.perk.functional.HealClip;
|
||||
import com.atsuishio.superbwarfare.perk.functional.Subsistence;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.effect.MobEffects;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
|
@ -55,9 +58,9 @@ public class ModPerks {
|
|||
public static final DeferredRegister<Perk> FUNC_PERKS = DeferredRegister.create(Mod.loc("perk"), Mod.MODID);
|
||||
|
||||
public static final DeferredHolder<Perk, Perk> HEAL_CLIP = FUNC_PERKS.register("heal_clip", HealClip::new);
|
||||
public static final DeferredHolder<Perk, Perk> FOURTH_TIMES_CHARM = FUNC_PERKS.register("fourth_times_charm", () -> new Perk("fourth_times_charm", Perk.Type.FUNCTIONAL));
|
||||
public static final DeferredHolder<Perk, Perk> SUBSISTENCE = FUNC_PERKS.register("subsistence", () -> new Perk("subsistence", Perk.Type.FUNCTIONAL));
|
||||
public static final DeferredHolder<Perk, Perk> FIELD_DOCTOR = FUNC_PERKS.register("field_doctor", () -> new Perk("field_doctor", Perk.Type.FUNCTIONAL));
|
||||
public static final DeferredHolder<Perk, Perk> FOURTH_TIMES_CHARM = FUNC_PERKS.register("fourth_times_charm", FourthTimesCharm::new);
|
||||
public static final DeferredHolder<Perk, Perk> SUBSISTENCE = FUNC_PERKS.register("subsistence", Subsistence::new);
|
||||
public static final DeferredHolder<Perk, Perk> FIELD_DOCTOR = FUNC_PERKS.register("field_doctor", FieldDoctor::new);
|
||||
public static final DeferredHolder<Perk, Perk> REGENERATION = FUNC_PERKS.register("regeneration", () -> new Perk("regeneration", Perk.Type.FUNCTIONAL));
|
||||
public static final DeferredHolder<Perk, Perk> TURBO_CHARGER = FUNC_PERKS.register("turbo_charger", () -> new Perk("turbo_charger", Perk.Type.FUNCTIONAL));
|
||||
public static final DeferredHolder<Perk, Perk> POWERFUL_ATTRACTION = FUNC_PERKS.register("powerful_attraction", () -> new Perk("powerful_attraction", Perk.Type.FUNCTIONAL));
|
||||
|
|
|
@ -100,7 +100,6 @@ public abstract class GunItem extends Item implements CustomRendererItem {
|
|||
instance.perk().tick(data, instance, living);
|
||||
}
|
||||
}
|
||||
handleGunPerks(data);
|
||||
|
||||
var hasBulletInBarrel = gunItem.hasBulletInBarrel(stack);
|
||||
var ammoCount = data.ammo.get();
|
||||
|
@ -197,28 +196,6 @@ public abstract class GunItem extends Item implements CustomRendererItem {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
private void handleGunPerks(GunData data) {
|
||||
var perk = data.perk;
|
||||
|
||||
perk.reduceCooldown(ModPerks.FOURTH_TIMES_CHARM, "FourthTimesCharmTick");
|
||||
|
||||
if (perk.getLevel(ModPerks.FOURTH_TIMES_CHARM) > 0) {
|
||||
var tag = data.perk.getTag(ModPerks.FOURTH_TIMES_CHARM);
|
||||
int count = perk.getTag(ModPerks.FOURTH_TIMES_CHARM).getInt("FourthTimesCharmCount");
|
||||
|
||||
if (count >= 4) {
|
||||
tag.remove("FourthTimesCharmTick");
|
||||
tag.remove("FourthTimesCharmCount");
|
||||
|
||||
int mag = data.magazine();
|
||||
data.ammo.set(Math.min(mag, data.ammo.get() + 2));
|
||||
}
|
||||
}
|
||||
|
||||
data.save();
|
||||
}
|
||||
|
||||
public boolean canApplyPerk(Perk perk) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -83,6 +83,10 @@ public class Perk {
|
|||
public void onChangeSlot(GunData data, PerkInstance instance, @Nullable LivingEntity living) {
|
||||
}
|
||||
|
||||
public boolean shouldCancelHurtEvent(float damage, GunData data, PerkInstance instance, LivingEntity target, DamageSource source) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
AMMO("Ammo", ChatFormatting.YELLOW),
|
||||
FUNCTIONAL("Functional", ChatFormatting.GREEN),
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
package com.atsuishio.superbwarfare.perk.functional;
|
||||
|
||||
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
|
||||
import com.atsuishio.superbwarfare.item.gun.data.GunData;
|
||||
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.player.Player;
|
||||
import net.minecraft.world.entity.projectile.Projectile;
|
||||
|
||||
public class FieldDoctor extends Perk {
|
||||
|
||||
public FieldDoctor() {
|
||||
super("field_doctor", Perk.Type.FUNCTIONAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHit(float damage, GunData data, PerkInstance instance, LivingEntity target, DamageSource source) {
|
||||
if (!trigger(target, source)) {
|
||||
return;
|
||||
}
|
||||
target.heal(damage * Math.min(1.0f, 0.25f + 0.05f * instance.level()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldCancelHurtEvent(float damage, GunData data, PerkInstance instance, LivingEntity target, DamageSource source) {
|
||||
return trigger(target, source);
|
||||
}
|
||||
|
||||
public boolean trigger(LivingEntity target, DamageSource source) {
|
||||
if (source.getDirectEntity() instanceof ProjectileEntity projectile && !projectile.isZoom()) {
|
||||
Player attacker = null;
|
||||
if (source.getEntity() instanceof Player player) {
|
||||
attacker = player;
|
||||
}
|
||||
if (source.getDirectEntity() instanceof Projectile p && p.getOwner() instanceof Player player) {
|
||||
attacker = player;
|
||||
}
|
||||
return attacker != null && target != null && target.isAlliedTo(attacker);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package com.atsuishio.superbwarfare.perk.functional;
|
||||
|
||||
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
|
||||
import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
||||
import com.atsuishio.superbwarfare.item.gun.data.GunData;
|
||||
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 org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class FourthTimesCharm extends Perk {
|
||||
|
||||
public FourthTimesCharm() {
|
||||
super("fourth_times_charm", Perk.Type.FUNCTIONAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(GunData data, PerkInstance instance, @Nullable LivingEntity living) {
|
||||
data.perk.reduceCooldown(this, "FourthTimesCharmTick");
|
||||
|
||||
var tag = data.perk.getTag(this);
|
||||
int count = tag.getInt("FourthTimesCharmCount");
|
||||
|
||||
if (count >= 4) {
|
||||
tag.remove("FourthTimesCharmTick");
|
||||
tag.remove("FourthTimesCharmCount");
|
||||
|
||||
int mag = data.magazine();
|
||||
data.ammo.set(Math.min(mag, data.ammo.get() + 2));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHit(float damage, GunData data, PerkInstance instance, LivingEntity target, DamageSource source) {
|
||||
if (source.getDirectEntity() instanceof ProjectileEntity projectile) {
|
||||
float bypassArmorRate = projectile.getBypassArmorRate();
|
||||
if (bypassArmorRate >= 1.0f && source.is(ModDamageTypes.GUN_FIRE_HEADSHOT_ABSOLUTE)) {
|
||||
handleFourthTimesCharm(data, instance);
|
||||
} else if (source.is(ModDamageTypes.GUN_FIRE_HEADSHOT)) {
|
||||
handleFourthTimesCharm(data, instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void handleFourthTimesCharm(GunData data, PerkInstance instance) {
|
||||
int fourthTimesCharmTick = data.perk.getTag(this).getInt("FourthTimesCharmTick");
|
||||
if (fourthTimesCharmTick <= 0) {
|
||||
data.perk.getTag(this).putInt("FourthTimesCharmTick", 40 + 10 * instance.level());
|
||||
data.perk.getTag(this).putInt("FourthTimesCharmCount", 1);
|
||||
} else {
|
||||
int count = data.perk.getTag(this).getInt("FourthTimesCharmCount");
|
||||
if (count < 4) {
|
||||
data.perk.getTag(this).putInt("FourthTimesCharmCount", Math.min(4, count + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package com.atsuishio.superbwarfare.perk.functional;
|
||||
|
||||
import com.atsuishio.superbwarfare.init.ModAttachments;
|
||||
import com.atsuishio.superbwarfare.init.ModTags;
|
||||
import com.atsuishio.superbwarfare.item.gun.data.GunData;
|
||||
import com.atsuishio.superbwarfare.perk.Perk;
|
||||
import com.atsuishio.superbwarfare.perk.PerkInstance;
|
||||
import com.atsuishio.superbwarfare.tools.DamageTypeTool;
|
||||
import com.atsuishio.superbwarfare.tools.InventoryTool;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.projectile.Projectile;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public class Subsistence extends Perk {
|
||||
|
||||
public Subsistence() {
|
||||
super("subsistence", Perk.Type.FUNCTIONAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKill(GunData data, PerkInstance instance, LivingEntity target, DamageSource source) {
|
||||
Player attacker = null;
|
||||
if (source.getEntity() instanceof Player player) {
|
||||
attacker = player;
|
||||
}
|
||||
if (source.getDirectEntity() instanceof Projectile p && p.getOwner() instanceof Player player) {
|
||||
attacker = player;
|
||||
}
|
||||
|
||||
if (DamageTypeTool.isGunDamage(source) && attacker != null) {
|
||||
ItemStack stack = data.stack;
|
||||
|
||||
float rate = instance.level() * (0.1f + (stack.is(ModTags.Items.SMG) || stack.is(ModTags.Items.RIFLE) ? 0.07f : 0f));
|
||||
|
||||
var cap = attacker.getData(ModAttachments.PLAYER_VARIABLE).watch();
|
||||
|
||||
int mag = data.magazine();
|
||||
int ammo = data.ammo.get();
|
||||
int ammoReload = (int) Math.min(mag, mag * rate);
|
||||
int ammoNeed = Math.min(mag - ammo, ammoReload);
|
||||
|
||||
boolean flag = attacker.isCreative() || InventoryTool.hasCreativeAmmoBox(attacker);
|
||||
|
||||
int ammoFinal = Math.min(data.countBackupAmmo(attacker), ammoNeed);
|
||||
if (flag) {
|
||||
ammoFinal = ammoNeed;
|
||||
} else {
|
||||
data.consumeBackupAmmo(attacker, ammoFinal);
|
||||
}
|
||||
data.ammo.set(Math.min(mag, ammo + ammoFinal));
|
||||
|
||||
cap.sync(attacker);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue