diff --git a/src/main/java/net/fretux/ascend/event/ActivityEvents.java b/src/main/java/net/fretux/ascend/event/ActivityEvents.java index ffa0aac..dd6e703 100644 --- a/src/main/java/net/fretux/ascend/event/ActivityEvents.java +++ b/src/main/java/net/fretux/ascend/event/ActivityEvents.java @@ -3,6 +3,7 @@ package net.fretux.ascend.event; import net.fretux.ascend.AscendMod; import net.fretux.ascend.config.AscendConfig; import net.fretux.ascend.player.PlayerStatsProvider; +import net.fretux.ascend.player.StatEffects; import net.minecraft.core.BlockPos; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.server.level.ServerLevel; @@ -216,17 +217,24 @@ public class ActivityEvents { public static void onPlayerDealsDamage(LivingDamageEvent event) { if (!(event.getSource().getEntity() instanceof Player player)) return; if (player.level().isClientSide) return; - LivingEntity target = event.getEntity(); player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> { - int strength = stats.getAttributeLevel("strength"); - if (strength <= 0) return; - float bypassFraction = Math.min(strength * 0.001f, 0.30f); - int armor = target.getArmorValue(); - if (armor <= 0 || bypassFraction <= 0f) return; - float baseDamage = event.getAmount(); - float armorFactor = (float) armor / (armor + 100.0f); - float bonus = baseDamage * armorFactor * bypassFraction; - event.setAmount(baseDamage + bonus); + float damage = event.getAmount(); + var stack = player.getMainHandItem(); + if (!stack.isEmpty()) { + double multiplier = 1.0d; + if (stack.getItem() instanceof net.minecraft.world.item.AxeItem) { + int heavy = stats.getAttributeLevel("heavy_scaling"); + multiplier = StatEffects.getHeavyWeaponScalingMultiplier(heavy); + } else if (stack.getItem() instanceof net.minecraft.world.item.SwordItem) { + int medium = stats.getAttributeLevel("medium_scaling"); + multiplier = StatEffects.getWeaponScalingMultiplier(medium); + } else { + int light = stats.getAttributeLevel("light_scaling"); + multiplier = StatEffects.getLightWeaponScalingMultiplier(light); + } + damage *= multiplier; + } + event.setAmount(damage); }); } diff --git a/src/main/java/net/fretux/ascend/network/ServerboundShrineChoicePacket.java b/src/main/java/net/fretux/ascend/network/ServerboundShrineChoicePacket.java index 5bedafc..8592272 100644 --- a/src/main/java/net/fretux/ascend/network/ServerboundShrineChoicePacket.java +++ b/src/main/java/net/fretux/ascend/network/ServerboundShrineChoicePacket.java @@ -38,6 +38,7 @@ public class ServerboundShrineChoicePacket { if (stats.getKnowledge() >= 15) { stats.addKnowledge(-15); stats.refundAllPoints(); + net.fretux.ascend.player.StatEffects.applyAll(player); player.sendSystemMessage(Component.literal("YOU ARE A BLANK SLATE. EMPTY. FORGOTTEN.")); RemembranceEssenceItem.consume(player); } else { diff --git a/src/main/java/net/fretux/ascend/player/StatEffects.java b/src/main/java/net/fretux/ascend/player/StatEffects.java index ed8b3f2..e021d84 100644 --- a/src/main/java/net/fretux/ascend/player/StatEffects.java +++ b/src/main/java/net/fretux/ascend/player/StatEffects.java @@ -24,30 +24,46 @@ public final class StatEffects { private static final UUID FORTITUDE_KB_RESIST_UUID = UUID.fromString("e4b5c6d7-8e9f-4012-9abc-334455667788"); - private StatEffects() {} + private StatEffects() { + } private static double getScaling() { return AscendConfig.COMMON.attributeScalingMultiplier.get(); } + private static double mediumScalingPercent(int x) { + if (x <= 0) return 0.0d; + return Math.pow(3.5d * x, 0.61d); + } + + private static double lightScalingPercent(int x) { + if (x <= 0) return 0.0d; + return Math.pow(4.0d * x, 0.55d); + } + + private static double heavyScalingPercent(int x) { + if (x <= 0) return 0.0d; + return (0.4d * x) + (5.0d * Math.sin(0.065d * x)); + } + public static void applyAll(Player player) { player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> { applyStrength(player, stats.getAttributeLevel("strength")); applyAgility(player, stats.getAttributeLevel("agility")); applyFortitude(player, stats.getAttributeLevel("fortitude")); - // - Willpower: see getWillpowerSanityMultiplier / getWillpowerTempoMultiplier. if (IronsSpellbooksCompat.isLoaded()) { IronsSpellbooksCompat.applyAll(player); } }); } - + public static void applyStrength(Player player, int strengthLevel) { + // Always remove first so resets correctly. AttributeInstance atk = player.getAttribute(Attributes.ATTACK_DAMAGE); if (atk != null) { atk.removeModifier(STRENGTH_DAMAGE_UUID); if (strengthLevel > 0) { - double dmgBonus = strengthLevel * 0.1d * getScaling(); + double dmgBonus = (mediumScalingPercent(strengthLevel) * 0.1d) * getScaling(); atk.addTransientModifier(new AttributeModifier( STRENGTH_DAMAGE_UUID, "Ascend Strength damage bonus", @@ -57,12 +73,11 @@ public final class StatEffects { } } - // Knockback AttributeInstance kb = player.getAttribute(Attributes.ATTACK_KNOCKBACK); if (kb != null) { kb.removeModifier(STRENGTH_KNOCKBACK_UUID); if (strengthLevel > 0) { - double kbBonus = strengthLevel * 0.015d * getScaling(); + double kbBonus = (mediumScalingPercent(strengthLevel) * 0.015d) * getScaling(); kb.addTransientModifier(new AttributeModifier( STRENGTH_KNOCKBACK_UUID, "Ascend Strength knockback bonus", @@ -72,7 +87,7 @@ public final class StatEffects { } } } - + public static void applyAgility(Player player, int agilityLevel) { AttributeInstance move = player.getAttribute(Attributes.MOVEMENT_SPEED); if (move != null) { @@ -88,7 +103,7 @@ public final class StatEffects { } } } - + public static void applyFortitude(Player player, int fortitudeLevel) { AttributeInstance hp = player.getAttribute(Attributes.MAX_HEALTH); if (hp != null) { @@ -117,53 +132,64 @@ public final class StatEffects { } } } - + public static float getWillpowerSanityMultiplier(int willpowerLevel) { if (willpowerLevel <= 0) return 1.0f; double reduction = Math.min(willpowerLevel * 0.005d * getScaling(), 0.5d); return (float) (1.0d - reduction); } - + public static float getWillpowerTempoMultiplier(int willpowerLevel) { if (willpowerLevel <= 0) return 1.0f; double bonus = Math.min(willpowerLevel * 0.004d * getScaling(), 0.4d); return (float) (1.0d + bonus); } - public static float getPlayerSanityMultiplier(Player player) { + public static float getPlayerSanityMultiplier(Player player) { return player.getCapability(PlayerStatsProvider.PLAYER_STATS) .map(stats -> getWillpowerSanityMultiplier(stats.getAttributeLevel("willpower"))) .orElse(1.0f); } - + public static float getPlayerTempoMultiplier(Player player) { return player.getCapability(PlayerStatsProvider.PLAYER_STATS) .map(stats -> getWillpowerTempoMultiplier(stats.getAttributeLevel("willpower"))) .orElse(1.0f); } - + public static int getIntelligenceManaBonus(int intelligenceLevel) { return Math.max(0, intelligenceLevel); } public static double getCharismaTradeDiscount(int charismaLevel) { if (charismaLevel <= 0) return 0.0d; - double perPoint = 0.01d; - double max = 0.30d; + double perPoint = 0.01d; + double max = 0.30d; return Math.min(charismaLevel * perPoint * getScaling(), max); } - + public static double getWeaponScalingMultiplier(int scalingLevel) { if (scalingLevel <= 0) return 1.0d; - double perPoint = 0.005d; - double maxBonus = 0.50d; - return 1.0d + Math.min(scalingLevel * perPoint, maxBonus); + double percent = mediumScalingPercent(scalingLevel); + return 1.0d + (percent / 100.0d); + } + + public static double getLightWeaponScalingMultiplier(int scalingLevel) { + if (scalingLevel <= 0) return 1.0d; + double percent = lightScalingPercent(scalingLevel); + return 1.0d + (percent / 100.0d); + } + + public static double getHeavyWeaponScalingMultiplier(int scalingLevel) { + if (scalingLevel <= 0) return 1.0d; + double percent = heavyScalingPercent(scalingLevel); + return 1.0d + (percent / 100.0d); } public static double getMagicScalingMultiplier(int scalingLevel) { if (scalingLevel <= 0) return 1.0d; - double perPoint = 0.0075d; - double maxBonus = 0.75d; + double perPoint = 0.0075d; + double maxBonus = 0.75d; return 1.0d + Math.min(scalingLevel * perPoint, maxBonus); } } \ No newline at end of file