Implement config and fix small bugs
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
package net.fretux.ascend;
|
||||
|
||||
import net.fretux.ascend.config.AscendConfig;
|
||||
import net.fretux.ascend.network.PacketHandler;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
@@ -17,6 +19,7 @@ public class AscendMod {
|
||||
modBus.addListener(this::onCommonSetup);
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
System.out.println("[Ascend] Mod loaded! Side=" + FMLEnvironment.dist);
|
||||
net.minecraftforge.fml.ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, AscendConfig.COMMON_SPEC);
|
||||
}
|
||||
|
||||
private void onCommonSetup(final FMLCommonSetupEvent event) {
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
package net.fretux.ascend;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.event.config.ModConfigEvent;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Mod.EventBusSubscriber(modid = AscendMod.MODID, bus = Mod.EventBusSubscriber.Bus.MOD)
|
||||
public class Config {
|
||||
private static final ForgeConfigSpec.Builder BUILDER = new ForgeConfigSpec.Builder();
|
||||
|
||||
private static final ForgeConfigSpec.BooleanValue LOG_DIRT_BLOCK = BUILDER
|
||||
.comment("Whether to log the dirt block on common setup")
|
||||
.define("logDirtBlock", true);
|
||||
|
||||
private static final ForgeConfigSpec.IntValue MAGIC_NUMBER = BUILDER
|
||||
.comment("A magic number")
|
||||
.defineInRange("magicNumber", 42, 0, Integer.MAX_VALUE);
|
||||
|
||||
public static final ForgeConfigSpec.ConfigValue<String> MAGIC_NUMBER_INTRODUCTION = BUILDER
|
||||
.comment("What you want the introduction message to be for the magic number")
|
||||
.define("magicNumberIntroduction", "The magic number is... ");
|
||||
|
||||
private static final ForgeConfigSpec.ConfigValue<List<? extends String>> ITEM_STRINGS = BUILDER
|
||||
.comment("A list of items to log on common setup.")
|
||||
.defineListAllowEmpty("items", List.of("minecraft:iron_ingot"), Config::validateItemName);
|
||||
|
||||
static final ForgeConfigSpec SPEC = BUILDER.build();
|
||||
|
||||
public static boolean logDirtBlock;
|
||||
public static int magicNumber;
|
||||
public static String magicNumberIntroduction;
|
||||
public static Set<Item> items;
|
||||
|
||||
private static boolean validateItemName(final Object obj) {
|
||||
return obj instanceof final String itemName && ForgeRegistries.ITEMS.containsKey(new ResourceLocation(itemName));
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
static void onLoad(final ModConfigEvent event) {
|
||||
logDirtBlock = LOG_DIRT_BLOCK.get();
|
||||
magicNumber = MAGIC_NUMBER.get();
|
||||
magicNumberIntroduction = MAGIC_NUMBER_INTRODUCTION.get();
|
||||
items = ITEM_STRINGS.get().stream()
|
||||
.map(itemName -> ForgeRegistries.ITEMS.getValue(new ResourceLocation(itemName)))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package net.fretux.ascend.config;
|
||||
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
public class AscendConfig {
|
||||
|
||||
public static class Common {
|
||||
public final ForgeConfigSpec.IntValue xpPerMobKill;
|
||||
public final ForgeConfigSpec.IntValue xpPerBlockBreak;
|
||||
public final ForgeConfigSpec.IntValue xpPerCraft;
|
||||
public final ForgeConfigSpec.IntValue xpPerSmelt;
|
||||
public final ForgeConfigSpec.IntValue xpPerTrade;
|
||||
public final ForgeConfigSpec.IntValue xpPerDamageTaken;
|
||||
public final ForgeConfigSpec.IntValue xpPerMovement;
|
||||
public final ForgeConfigSpec.IntValue xpPerPotion;
|
||||
public final ForgeConfigSpec.IntValue pointsPerLevel;
|
||||
public final ForgeConfigSpec.IntValue maxAscendLevel;
|
||||
public final ForgeConfigSpec.IntValue maxAttributePoints;
|
||||
|
||||
public final ForgeConfigSpec.DoubleValue xpMultiplier;
|
||||
public final ForgeConfigSpec.DoubleValue attributeScalingMultiplier;
|
||||
|
||||
Common(ForgeConfigSpec.Builder builder) {
|
||||
builder.push("Ascend Progression");
|
||||
|
||||
xpPerMobKill = builder.comment("Ascend XP gained for killing a mob.")
|
||||
.defineInRange("xpPerMobKill", 5, 0, 1000);
|
||||
xpPerBlockBreak = builder.comment("Ascend XP gained for breaking a block (ore/stone/log).")
|
||||
.defineInRange("xpPerBlockBreak", 2, 0, 1000);
|
||||
xpPerCraft = builder.comment("Ascend XP gained for crafting items.")
|
||||
.defineInRange("xpPerCraft", 3, 0, 1000);
|
||||
xpPerSmelt = builder.comment("Ascend XP gained for smelting items.")
|
||||
.defineInRange("xpPerSmelt", 2, 0, 1000);
|
||||
xpPerTrade = builder.comment("Ascend XP gained for trading with villagers.")
|
||||
.defineInRange("xpPerTrade", 5, 0, 1000);
|
||||
xpPerDamageTaken = builder.comment("Ascend XP gained for taking damage.")
|
||||
.defineInRange("xpPerDamageTaken", 2, 0, 1000);
|
||||
xpPerMovement = builder.comment("Ascend XP gained for movement actions.")
|
||||
.defineInRange("xpPerMovement", 1, 0, 1000);
|
||||
xpPerPotion = builder.comment("Ascend XP gained for using a potion.")
|
||||
.defineInRange("xpPerPotion", 3, 0, 1000);
|
||||
|
||||
pointsPerLevel = builder.comment("Unspent points gained per Ascend level.")
|
||||
.defineInRange("pointsPerLevel", 15, 1, 1000);
|
||||
maxAscendLevel = builder.comment("Maximum Ascend level.")
|
||||
.defineInRange("maxAscendLevel", 20, 1, 100);
|
||||
maxAttributePoints = builder.comment("Maximum points in a single attribute.")
|
||||
.defineInRange("maxAttributePoints", 100, 1, 1000);
|
||||
|
||||
xpMultiplier = builder.comment("Global multiplier for all Ascend XP gain.")
|
||||
.defineInRange("xpMultiplier", 1.0D, 0.0D, 100.0D);
|
||||
attributeScalingMultiplier = builder.comment("Global multiplier for all attribute-based stat bonuses (damage, mana, speed, etc.).")
|
||||
.defineInRange("attributeScalingMultiplier", 1.0D, 0.1D, 10.0D);
|
||||
|
||||
builder.pop();
|
||||
}
|
||||
}
|
||||
|
||||
public static final ForgeConfigSpec COMMON_SPEC;
|
||||
public static final Common COMMON;
|
||||
|
||||
static {
|
||||
final Pair<Common, ForgeConfigSpec> specPair = new ForgeConfigSpec.Builder().configure(Common::new);
|
||||
COMMON_SPEC = specPair.getRight();
|
||||
COMMON = specPair.getLeft();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,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.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
@@ -33,7 +34,7 @@ public class ActivityEvents {
|
||||
public static void onMobKilled(LivingDeathEvent event) {
|
||||
if (event.getSource().getEntity() instanceof Player player && !player.level().isClientSide) {
|
||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||
stats.addAscendXP(5);
|
||||
stats.addAscendXP((int) (AscendConfig.COMMON.xpPerMobKill.get() * AscendConfig.COMMON.xpMultiplier.get()));
|
||||
PlayerStatsProvider.sync(player);
|
||||
});
|
||||
}
|
||||
@@ -43,13 +44,11 @@ public class ActivityEvents {
|
||||
public static void onBlockBreak(BlockEvent.BreakEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (player == null || player.level().isClientSide) return;
|
||||
|
||||
Block block = event.getState().getBlock();
|
||||
String name = block.getName().getString().toLowerCase();
|
||||
|
||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||
if (name.contains("log") || name.contains("ore") || name.contains("stone")) {
|
||||
stats.addAscendXP(2);
|
||||
stats.addAscendXP((int) (AscendConfig.COMMON.xpPerBlockBreak.get() * AscendConfig.COMMON.xpMultiplier.get()));
|
||||
PlayerStatsProvider.sync(player);
|
||||
}
|
||||
});
|
||||
@@ -77,7 +76,7 @@ public class ActivityEvents {
|
||||
boolean hasNegativeEffect = player.getActiveEffects().stream()
|
||||
.anyMatch(e -> e.getEffect().getCategory() == MobEffectCategory.HARMFUL);
|
||||
if (player.getFoodData().getFoodLevel() <= 6 || hasNegativeEffect) {
|
||||
stats.addAscendXP(2);
|
||||
stats.addAscendXP((int) (AscendConfig.COMMON.xpPerDamageTaken.get() * AscendConfig.COMMON.xpMultiplier.get()));
|
||||
PlayerStatsProvider.sync(player);
|
||||
}
|
||||
});
|
||||
@@ -97,7 +96,7 @@ public class ActivityEvents {
|
||||
|| Math.abs(player.getDeltaMovement().y) > 0.25
|
||||
|| player.onClimbable();
|
||||
if (didAgileThing) {
|
||||
stats.addAscendXP(1);
|
||||
stats.addAscendXP((int) (AscendConfig.COMMON.xpPerMovement.get() * AscendConfig.COMMON.xpMultiplier.get()));
|
||||
PlayerStatsProvider.sync(player);
|
||||
}
|
||||
});
|
||||
@@ -108,7 +107,7 @@ public class ActivityEvents {
|
||||
Player player = event.getEntity();
|
||||
if (player.level().isClientSide) return;
|
||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||
stats.addAscendXP(3);
|
||||
stats.addAscendXP((int) (AscendConfig.COMMON.xpPerCraft.get() * AscendConfig.COMMON.xpMultiplier.get()));
|
||||
PlayerStatsProvider.sync(player);
|
||||
});
|
||||
}
|
||||
@@ -118,7 +117,7 @@ public class ActivityEvents {
|
||||
Player player = event.getEntity();
|
||||
if (player.level().isClientSide) return;
|
||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||
stats.addAscendXP(2);
|
||||
stats.addAscendXP((int) (AscendConfig.COMMON.xpPerSmelt.get() * AscendConfig.COMMON.xpMultiplier.get()));
|
||||
PlayerStatsProvider.sync(player);
|
||||
});
|
||||
}
|
||||
@@ -151,7 +150,7 @@ public class ActivityEvents {
|
||||
Player player = event.getEntity();
|
||||
if (player.level().isClientSide) return;
|
||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||
stats.addAscendXP(5);
|
||||
stats.addAscendXP((int) (AscendConfig.COMMON.xpPerTrade.get() * AscendConfig.COMMON.xpMultiplier.get()));
|
||||
PlayerStatsProvider.sync(player);
|
||||
});
|
||||
}
|
||||
@@ -178,7 +177,7 @@ public class ActivityEvents {
|
||||
if (player.level().isClientSide) return;
|
||||
if (event.getItemStack().getItem().getDescriptionId().contains("potion")) {
|
||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||
stats.addAscendXP(3);
|
||||
stats.addAscendXP((int) (AscendConfig.COMMON.xpPerPotion.get() * AscendConfig.COMMON.xpMultiplier.get()));
|
||||
PlayerStatsProvider.sync(player);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -26,17 +26,16 @@ public class PlayerEvents {
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onPlayerClone(PlayerEvent.Clone event) {
|
||||
if (!event.isWasDeath()) return;
|
||||
event.getOriginal().reviveCaps();
|
||||
event.getOriginal().getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(oldStats ->
|
||||
event.getEntity().getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(newStats -> {
|
||||
newStats.deserializeNBT(oldStats.serializeNBT());
|
||||
StatEffects.applyAll(event.getEntity());
|
||||
if (!event.getEntity().level().isClientSide) {
|
||||
PlayerStatsProvider.sync(event.getEntity());
|
||||
}
|
||||
})
|
||||
);
|
||||
if (!event.getEntity().level().isClientSide) {
|
||||
StatEffects.applyAll(event.getEntity());
|
||||
PlayerStatsProvider.sync(event.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
@@ -46,5 +45,4 @@ public class PlayerEvents {
|
||||
StatEffects.applyAll(event.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,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.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
@@ -11,6 +12,7 @@ import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@Mod.EventBusSubscriber(modid = AscendMod.MODID)
|
||||
public class WeaponMagicScalingEvents {
|
||||
static double scale = AscendConfig.COMMON.attributeScalingMultiplier.get();
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onLivingHurt(LivingHurtEvent event) {
|
||||
@@ -25,7 +27,7 @@ public class WeaponMagicScalingEvents {
|
||||
if (magicScaling > 0) {
|
||||
double perPoint = 0.005d;
|
||||
double maxBonus = 0.40d;
|
||||
double bonusMult = 1.0d + Math.min(magicScaling * perPoint, maxBonus);
|
||||
double bonusMult = 1.0d + Math.min(magicScaling * perPoint * scale, maxBonus);
|
||||
modified = (float) (modified * bonusMult);
|
||||
}
|
||||
} else {
|
||||
@@ -33,12 +35,10 @@ public class WeaponMagicScalingEvents {
|
||||
if (player.getAttribute(Attributes.ATTACK_SPEED) != null) {
|
||||
attackSpeed = player.getAttribute(Attributes.ATTACK_SPEED).getValue();
|
||||
}
|
||||
|
||||
String key =
|
||||
(attackSpeed >= 1.8d) ? "light_scaling" :
|
||||
(attackSpeed >= 1.2d) ? "medium_scaling" :
|
||||
"heavy_scaling";
|
||||
|
||||
int level = stats.getAttributeLevel(key);
|
||||
if (level > 0) {
|
||||
double perPoint =
|
||||
@@ -46,7 +46,7 @@ public class WeaponMagicScalingEvents {
|
||||
key.equals("medium_scaling") ? 0.004d :
|
||||
0.005d;
|
||||
double maxBonus = 0.40d;
|
||||
double bonusMult = 1.0d + Math.min(level * perPoint, maxBonus);
|
||||
double bonusMult = 1.0d + Math.min(level * perPoint * scale, maxBonus);
|
||||
modified = (float) (modified * bonusMult);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.fretux.ascend.network;
|
||||
|
||||
import net.fretux.ascend.player.PlayerStats;
|
||||
import net.fretux.ascend.player.PlayerStatsProvider;
|
||||
import net.fretux.ascend.player.StatEffects;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
@@ -12,9 +13,17 @@ import java.util.function.Supplier;
|
||||
public class ClientboundSyncStatsPacket {
|
||||
private final CompoundTag data;
|
||||
|
||||
public ClientboundSyncStatsPacket(CompoundTag data) { this.data = data; }
|
||||
public ClientboundSyncStatsPacket(FriendlyByteBuf buf) { this.data = buf.readNbt(); }
|
||||
public void toBytes(FriendlyByteBuf buf) { buf.writeNbt(data); }
|
||||
public ClientboundSyncStatsPacket(CompoundTag data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public ClientboundSyncStatsPacket(FriendlyByteBuf buf) {
|
||||
this.data = buf.readNbt();
|
||||
}
|
||||
|
||||
public void toBytes(FriendlyByteBuf buf) {
|
||||
buf.writeNbt(data);
|
||||
}
|
||||
|
||||
public void handle(Supplier<NetworkEvent.Context> ctx) {
|
||||
System.out.println("[SERVER] Spend packet handle() called");
|
||||
@@ -22,7 +31,9 @@ public class ClientboundSyncStatsPacket {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
var player = mc.player;
|
||||
if (player != null) {
|
||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||
mc.player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||
stats.deserializeNBT(data);
|
||||
StatEffects.applyAll(mc.player);
|
||||
stats.deserializeNBT(data);
|
||||
System.out.println("[CLIENT] Before sync: points="
|
||||
+ player.getCapability(PlayerStatsProvider.PLAYER_STATS)
|
||||
@@ -31,10 +42,9 @@ public class ClientboundSyncStatsPacket {
|
||||
System.out.println("[CLIENT] After sync: points="
|
||||
+ player.getCapability(PlayerStatsProvider.PLAYER_STATS)
|
||||
.map(PlayerStats::getUnspentPoints).orElse(-1));
|
||||
|
||||
});
|
||||
}
|
||||
ctx.get().setPacketHandled(true);
|
||||
});
|
||||
ctx.get().setPacketHandled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package net.fretux.ascend.network;
|
||||
|
||||
import net.fretux.ascend.player.PlayerStatsProvider;
|
||||
import net.fretux.ascend.player.StatEffects;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.fretux.ascend.player.PlayerStatsProvider;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
@@ -31,9 +31,6 @@ public class ServerboundSpendPointPacket {
|
||||
context.enqueueWork(() -> {
|
||||
ServerPlayer player = context.getSender();
|
||||
if (player == null) return;
|
||||
|
||||
System.out.println("[Ascend] Received spend packet '" + attribute + "' from " + player.getGameProfile().getName());
|
||||
|
||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||
boolean success = stats.spendPoints(attribute);
|
||||
if (success) {
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
package net.fretux.ascend.player;
|
||||
|
||||
import net.fretux.ascend.config.AscendConfig;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class PlayerStats {
|
||||
public static final int MAX_ASCEND_LEVEL = 20;
|
||||
public static final int POINTS_PER_LEVEL = 15;
|
||||
public static final int POINTS_PER_LEVEL = AscendConfig.COMMON.pointsPerLevel.get();
|
||||
public static final int MAX_ASCEND_LEVEL = AscendConfig.COMMON.maxAscendLevel.get();
|
||||
public static final int MAX_ATTRIBUTE_POINTS = AscendConfig.COMMON.maxAttributePoints.get();
|
||||
private final Map<String, Integer> attributes = new HashMap<>();
|
||||
private int ascendLevel = 1;
|
||||
private int ascendXP = 0;
|
||||
private int unspentPoints = POINTS_PER_LEVEL;
|
||||
public static final int MAX_ATTRIBUTE_POINTS = 100;
|
||||
public PlayerStats() {
|
||||
for (String attr : new String[]{
|
||||
"strength", "agility", "fortitude", "intelligence",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.fretux.ascend.player;
|
||||
|
||||
import net.fretux.ascend.compat.IronsSpellbooksCompat;
|
||||
import net.fretux.ascend.config.AscendConfig;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
|
||||
@@ -8,9 +9,6 @@ import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import static net.fretux.ascend.compat.IronsSpellbooksCompat.applyCharisma;
|
||||
import static net.fretux.ascend.compat.IronsSpellbooksCompat.applyIntelligence;
|
||||
|
||||
public final class StatEffects {
|
||||
|
||||
private static final UUID STRENGTH_DAMAGE_UUID =
|
||||
@@ -27,6 +25,8 @@ public final class StatEffects {
|
||||
UUID.fromString("e4b5c6d7-8e9f-4012-9abc-334455667788");
|
||||
|
||||
private StatEffects() {}
|
||||
|
||||
static double scale = AscendConfig.COMMON.attributeScalingMultiplier.get();
|
||||
|
||||
public static void applyAll(Player player) {
|
||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||
@@ -39,20 +39,14 @@ public final class StatEffects {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Strength:
|
||||
* - +0.1 attack damage per point (0.05 hearts)
|
||||
* - +0.03 knockback per point
|
||||
* - Armor bypass handled in your combat event using strength level.
|
||||
*/
|
||||
|
||||
public static void applyStrength(Player player, int strengthLevel) {
|
||||
// Damage
|
||||
AttributeInstance atk = player.getAttribute(Attributes.ATTACK_DAMAGE);
|
||||
if (atk != null) {
|
||||
atk.removeModifier(STRENGTH_DAMAGE_UUID);
|
||||
if (strengthLevel > 0) {
|
||||
double dmgBonus = strengthLevel * 0.1d;
|
||||
double dmgBonus = strengthLevel * 0.1d * scale;
|
||||
atk.addTransientModifier(new AttributeModifier(
|
||||
STRENGTH_DAMAGE_UUID,
|
||||
"Ascend Strength damage bonus",
|
||||
@@ -67,7 +61,7 @@ public final class StatEffects {
|
||||
if (kb != null) {
|
||||
kb.removeModifier(STRENGTH_KNOCKBACK_UUID);
|
||||
if (strengthLevel > 0) {
|
||||
double kbBonus = strengthLevel * 0.03d;
|
||||
double kbBonus = strengthLevel * 0.03d * scale;
|
||||
kb.addTransientModifier(new AttributeModifier(
|
||||
STRENGTH_KNOCKBACK_UUID,
|
||||
"Ascend Strength knockback bonus",
|
||||
@@ -77,19 +71,13 @@ public final class StatEffects {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Agility:
|
||||
* - Small movement speed bonus per point.
|
||||
* - Stealth handled externally (e.g. other mods can read agility).
|
||||
*/
|
||||
|
||||
public static void applyAgility(Player player, int agilityLevel) {
|
||||
AttributeInstance move = player.getAttribute(Attributes.MOVEMENT_SPEED);
|
||||
if (move != null) {
|
||||
move.removeModifier(AGILITY_SPEED_UUID);
|
||||
if (agilityLevel > 0) {
|
||||
// Example: +0.002 per point = +0.2 at 100 (about +20% on base 0.1)
|
||||
double bonus = agilityLevel * 0.002d;
|
||||
double bonus = agilityLevel * 0.002d * scale;
|
||||
move.addTransientModifier(new AttributeModifier(
|
||||
AGILITY_SPEED_UUID,
|
||||
"Ascend Agility speed bonus",
|
||||
@@ -99,21 +87,13 @@ public final class StatEffects {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fortitude:
|
||||
* - Max HP up per point.
|
||||
* - Knockback taken reduced via attribute.
|
||||
* (Poison/hunger/debuff tuning handled via your other event hooks.)
|
||||
*/
|
||||
|
||||
public static void applyFortitude(Player player, int fortitudeLevel) {
|
||||
// Max health
|
||||
AttributeInstance hp = player.getAttribute(Attributes.MAX_HEALTH);
|
||||
if (hp != null) {
|
||||
hp.removeModifier(FORTITUDE_HEALTH_UUID);
|
||||
if (fortitudeLevel > 0) {
|
||||
// Example: 0.25 HP (1/8 heart) per point = +12.5 hearts at 100
|
||||
double healthBonus = fortitudeLevel * 0.25d;
|
||||
double healthBonus = fortitudeLevel * 0.25d * scale;
|
||||
hp.addTransientModifier(new AttributeModifier(
|
||||
FORTITUDE_HEALTH_UUID,
|
||||
"Ascend Fortitude health bonus",
|
||||
@@ -122,14 +102,11 @@ public final class StatEffects {
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Knockback resistance
|
||||
AttributeInstance kbRes = player.getAttribute(Attributes.KNOCKBACK_RESISTANCE);
|
||||
if (kbRes != null) {
|
||||
kbRes.removeModifier(FORTITUDE_KB_RESIST_UUID);
|
||||
if (fortitudeLevel > 0) {
|
||||
// Tiny scaling; cap at 60% here
|
||||
double res = Math.min(0.006d * fortitudeLevel, 0.60d);
|
||||
double res = Math.min(0.006d * fortitudeLevel * scale, 0.60d);
|
||||
kbRes.addTransientModifier(new AttributeModifier(
|
||||
FORTITUDE_KB_RESIST_UUID,
|
||||
"Ascend Fortitude knockback resist",
|
||||
@@ -139,75 +116,40 @@ public final class StatEffects {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Intelligence:
|
||||
* - Used for mana & potion/enchant effects via other hooks.
|
||||
* - Here we only expose a mana bonus helper.
|
||||
*/
|
||||
|
||||
// ===== Willpower external API =====
|
||||
|
||||
/**
|
||||
* Sanity drain multiplier from Willpower.
|
||||
* Other mods can call this directly.
|
||||
*
|
||||
* - Starts at 1.0
|
||||
* - Reduces up to 50% at high Willpower.
|
||||
*/
|
||||
|
||||
public static float getWillpowerSanityMultiplier(int willpowerLevel) {
|
||||
if (willpowerLevel <= 0) return 1.0f;
|
||||
double reduction = Math.min(willpowerLevel * 0.005d, 0.5d); // up to -50%
|
||||
double reduction = Math.min(willpowerLevel * 0.005d * scale, 0.5d);
|
||||
return (float) (1.0d - reduction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tempo gain/multiplier from Willpower.
|
||||
* Other mods can plug this into stamina/tempo/sprint systems.
|
||||
*
|
||||
* - Starts at 1.0
|
||||
* - Increases up to +40%.
|
||||
*/
|
||||
|
||||
public static float getWillpowerTempoMultiplier(int willpowerLevel) {
|
||||
if (willpowerLevel <= 0) return 1.0f;
|
||||
double bonus = Math.min(willpowerLevel * 0.004d, 0.4d); // up to +40%
|
||||
double bonus = Math.min(willpowerLevel * 0.004d * scale, 0.4d); // up to +40%
|
||||
return (float) (1.0d + bonus);
|
||||
}
|
||||
|
||||
/** Convenience: from player capability → sanity multiplier. */
|
||||
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);
|
||||
}
|
||||
|
||||
/** Convenience: from player capability → tempo multiplier. */
|
||||
|
||||
public static float getPlayerTempoMultiplier(Player player) {
|
||||
return player.getCapability(PlayerStatsProvider.PLAYER_STATS)
|
||||
.map(stats -> getWillpowerTempoMultiplier(stats.getAttributeLevel("willpower")))
|
||||
.orElse(1.0f);
|
||||
}
|
||||
|
||||
// ===== Intelligence external helper (for your mana system) =====
|
||||
|
||||
/**
|
||||
* Example mana bonus: 1 mana per INT, capped by caller if needed.
|
||||
*/
|
||||
|
||||
public static int getIntelligenceManaBonus(int intelligenceLevel) {
|
||||
return Math.max(0, intelligenceLevel);
|
||||
}
|
||||
|
||||
// ===== Charisma helper (used in trade discount handler) =====
|
||||
|
||||
/**
|
||||
* Charisma → trade discount fraction.
|
||||
* Returns value in [0, max], e.g. 0.0 = no discount, 0.25 = 25% cheaper.
|
||||
*/
|
||||
public static double getCharismaTradeDiscount(int charismaLevel) {
|
||||
if (charismaLevel <= 0) return 0.0d;
|
||||
double perPoint = 0.01d;
|
||||
double max = 0.30d;
|
||||
return Math.min(charismaLevel * perPoint, max);
|
||||
return Math.min(charismaLevel * perPoint * scale, max);
|
||||
}
|
||||
|
||||
public static double getWeaponScalingMultiplier(int scalingLevel) {
|
||||
|
||||
Reference in New Issue
Block a user