Implement config and fix small bugs
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
package net.fretux.ascend;
|
package net.fretux.ascend;
|
||||||
|
|
||||||
|
import net.fretux.ascend.config.AscendConfig;
|
||||||
import net.fretux.ascend.network.PacketHandler;
|
import net.fretux.ascend.network.PacketHandler;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.config.ModConfig;
|
||||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||||
import net.minecraftforge.eventbus.api.IEventBus;
|
import net.minecraftforge.eventbus.api.IEventBus;
|
||||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
@@ -17,6 +19,7 @@ public class AscendMod {
|
|||||||
modBus.addListener(this::onCommonSetup);
|
modBus.addListener(this::onCommonSetup);
|
||||||
MinecraftForge.EVENT_BUS.register(this);
|
MinecraftForge.EVENT_BUS.register(this);
|
||||||
System.out.println("[Ascend] Mod loaded! Side=" + FMLEnvironment.dist);
|
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) {
|
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;
|
package net.fretux.ascend.event;
|
||||||
|
|
||||||
import net.fretux.ascend.AscendMod;
|
import net.fretux.ascend.AscendMod;
|
||||||
|
import net.fretux.ascend.config.AscendConfig;
|
||||||
import net.fretux.ascend.player.PlayerStatsProvider;
|
import net.fretux.ascend.player.PlayerStatsProvider;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.particles.ParticleTypes;
|
import net.minecraft.core.particles.ParticleTypes;
|
||||||
@@ -33,7 +34,7 @@ public class ActivityEvents {
|
|||||||
public static void onMobKilled(LivingDeathEvent event) {
|
public static void onMobKilled(LivingDeathEvent event) {
|
||||||
if (event.getSource().getEntity() instanceof Player player && !player.level().isClientSide) {
|
if (event.getSource().getEntity() instanceof Player player && !player.level().isClientSide) {
|
||||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||||
stats.addAscendXP(5);
|
stats.addAscendXP((int) (AscendConfig.COMMON.xpPerMobKill.get() * AscendConfig.COMMON.xpMultiplier.get()));
|
||||||
PlayerStatsProvider.sync(player);
|
PlayerStatsProvider.sync(player);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -43,13 +44,11 @@ public class ActivityEvents {
|
|||||||
public static void onBlockBreak(BlockEvent.BreakEvent event) {
|
public static void onBlockBreak(BlockEvent.BreakEvent event) {
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
if (player == null || player.level().isClientSide) return;
|
if (player == null || player.level().isClientSide) return;
|
||||||
|
|
||||||
Block block = event.getState().getBlock();
|
Block block = event.getState().getBlock();
|
||||||
String name = block.getName().getString().toLowerCase();
|
String name = block.getName().getString().toLowerCase();
|
||||||
|
|
||||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||||
if (name.contains("log") || name.contains("ore") || name.contains("stone")) {
|
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);
|
PlayerStatsProvider.sync(player);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -77,7 +76,7 @@ public class ActivityEvents {
|
|||||||
boolean hasNegativeEffect = player.getActiveEffects().stream()
|
boolean hasNegativeEffect = player.getActiveEffects().stream()
|
||||||
.anyMatch(e -> e.getEffect().getCategory() == MobEffectCategory.HARMFUL);
|
.anyMatch(e -> e.getEffect().getCategory() == MobEffectCategory.HARMFUL);
|
||||||
if (player.getFoodData().getFoodLevel() <= 6 || hasNegativeEffect) {
|
if (player.getFoodData().getFoodLevel() <= 6 || hasNegativeEffect) {
|
||||||
stats.addAscendXP(2);
|
stats.addAscendXP((int) (AscendConfig.COMMON.xpPerDamageTaken.get() * AscendConfig.COMMON.xpMultiplier.get()));
|
||||||
PlayerStatsProvider.sync(player);
|
PlayerStatsProvider.sync(player);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -97,7 +96,7 @@ public class ActivityEvents {
|
|||||||
|| Math.abs(player.getDeltaMovement().y) > 0.25
|
|| Math.abs(player.getDeltaMovement().y) > 0.25
|
||||||
|| player.onClimbable();
|
|| player.onClimbable();
|
||||||
if (didAgileThing) {
|
if (didAgileThing) {
|
||||||
stats.addAscendXP(1);
|
stats.addAscendXP((int) (AscendConfig.COMMON.xpPerMovement.get() * AscendConfig.COMMON.xpMultiplier.get()));
|
||||||
PlayerStatsProvider.sync(player);
|
PlayerStatsProvider.sync(player);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -108,7 +107,7 @@ public class ActivityEvents {
|
|||||||
Player player = event.getEntity();
|
Player player = event.getEntity();
|
||||||
if (player.level().isClientSide) return;
|
if (player.level().isClientSide) return;
|
||||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||||
stats.addAscendXP(3);
|
stats.addAscendXP((int) (AscendConfig.COMMON.xpPerCraft.get() * AscendConfig.COMMON.xpMultiplier.get()));
|
||||||
PlayerStatsProvider.sync(player);
|
PlayerStatsProvider.sync(player);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -118,7 +117,7 @@ public class ActivityEvents {
|
|||||||
Player player = event.getEntity();
|
Player player = event.getEntity();
|
||||||
if (player.level().isClientSide) return;
|
if (player.level().isClientSide) return;
|
||||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||||
stats.addAscendXP(2);
|
stats.addAscendXP((int) (AscendConfig.COMMON.xpPerSmelt.get() * AscendConfig.COMMON.xpMultiplier.get()));
|
||||||
PlayerStatsProvider.sync(player);
|
PlayerStatsProvider.sync(player);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -151,7 +150,7 @@ public class ActivityEvents {
|
|||||||
Player player = event.getEntity();
|
Player player = event.getEntity();
|
||||||
if (player.level().isClientSide) return;
|
if (player.level().isClientSide) return;
|
||||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||||
stats.addAscendXP(5);
|
stats.addAscendXP((int) (AscendConfig.COMMON.xpPerTrade.get() * AscendConfig.COMMON.xpMultiplier.get()));
|
||||||
PlayerStatsProvider.sync(player);
|
PlayerStatsProvider.sync(player);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -178,7 +177,7 @@ public class ActivityEvents {
|
|||||||
if (player.level().isClientSide) return;
|
if (player.level().isClientSide) return;
|
||||||
if (event.getItemStack().getItem().getDescriptionId().contains("potion")) {
|
if (event.getItemStack().getItem().getDescriptionId().contains("potion")) {
|
||||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||||
stats.addAscendXP(3);
|
stats.addAscendXP((int) (AscendConfig.COMMON.xpPerPotion.get() * AscendConfig.COMMON.xpMultiplier.get()));
|
||||||
PlayerStatsProvider.sync(player);
|
PlayerStatsProvider.sync(player);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,17 +26,16 @@ public class PlayerEvents {
|
|||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onPlayerClone(PlayerEvent.Clone event) {
|
public static void onPlayerClone(PlayerEvent.Clone event) {
|
||||||
if (!event.isWasDeath()) return;
|
|
||||||
event.getOriginal().reviveCaps();
|
event.getOriginal().reviveCaps();
|
||||||
event.getOriginal().getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(oldStats ->
|
event.getOriginal().getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(oldStats ->
|
||||||
event.getEntity().getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(newStats -> {
|
event.getEntity().getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(newStats -> {
|
||||||
newStats.deserializeNBT(oldStats.serializeNBT());
|
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
|
@SubscribeEvent
|
||||||
@@ -46,5 +45,4 @@ public class PlayerEvents {
|
|||||||
StatEffects.applyAll(event.getEntity());
|
StatEffects.applyAll(event.getEntity());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package net.fretux.ascend.event;
|
package net.fretux.ascend.event;
|
||||||
|
|
||||||
import net.fretux.ascend.AscendMod;
|
import net.fretux.ascend.AscendMod;
|
||||||
|
import net.fretux.ascend.config.AscendConfig;
|
||||||
import net.fretux.ascend.player.PlayerStatsProvider;
|
import net.fretux.ascend.player.PlayerStatsProvider;
|
||||||
import net.minecraft.world.damagesource.DamageSource;
|
import net.minecraft.world.damagesource.DamageSource;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
@@ -11,6 +12,7 @@ import net.minecraftforge.fml.common.Mod;
|
|||||||
|
|
||||||
@Mod.EventBusSubscriber(modid = AscendMod.MODID)
|
@Mod.EventBusSubscriber(modid = AscendMod.MODID)
|
||||||
public class WeaponMagicScalingEvents {
|
public class WeaponMagicScalingEvents {
|
||||||
|
static double scale = AscendConfig.COMMON.attributeScalingMultiplier.get();
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onLivingHurt(LivingHurtEvent event) {
|
public static void onLivingHurt(LivingHurtEvent event) {
|
||||||
@@ -25,7 +27,7 @@ public class WeaponMagicScalingEvents {
|
|||||||
if (magicScaling > 0) {
|
if (magicScaling > 0) {
|
||||||
double perPoint = 0.005d;
|
double perPoint = 0.005d;
|
||||||
double maxBonus = 0.40d;
|
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);
|
modified = (float) (modified * bonusMult);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -33,12 +35,10 @@ public class WeaponMagicScalingEvents {
|
|||||||
if (player.getAttribute(Attributes.ATTACK_SPEED) != null) {
|
if (player.getAttribute(Attributes.ATTACK_SPEED) != null) {
|
||||||
attackSpeed = player.getAttribute(Attributes.ATTACK_SPEED).getValue();
|
attackSpeed = player.getAttribute(Attributes.ATTACK_SPEED).getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
String key =
|
String key =
|
||||||
(attackSpeed >= 1.8d) ? "light_scaling" :
|
(attackSpeed >= 1.8d) ? "light_scaling" :
|
||||||
(attackSpeed >= 1.2d) ? "medium_scaling" :
|
(attackSpeed >= 1.2d) ? "medium_scaling" :
|
||||||
"heavy_scaling";
|
"heavy_scaling";
|
||||||
|
|
||||||
int level = stats.getAttributeLevel(key);
|
int level = stats.getAttributeLevel(key);
|
||||||
if (level > 0) {
|
if (level > 0) {
|
||||||
double perPoint =
|
double perPoint =
|
||||||
@@ -46,7 +46,7 @@ public class WeaponMagicScalingEvents {
|
|||||||
key.equals("medium_scaling") ? 0.004d :
|
key.equals("medium_scaling") ? 0.004d :
|
||||||
0.005d;
|
0.005d;
|
||||||
double maxBonus = 0.40d;
|
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);
|
modified = (float) (modified * bonusMult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package net.fretux.ascend.network;
|
|||||||
|
|
||||||
import net.fretux.ascend.player.PlayerStats;
|
import net.fretux.ascend.player.PlayerStats;
|
||||||
import net.fretux.ascend.player.PlayerStatsProvider;
|
import net.fretux.ascend.player.PlayerStatsProvider;
|
||||||
|
import net.fretux.ascend.player.StatEffects;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
@@ -12,9 +13,17 @@ import java.util.function.Supplier;
|
|||||||
public class ClientboundSyncStatsPacket {
|
public class ClientboundSyncStatsPacket {
|
||||||
private final CompoundTag data;
|
private final CompoundTag data;
|
||||||
|
|
||||||
public ClientboundSyncStatsPacket(CompoundTag data) { this.data = data; }
|
public ClientboundSyncStatsPacket(CompoundTag data) {
|
||||||
public ClientboundSyncStatsPacket(FriendlyByteBuf buf) { this.data = buf.readNbt(); }
|
this.data = data;
|
||||||
public void toBytes(FriendlyByteBuf buf) { buf.writeNbt(data); }
|
}
|
||||||
|
|
||||||
|
public ClientboundSyncStatsPacket(FriendlyByteBuf buf) {
|
||||||
|
this.data = buf.readNbt();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toBytes(FriendlyByteBuf buf) {
|
||||||
|
buf.writeNbt(data);
|
||||||
|
}
|
||||||
|
|
||||||
public void handle(Supplier<NetworkEvent.Context> ctx) {
|
public void handle(Supplier<NetworkEvent.Context> ctx) {
|
||||||
System.out.println("[SERVER] Spend packet handle() called");
|
System.out.println("[SERVER] Spend packet handle() called");
|
||||||
@@ -22,7 +31,9 @@ public class ClientboundSyncStatsPacket {
|
|||||||
Minecraft mc = Minecraft.getInstance();
|
Minecraft mc = Minecraft.getInstance();
|
||||||
var player = mc.player;
|
var player = mc.player;
|
||||||
if (player != null) {
|
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);
|
stats.deserializeNBT(data);
|
||||||
System.out.println("[CLIENT] Before sync: points="
|
System.out.println("[CLIENT] Before sync: points="
|
||||||
+ player.getCapability(PlayerStatsProvider.PLAYER_STATS)
|
+ player.getCapability(PlayerStatsProvider.PLAYER_STATS)
|
||||||
@@ -31,10 +42,9 @@ public class ClientboundSyncStatsPacket {
|
|||||||
System.out.println("[CLIENT] After sync: points="
|
System.out.println("[CLIENT] After sync: points="
|
||||||
+ player.getCapability(PlayerStatsProvider.PLAYER_STATS)
|
+ player.getCapability(PlayerStatsProvider.PLAYER_STATS)
|
||||||
.map(PlayerStats::getUnspentPoints).orElse(-1));
|
.map(PlayerStats::getUnspentPoints).orElse(-1));
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
ctx.get().setPacketHandled(true);
|
||||||
});
|
});
|
||||||
ctx.get().setPacketHandled(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package net.fretux.ascend.network;
|
package net.fretux.ascend.network;
|
||||||
|
|
||||||
|
import net.fretux.ascend.player.PlayerStatsProvider;
|
||||||
import net.fretux.ascend.player.StatEffects;
|
import net.fretux.ascend.player.StatEffects;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraftforge.network.NetworkEvent;
|
import net.minecraftforge.network.NetworkEvent;
|
||||||
import net.fretux.ascend.player.PlayerStatsProvider;
|
|
||||||
import net.minecraftforge.network.PacketDistributor;
|
import net.minecraftforge.network.PacketDistributor;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
|
||||||
@@ -31,9 +31,6 @@ public class ServerboundSpendPointPacket {
|
|||||||
context.enqueueWork(() -> {
|
context.enqueueWork(() -> {
|
||||||
ServerPlayer player = context.getSender();
|
ServerPlayer player = context.getSender();
|
||||||
if (player == null) return;
|
if (player == null) return;
|
||||||
|
|
||||||
System.out.println("[Ascend] Received spend packet '" + attribute + "' from " + player.getGameProfile().getName());
|
|
||||||
|
|
||||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||||
boolean success = stats.spendPoints(attribute);
|
boolean success = stats.spendPoints(attribute);
|
||||||
if (success) {
|
if (success) {
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
package net.fretux.ascend.player;
|
package net.fretux.ascend.player;
|
||||||
|
|
||||||
|
import net.fretux.ascend.config.AscendConfig;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class PlayerStats {
|
public class PlayerStats {
|
||||||
public static final int MAX_ASCEND_LEVEL = 20;
|
public static final int POINTS_PER_LEVEL = AscendConfig.COMMON.pointsPerLevel.get();
|
||||||
public static final int POINTS_PER_LEVEL = 15;
|
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 final Map<String, Integer> attributes = new HashMap<>();
|
||||||
private int ascendLevel = 1;
|
private int ascendLevel = 1;
|
||||||
private int ascendXP = 0;
|
private int ascendXP = 0;
|
||||||
private int unspentPoints = POINTS_PER_LEVEL;
|
private int unspentPoints = POINTS_PER_LEVEL;
|
||||||
public static final int MAX_ATTRIBUTE_POINTS = 100;
|
|
||||||
public PlayerStats() {
|
public PlayerStats() {
|
||||||
for (String attr : new String[]{
|
for (String attr : new String[]{
|
||||||
"strength", "agility", "fortitude", "intelligence",
|
"strength", "agility", "fortitude", "intelligence",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package net.fretux.ascend.player;
|
package net.fretux.ascend.player;
|
||||||
|
|
||||||
import net.fretux.ascend.compat.IronsSpellbooksCompat;
|
import net.fretux.ascend.compat.IronsSpellbooksCompat;
|
||||||
|
import net.fretux.ascend.config.AscendConfig;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
|
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
|
||||||
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
|
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 java.util.UUID;
|
||||||
|
|
||||||
import static net.fretux.ascend.compat.IronsSpellbooksCompat.applyCharisma;
|
|
||||||
import static net.fretux.ascend.compat.IronsSpellbooksCompat.applyIntelligence;
|
|
||||||
|
|
||||||
public final class StatEffects {
|
public final class StatEffects {
|
||||||
|
|
||||||
private static final UUID STRENGTH_DAMAGE_UUID =
|
private static final UUID STRENGTH_DAMAGE_UUID =
|
||||||
@@ -28,6 +26,8 @@ public final class StatEffects {
|
|||||||
|
|
||||||
private StatEffects() {}
|
private StatEffects() {}
|
||||||
|
|
||||||
|
static double scale = AscendConfig.COMMON.attributeScalingMultiplier.get();
|
||||||
|
|
||||||
public static void applyAll(Player player) {
|
public static void applyAll(Player player) {
|
||||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||||
applyStrength(player, stats.getAttributeLevel("strength"));
|
applyStrength(player, stats.getAttributeLevel("strength"));
|
||||||
@@ -40,19 +40,13 @@ 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) {
|
public static void applyStrength(Player player, int strengthLevel) {
|
||||||
// Damage
|
// Damage
|
||||||
AttributeInstance atk = player.getAttribute(Attributes.ATTACK_DAMAGE);
|
AttributeInstance atk = player.getAttribute(Attributes.ATTACK_DAMAGE);
|
||||||
if (atk != null) {
|
if (atk != null) {
|
||||||
atk.removeModifier(STRENGTH_DAMAGE_UUID);
|
atk.removeModifier(STRENGTH_DAMAGE_UUID);
|
||||||
if (strengthLevel > 0) {
|
if (strengthLevel > 0) {
|
||||||
double dmgBonus = strengthLevel * 0.1d;
|
double dmgBonus = strengthLevel * 0.1d * scale;
|
||||||
atk.addTransientModifier(new AttributeModifier(
|
atk.addTransientModifier(new AttributeModifier(
|
||||||
STRENGTH_DAMAGE_UUID,
|
STRENGTH_DAMAGE_UUID,
|
||||||
"Ascend Strength damage bonus",
|
"Ascend Strength damage bonus",
|
||||||
@@ -67,7 +61,7 @@ public final class StatEffects {
|
|||||||
if (kb != null) {
|
if (kb != null) {
|
||||||
kb.removeModifier(STRENGTH_KNOCKBACK_UUID);
|
kb.removeModifier(STRENGTH_KNOCKBACK_UUID);
|
||||||
if (strengthLevel > 0) {
|
if (strengthLevel > 0) {
|
||||||
double kbBonus = strengthLevel * 0.03d;
|
double kbBonus = strengthLevel * 0.03d * scale;
|
||||||
kb.addTransientModifier(new AttributeModifier(
|
kb.addTransientModifier(new AttributeModifier(
|
||||||
STRENGTH_KNOCKBACK_UUID,
|
STRENGTH_KNOCKBACK_UUID,
|
||||||
"Ascend Strength knockback bonus",
|
"Ascend Strength knockback bonus",
|
||||||
@@ -78,18 +72,12 @@ 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) {
|
public static void applyAgility(Player player, int agilityLevel) {
|
||||||
AttributeInstance move = player.getAttribute(Attributes.MOVEMENT_SPEED);
|
AttributeInstance move = player.getAttribute(Attributes.MOVEMENT_SPEED);
|
||||||
if (move != null) {
|
if (move != null) {
|
||||||
move.removeModifier(AGILITY_SPEED_UUID);
|
move.removeModifier(AGILITY_SPEED_UUID);
|
||||||
if (agilityLevel > 0) {
|
if (agilityLevel > 0) {
|
||||||
// Example: +0.002 per point = +0.2 at 100 (about +20% on base 0.1)
|
double bonus = agilityLevel * 0.002d * scale;
|
||||||
double bonus = agilityLevel * 0.002d;
|
|
||||||
move.addTransientModifier(new AttributeModifier(
|
move.addTransientModifier(new AttributeModifier(
|
||||||
AGILITY_SPEED_UUID,
|
AGILITY_SPEED_UUID,
|
||||||
"Ascend Agility speed bonus",
|
"Ascend Agility speed bonus",
|
||||||
@@ -100,20 +88,12 @@ 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) {
|
public static void applyFortitude(Player player, int fortitudeLevel) {
|
||||||
// Max health
|
|
||||||
AttributeInstance hp = player.getAttribute(Attributes.MAX_HEALTH);
|
AttributeInstance hp = player.getAttribute(Attributes.MAX_HEALTH);
|
||||||
if (hp != null) {
|
if (hp != null) {
|
||||||
hp.removeModifier(FORTITUDE_HEALTH_UUID);
|
hp.removeModifier(FORTITUDE_HEALTH_UUID);
|
||||||
if (fortitudeLevel > 0) {
|
if (fortitudeLevel > 0) {
|
||||||
// Example: 0.25 HP (1/8 heart) per point = +12.5 hearts at 100
|
double healthBonus = fortitudeLevel * 0.25d * scale;
|
||||||
double healthBonus = fortitudeLevel * 0.25d;
|
|
||||||
hp.addTransientModifier(new AttributeModifier(
|
hp.addTransientModifier(new AttributeModifier(
|
||||||
FORTITUDE_HEALTH_UUID,
|
FORTITUDE_HEALTH_UUID,
|
||||||
"Ascend Fortitude health bonus",
|
"Ascend Fortitude health bonus",
|
||||||
@@ -122,14 +102,11 @@ public final class StatEffects {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Knockback resistance
|
|
||||||
AttributeInstance kbRes = player.getAttribute(Attributes.KNOCKBACK_RESISTANCE);
|
AttributeInstance kbRes = player.getAttribute(Attributes.KNOCKBACK_RESISTANCE);
|
||||||
if (kbRes != null) {
|
if (kbRes != null) {
|
||||||
kbRes.removeModifier(FORTITUDE_KB_RESIST_UUID);
|
kbRes.removeModifier(FORTITUDE_KB_RESIST_UUID);
|
||||||
if (fortitudeLevel > 0) {
|
if (fortitudeLevel > 0) {
|
||||||
// Tiny scaling; cap at 60% here
|
double res = Math.min(0.006d * fortitudeLevel * scale, 0.60d);
|
||||||
double res = Math.min(0.006d * fortitudeLevel, 0.60d);
|
|
||||||
kbRes.addTransientModifier(new AttributeModifier(
|
kbRes.addTransientModifier(new AttributeModifier(
|
||||||
FORTITUDE_KB_RESIST_UUID,
|
FORTITUDE_KB_RESIST_UUID,
|
||||||
"Ascend Fortitude knockback resist",
|
"Ascend Fortitude knockback resist",
|
||||||
@@ -140,74 +117,39 @@ 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) {
|
public static float getWillpowerSanityMultiplier(int willpowerLevel) {
|
||||||
if (willpowerLevel <= 0) return 1.0f;
|
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);
|
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) {
|
public static float getWillpowerTempoMultiplier(int willpowerLevel) {
|
||||||
if (willpowerLevel <= 0) return 1.0f;
|
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);
|
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)
|
return player.getCapability(PlayerStatsProvider.PLAYER_STATS)
|
||||||
.map(stats -> getWillpowerSanityMultiplier(stats.getAttributeLevel("willpower")))
|
.map(stats -> getWillpowerSanityMultiplier(stats.getAttributeLevel("willpower")))
|
||||||
.orElse(1.0f);
|
.orElse(1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Convenience: from player capability → tempo multiplier. */
|
|
||||||
public static float getPlayerTempoMultiplier(Player player) {
|
public static float getPlayerTempoMultiplier(Player player) {
|
||||||
return player.getCapability(PlayerStatsProvider.PLAYER_STATS)
|
return player.getCapability(PlayerStatsProvider.PLAYER_STATS)
|
||||||
.map(stats -> getWillpowerTempoMultiplier(stats.getAttributeLevel("willpower")))
|
.map(stats -> getWillpowerTempoMultiplier(stats.getAttributeLevel("willpower")))
|
||||||
.orElse(1.0f);
|
.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) {
|
public static int getIntelligenceManaBonus(int intelligenceLevel) {
|
||||||
return Math.max(0, 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) {
|
public static double getCharismaTradeDiscount(int charismaLevel) {
|
||||||
if (charismaLevel <= 0) return 0.0d;
|
if (charismaLevel <= 0) return 0.0d;
|
||||||
double perPoint = 0.01d;
|
double perPoint = 0.01d;
|
||||||
double max = 0.30d;
|
double max = 0.30d;
|
||||||
return Math.min(charismaLevel * perPoint, max);
|
return Math.min(charismaLevel * perPoint * scale, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double getWeaponScalingMultiplier(int scalingLevel) {
|
public static double getWeaponScalingMultiplier(int scalingLevel) {
|
||||||
|
|||||||
Reference in New Issue
Block a user