Implement changes to leveling
This commit is contained in:
@@ -1,12 +1,7 @@
|
|||||||
package net.fretux.ascend;
|
package net.fretux.ascend;
|
||||||
|
|
||||||
import net.fretux.ascend.command.StatsCommand;
|
|
||||||
import net.fretux.ascend.event.ActivityEvents;
|
|
||||||
import net.fretux.ascend.event.PlayerEvents;
|
|
||||||
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.event.RegisterCommandsEvent;
|
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
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;
|
||||||
@@ -30,11 +25,4 @@ public class AscendMod {
|
|||||||
System.out.println("[Ascend] Registering packets... Side=" + FMLEnvironment.dist);
|
System.out.println("[Ascend] Registering packets... Side=" + FMLEnvironment.dist);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ✅ Directly subscribe in this mod class instead of inner static
|
|
||||||
@SubscribeEvent
|
|
||||||
public void onRegisterCommands(RegisterCommandsEvent event) {
|
|
||||||
StatsCommand.register(event.getDispatcher());
|
|
||||||
System.out.println("[Ascend] Registered /stats command on side=" + FMLEnvironment.dist);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,6 @@ package net.fretux.ascend.client.screen;
|
|||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import net.fretux.ascend.network.PacketHandler;
|
import net.fretux.ascend.network.PacketHandler;
|
||||||
import net.fretux.ascend.network.ServerboundSpendPointPacket;
|
import net.fretux.ascend.network.ServerboundSpendPointPacket;
|
||||||
import net.fretux.ascend.player.PlayerStats;
|
|
||||||
import net.fretux.ascend.player.PlayerStatsProvider;
|
import net.fretux.ascend.player.PlayerStatsProvider;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
@@ -17,7 +16,7 @@ import java.util.Map;
|
|||||||
public class StatsScreen extends Screen {
|
public class StatsScreen extends Screen {
|
||||||
|
|
||||||
private static final int WIDTH = 220;
|
private static final int WIDTH = 220;
|
||||||
private static final int HEIGHT = 210;
|
private static final int HEIGHT = 240;
|
||||||
|
|
||||||
private int leftPos;
|
private int leftPos;
|
||||||
private int topPos;
|
private int topPos;
|
||||||
@@ -30,7 +29,6 @@ public class StatsScreen extends Screen {
|
|||||||
"light_scaling", "medium_scaling", "heavy_scaling", "magic_scaling"
|
"light_scaling", "medium_scaling", "heavy_scaling", "magic_scaling"
|
||||||
};
|
};
|
||||||
|
|
||||||
// Track plus buttons so we can update enabled state & labels based on current stats
|
|
||||||
private final Map<String, Button> plusButtons = new HashMap<>();
|
private final Map<String, Button> plusButtons = new HashMap<>();
|
||||||
|
|
||||||
public StatsScreen() {
|
public StatsScreen() {
|
||||||
@@ -40,32 +38,22 @@ public class StatsScreen extends Screen {
|
|||||||
@Override
|
@Override
|
||||||
protected void init() {
|
protected void init() {
|
||||||
super.init();
|
super.init();
|
||||||
|
|
||||||
this.leftPos = (this.width - WIDTH) / 2;
|
this.leftPos = (this.width - WIDTH) / 2;
|
||||||
this.topPos = (this.height - HEIGHT) / 2;
|
this.topPos = (this.height - HEIGHT) / 2;
|
||||||
|
|
||||||
this.plusButtons.clear();
|
this.plusButtons.clear();
|
||||||
this.clearWidgets();
|
this.clearWidgets();
|
||||||
|
|
||||||
// Create + buttons for each attribute
|
|
||||||
int y = topPos + 55;
|
int y = topPos + 55;
|
||||||
for (String attr : ATTRIBUTES) {
|
for (String attr : ATTRIBUTES) {
|
||||||
final String key = attr;
|
final String key = attr;
|
||||||
|
|
||||||
Button plus = Button.builder(Component.literal("+"), (button) -> {
|
Button plus = Button.builder(Component.literal("+"), (button) -> {
|
||||||
// Send spend request to server for this attribute
|
|
||||||
PacketHandler.INSTANCE.sendToServer(new ServerboundSpendPointPacket(key));
|
PacketHandler.INSTANCE.sendToServer(new ServerboundSpendPointPacket(key));
|
||||||
})
|
})
|
||||||
.bounds(leftPos + WIDTH - 40, y - 6, 30, 18)
|
.bounds(leftPos + WIDTH - 40, y - 6, 30, 18)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
this.addRenderableWidget(plus);
|
this.addRenderableWidget(plus);
|
||||||
this.plusButtons.put(key, plus);
|
this.plusButtons.put(key, plus);
|
||||||
|
|
||||||
y += 16;
|
y += 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Done/close button
|
|
||||||
Button done = Button.builder(Component.translatable("gui.done"), (btn) -> onClose())
|
Button done = Button.builder(Component.translatable("gui.done"), (btn) -> onClose())
|
||||||
.bounds(leftPos + WIDTH / 2 - 40, topPos + HEIGHT - 24, 80, 20)
|
.bounds(leftPos + WIDTH / 2 - 40, topPos + HEIGHT - 24, 80, 20)
|
||||||
.build();
|
.build();
|
||||||
@@ -75,73 +63,43 @@ public class StatsScreen extends Screen {
|
|||||||
@Override
|
@Override
|
||||||
public void render(GuiGraphics gui, int mouseX, int mouseY, float partialTicks) {
|
public void render(GuiGraphics gui, int mouseX, int mouseY, float partialTicks) {
|
||||||
this.renderBackground(gui);
|
this.renderBackground(gui);
|
||||||
|
|
||||||
// Panel background (simple rectangle; swap to texture if you have one)
|
|
||||||
RenderSystem.enableBlend();
|
RenderSystem.enableBlend();
|
||||||
gui.fill(leftPos - 4, topPos - 4, leftPos + WIDTH + 4, topPos + HEIGHT + 4, 0xAA000000);
|
gui.fill(leftPos - 4, topPos - 4, leftPos + WIDTH + 4, topPos + HEIGHT + 4, 0xAA000000);
|
||||||
RenderSystem.disableBlend();
|
RenderSystem.disableBlend();
|
||||||
|
|
||||||
// Title
|
|
||||||
gui.drawCenteredString(this.font, this.title, this.width / 2, topPos + 8, 0xFFFFFF);
|
gui.drawCenteredString(this.font, this.title, this.width / 2, topPos + 8, 0xFFFFFF);
|
||||||
|
|
||||||
if (mc.player != null) {
|
if (mc.player != null) {
|
||||||
mc.player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
mc.player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||||
// ==== Top Info: Level, XP, Points ====
|
int level = stats.getAscendLevel();
|
||||||
int level = stats.getLevel();
|
|
||||||
int xp = stats.getAscendXP();
|
int xp = stats.getAscendXP();
|
||||||
int xpNext = stats.getXPForNextLevel(); // 0 if max
|
int xpNext = stats.getXPToNextAscendLevel();
|
||||||
int unspent = stats.getUnspentPoints();
|
int unspent = stats.getUnspentPoints();
|
||||||
|
|
||||||
// Level
|
|
||||||
String levelStr = "Level: " + level + "/" + 20;
|
String levelStr = "Level: " + level + "/" + 20;
|
||||||
gui.drawString(font, levelStr, leftPos + 10, topPos + 24, 0xFFFF55);
|
gui.drawString(font, levelStr, leftPos + 10, topPos + 24, 0xFFFF55);
|
||||||
|
|
||||||
// Ascend XP
|
|
||||||
if (level < 20) {
|
if (level < 20) {
|
||||||
String xpStr = "Ascend XP: " + xp + " / " + xpNext;
|
String xpStr = "Ascend XP: " + xp + " / " + xpNext;
|
||||||
gui.drawString(font, xpStr, leftPos + 10, topPos + 36, 0xAAAAAA);
|
gui.drawString(font, xpStr, leftPos + 10, topPos + 36, 0xAAAAAA);
|
||||||
} else {
|
} else {
|
||||||
gui.drawString(font, "Ascend XP: MAX", leftPos + 10, topPos + 36, 0xAAAAAA);
|
gui.drawString(font, "Ascend XP: MAX", leftPos + 10, topPos + 36, 0xAAAAAA);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unspent points (right aligned)
|
|
||||||
String ptsStr = "Unspent Points: " + unspent;
|
String ptsStr = "Unspent Points: " + unspent;
|
||||||
int ptsWidth = font.width(ptsStr);
|
int ptsWidth = font.width(ptsStr);
|
||||||
gui.drawString(font, ptsStr,
|
gui.drawString(font, ptsStr,
|
||||||
leftPos + WIDTH - 10 - ptsWidth, topPos + 24, 0x55FF55);
|
leftPos + WIDTH - 10 - ptsWidth, topPos + 24, 0x55FF55);
|
||||||
|
|
||||||
// ==== Attributes List ====
|
|
||||||
int y = topPos + 55;
|
int y = topPos + 55;
|
||||||
for (String key : ATTRIBUTES) {
|
for (String key : ATTRIBUTES) {
|
||||||
int attrLevel = stats.getAttributeLevel(key);
|
int attrLevel = stats.getAttributeLevel(key);
|
||||||
int sourceXP = stats.getXP(key); // per-activity XP, just for feedback
|
int sourceXP = stats.getAscendXP();
|
||||||
int cost = stats.getCostToUpgrade(key);
|
int cost = stats.getCostToUpgrade(key);
|
||||||
|
|
||||||
String niceName = formatAttributeName(key);
|
String niceName = formatAttributeName(key);
|
||||||
|
|
||||||
// Attribute name + level
|
|
||||||
gui.drawString(font,
|
gui.drawString(font,
|
||||||
niceName + ": " + attrLevel,
|
niceName + ": " + attrLevel,
|
||||||
leftPos + 10, y,
|
leftPos + 10, y,
|
||||||
0xFFFFFF);
|
0xFFFFFF);
|
||||||
|
|
||||||
// XP (source-based)
|
|
||||||
gui.drawString(font,
|
|
||||||
"XP: " + sourceXP,
|
|
||||||
leftPos + 110, y,
|
|
||||||
0x777777);
|
|
||||||
|
|
||||||
// Update + button (position, text, enabled)
|
|
||||||
Button plus = plusButtons.get(key);
|
Button plus = plusButtons.get(key);
|
||||||
if (plus != null) {
|
if (plus != null) {
|
||||||
plus.setX(leftPos + WIDTH - 40);
|
plus.setX(leftPos + WIDTH - 40);
|
||||||
plus.setY(y - 6);
|
plus.setY(y - 6);
|
||||||
|
|
||||||
// Always visible, but only active if enough points
|
|
||||||
plus.active = (unspent >= cost);
|
plus.active = (unspent >= cost);
|
||||||
|
|
||||||
// Show cost inside button
|
|
||||||
// Keep it short; if too long for your font, switch to just "+"
|
|
||||||
plus.setMessage(Component.literal("+" + cost));
|
plus.setMessage(Component.literal("+" + cost));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
package net.fretux.ascend.command;
|
|
||||||
|
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
|
||||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
|
||||||
import net.fretux.ascend.player.PlayerStatsProvider;
|
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
|
||||||
import net.minecraft.commands.Commands;
|
|
||||||
import net.minecraft.network.chat.Component;
|
|
||||||
|
|
||||||
public class StatsCommand {
|
|
||||||
|
|
||||||
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
|
|
||||||
dispatcher.register(Commands.literal("stats")
|
|
||||||
.then(Commands.literal("show")
|
|
||||||
.executes(ctx -> {
|
|
||||||
var player = ctx.getSource().getPlayerOrException();
|
|
||||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
|
||||||
player.sendSystemMessage(Component.literal("Unspent points: " + stats.getUnspentPoints()));
|
|
||||||
for (String key : stats.serializeNBT().getCompound("Attributes").getAllKeys()) {
|
|
||||||
int lvl = stats.getAttributeLevel(key);
|
|
||||||
int xp = stats.getXP(key);
|
|
||||||
int needed = stats.getXPToNextLevel(key);
|
|
||||||
player.sendSystemMessage(Component.literal(
|
|
||||||
key + " → Lvl " + lvl + " | XP: " + xp + "/" + needed
|
|
||||||
));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return 1;
|
|
||||||
}))
|
|
||||||
.then(Commands.literal("spend")
|
|
||||||
.then(Commands.argument("attribute", StringArgumentType.string())
|
|
||||||
.executes(ctx -> {
|
|
||||||
var player = ctx.getSource().getPlayerOrException();
|
|
||||||
String attr = StringArgumentType.getString(ctx, "attribute");
|
|
||||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
|
||||||
int cost = stats.getXPToNextLevel(attr);
|
|
||||||
boolean success = stats.spendPoints(attr);
|
|
||||||
if (success) {
|
|
||||||
player.sendSystemMessage(Component.literal("You invested a point in " + attr + "!"));
|
|
||||||
} else {
|
|
||||||
player.sendSystemMessage(Component.literal("Not enough points to upgrade " + attr + "."));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return 1;
|
|
||||||
})))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -27,10 +27,10 @@ public class ActivityEvents {
|
|||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
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.addXP("strength", 5)
|
stats.addAscendXP(5);
|
||||||
);
|
|
||||||
PlayerStatsProvider.sync(player);
|
PlayerStatsProvider.sync(player);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,12 +38,13 @@ 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.addXP("strength", 2);
|
stats.addAscendXP(2);
|
||||||
System.out.println("Added 2 strength XP");
|
|
||||||
PlayerStatsProvider.sync(player);
|
PlayerStatsProvider.sync(player);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -52,11 +53,11 @@ public class ActivityEvents {
|
|||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onPlayerDamaged(LivingHurtEvent event) {
|
public static void onPlayerDamaged(LivingHurtEvent event) {
|
||||||
if (event.getEntity() instanceof Player player && !player.level().isClientSide) {
|
if (event.getEntity() instanceof Player player && !player.level().isClientSide) {
|
||||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats ->
|
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||||
stats.addXP("fortitude", Math.min((int) event.getAmount() * 2, 10))
|
int gain = Math.min((int) event.getAmount() * 2, 10);
|
||||||
);
|
stats.addAscendXP(gain);
|
||||||
PlayerStatsProvider.sync(player);
|
PlayerStatsProvider.sync(player);
|
||||||
System.out.println("Added " + event.getAmount() * 2 + " fortitude XP");
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,16 +65,16 @@ public class ActivityEvents {
|
|||||||
public static void onPlayerTickFortitude(TickEvent.PlayerTickEvent event) {
|
public static void onPlayerTickFortitude(TickEvent.PlayerTickEvent event) {
|
||||||
Player player = event.player;
|
Player player = event.player;
|
||||||
if (player.level().isClientSide || event.phase != TickEvent.Phase.END) return;
|
if (player.level().isClientSide || event.phase != TickEvent.Phase.END) return;
|
||||||
|
|
||||||
fortitudeTickCounter++;
|
fortitudeTickCounter++;
|
||||||
if (fortitudeTickCounter % 100 == 0) {
|
if (fortitudeTickCounter % 100 == 0) {
|
||||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||||
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.addXP("fortitude", 2);
|
stats.addAscendXP(2);
|
||||||
PlayerStatsProvider.sync(player);
|
PlayerStatsProvider.sync(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,13 +84,17 @@ public class ActivityEvents {
|
|||||||
Player player = event.player;
|
Player player = event.player;
|
||||||
if (player.level().isClientSide || event.phase != TickEvent.Phase.END) return;
|
if (player.level().isClientSide || event.phase != TickEvent.Phase.END) return;
|
||||||
agilityTickCounter++;
|
agilityTickCounter++;
|
||||||
if (agilityTickCounter % 20 != 0) return;
|
if (agilityTickCounter % 40 != 0) return;
|
||||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||||
if (player.isSprinting()) stats.addXP("agility", 2);
|
boolean didAgileThing =
|
||||||
if (player.isCrouching()) stats.addXP("agility", 1);
|
player.isSprinting()
|
||||||
if (Math.abs(player.getDeltaMovement().y) > 0.25) stats.addXP("agility", 1);
|
|| player.isCrouching()
|
||||||
if (player.onClimbable()) stats.addXP("agility", 1);
|
|| Math.abs(player.getDeltaMovement().y) > 0.25
|
||||||
|
|| player.onClimbable();
|
||||||
|
if (didAgileThing) {
|
||||||
|
stats.addAscendXP(1);
|
||||||
PlayerStatsProvider.sync(player);
|
PlayerStatsProvider.sync(player);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +103,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.addXP("intelligence", 3);
|
stats.addAscendXP(3);
|
||||||
PlayerStatsProvider.sync(player);
|
PlayerStatsProvider.sync(player);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -108,7 +113,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.addXP("intelligence", 2);
|
stats.addAscendXP(2);
|
||||||
PlayerStatsProvider.sync(player);
|
PlayerStatsProvider.sync(player);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -118,24 +123,22 @@ public class ActivityEvents {
|
|||||||
Player player = event.player;
|
Player player = event.player;
|
||||||
if (player.level().isClientSide || event.phase != TickEvent.Phase.END) return;
|
if (player.level().isClientSide || event.phase != TickEvent.Phase.END) return;
|
||||||
willpowerTickCounter++;
|
willpowerTickCounter++;
|
||||||
if (willpowerTickCounter % 100 == 0) { // every 5s
|
if (willpowerTickCounter % 200 != 0) return;
|
||||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||||
// XP for surviving under pressure
|
|
||||||
boolean hasNegativeEffect = player.getActiveEffects().stream()
|
boolean hasNegativeEffect = player.getActiveEffects().stream()
|
||||||
.anyMatch(e -> e.getEffect().getCategory() == MobEffectCategory.HARMFUL);
|
.anyMatch(e -> e.getEffect().getCategory() == MobEffectCategory.HARMFUL);
|
||||||
boolean lowHealth = player.getHealth() <= player.getMaxHealth() * 0.25f;
|
boolean lowHealth = player.getHealth() <= player.getMaxHealth() * 0.25f;
|
||||||
|
|
||||||
// Check darkness
|
|
||||||
BlockPos pos = player.blockPosition();
|
BlockPos pos = player.blockPosition();
|
||||||
int light = player.level().getBrightness(LightLayer.BLOCK, pos);
|
int blockLight = player.level().getBrightness(LightLayer.BLOCK, pos);
|
||||||
|
int skyLight = player.level().getBrightness(LightLayer.SKY, pos);
|
||||||
if (hasNegativeEffect || lowHealth || light < 4) {
|
int light = Math.max(blockLight, skyLight);
|
||||||
stats.addXP("willpower", 2);
|
boolean inDarkness = light <= 3;
|
||||||
|
if (lowHealth || (hasNegativeEffect && inDarkness)) {
|
||||||
|
stats.addAscendXP(1);
|
||||||
PlayerStatsProvider.sync(player);
|
PlayerStatsProvider.sync(player);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onVillagerTrade(PlayerInteractEvent.EntityInteract event) {
|
public static void onVillagerTrade(PlayerInteractEvent.EntityInteract event) {
|
||||||
@@ -143,7 +146,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.addXP("charisma", 5);
|
stats.addAscendXP(5);
|
||||||
PlayerStatsProvider.sync(player);
|
PlayerStatsProvider.sync(player);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -153,20 +156,13 @@ public class ActivityEvents {
|
|||||||
if (!(event.getSource().getEntity() instanceof Player player)) return;
|
if (!(event.getSource().getEntity() instanceof Player player)) return;
|
||||||
if (player.level().isClientSide) return;
|
if (player.level().isClientSide) return;
|
||||||
if (event.getEntity() == player) return;
|
if (event.getEntity() == player) return;
|
||||||
|
|
||||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||||
var heldItem = player.getMainHandItem();
|
var heldItem = player.getMainHandItem();
|
||||||
if (heldItem.isEmpty()) return;
|
if (heldItem.isEmpty()) return;
|
||||||
|
|
||||||
double attackSpeed = player.getAttribute(
|
double attackSpeed = player.getAttribute(
|
||||||
net.minecraft.world.entity.ai.attributes.Attributes.ATTACK_SPEED
|
net.minecraft.world.entity.ai.attributes.Attributes.ATTACK_SPEED
|
||||||
).getBaseValue();
|
).getBaseValue();
|
||||||
|
stats.addAscendXP(3);
|
||||||
String category = (attackSpeed >= 2.0) ? "light_scaling"
|
|
||||||
: (attackSpeed >= 1.2) ? "medium_scaling"
|
|
||||||
: "heavy_scaling";
|
|
||||||
|
|
||||||
stats.addXP(category, 3);
|
|
||||||
PlayerStatsProvider.sync(player);
|
PlayerStatsProvider.sync(player);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -177,7 +173,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.addXP("magic_scaling", 3);
|
stats.addAscendXP(3);
|
||||||
PlayerStatsProvider.sync(player);
|
PlayerStatsProvider.sync(player);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -189,7 +185,7 @@ public class ActivityEvents {
|
|||||||
if (player.level().isClientSide) return;
|
if (player.level().isClientSide) return;
|
||||||
if (event.getEffectInstance().getEffect().getCategory() == net.minecraft.world.effect.MobEffectCategory.BENEFICIAL) {
|
if (event.getEffectInstance().getEffect().getCategory() == net.minecraft.world.effect.MobEffectCategory.BENEFICIAL) {
|
||||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||||
stats.addXP("magic_scaling", 2);
|
stats.addAscendXP(2);
|
||||||
PlayerStatsProvider.sync(player);
|
PlayerStatsProvider.sync(player);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -202,7 +198,7 @@ public class ActivityEvents {
|
|||||||
String itemName = event.getSmelting().getDisplayName().getString().toLowerCase();
|
String itemName = event.getSmelting().getDisplayName().getString().toLowerCase();
|
||||||
if (itemName.contains("potion") || itemName.contains("elixir")) {
|
if (itemName.contains("potion") || itemName.contains("elixir")) {
|
||||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||||
stats.addXP("magic_scaling", 2);
|
stats.addAscendXP(3);
|
||||||
PlayerStatsProvider.sync(player);
|
PlayerStatsProvider.sync(player);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,84 +6,37 @@ 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 = 15;
|
||||||
private final Map<String, Integer> attributes = new HashMap<>();
|
private final Map<String, Integer> attributes = new HashMap<>();
|
||||||
private final Map<String, Integer> xp = new HashMap<>();
|
|
||||||
private int unspentPoints = 15;
|
|
||||||
private int ascendLevel = 1;
|
private int ascendLevel = 1;
|
||||||
private int ascendXP = 0;
|
private int ascendXP = 0;
|
||||||
private static final int MAX_ASCEND_LEVEL = 20;
|
private int unspentPoints = POINTS_PER_LEVEL;
|
||||||
|
|
||||||
public PlayerStats() {
|
public PlayerStats() {
|
||||||
for (String attr : new String[]{
|
for (String attr : new String[]{
|
||||||
"strength", "agility", "fortitude", "intelligence",
|
"strength", "agility", "fortitude", "intelligence",
|
||||||
"willpower", "charisma",
|
"willpower", "charisma",
|
||||||
"light_scaling", "medium_scaling", "heavy_scaling", "magic_scaling"}) {
|
"light_scaling", "medium_scaling", "heavy_scaling", "magic_scaling"}) {
|
||||||
attributes.put(attr, 0);
|
attributes.put(attr, 0);
|
||||||
xp.put(attr, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addUnspentPoints(int amount) {
|
public void addAscendXP(int amount) {
|
||||||
unspentPoints += amount;
|
if (amount <= 0 || ascendLevel >= MAX_ASCEND_LEVEL) return;
|
||||||
|
ascendXP += amount;
|
||||||
|
while (ascendLevel < MAX_ASCEND_LEVEL) {
|
||||||
|
int xpNeeded = getXPToNextAscendLevel();
|
||||||
|
if (ascendXP < xpNeeded) break;
|
||||||
|
ascendXP -= xpNeeded;
|
||||||
|
ascendLevel++;
|
||||||
|
unspentPoints += POINTS_PER_LEVEL;
|
||||||
}
|
}
|
||||||
|
if (ascendLevel >= MAX_ASCEND_LEVEL) {
|
||||||
public int getUnspentPoints() {
|
int xpNeeded = getXPToNextAscendLevel();
|
||||||
return unspentPoints;
|
if (ascendXP > xpNeeded) {
|
||||||
|
ascendXP = xpNeeded;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean spendPoints(String attribute) {
|
|
||||||
if (!attributes.containsKey(attribute)) return false;
|
|
||||||
int cost = getCostToUpgrade(attribute);
|
|
||||||
if (unspentPoints < cost) return false;
|
|
||||||
unspentPoints -= cost;
|
|
||||||
attributes.put(attribute, attributes.get(attribute) + 1);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCostToUpgrade(String attribute) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addXP(String attribute, int amount) {
|
|
||||||
if (!xp.containsKey(attribute) || amount <= 0) return;
|
|
||||||
int currentXP = xp.get(attribute) + amount;
|
|
||||||
int level = attributes.getOrDefault(attribute, 0);
|
|
||||||
boolean changed = false;
|
|
||||||
while (true) {
|
|
||||||
int xpNeeded = getXPToNextAttributeLevel(attribute, level);
|
|
||||||
if (xpNeeded <= 0 || currentXP < xpNeeded) break;
|
|
||||||
currentXP -= xpNeeded;
|
|
||||||
level++;
|
|
||||||
changed = true;
|
|
||||||
unspentPoints += 1;
|
|
||||||
grantAscendXP(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changed) {
|
|
||||||
attributes.put(attribute, level);
|
|
||||||
}
|
|
||||||
xp.put(attribute, currentXP);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getXPToNextAttributeLevel(String attribute, int level) {
|
|
||||||
return 20 + (level * 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getXP(String attribute) {
|
|
||||||
return xp.getOrDefault(attribute, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getXPToNextLevel(String attribute) {
|
|
||||||
int level = attributes.getOrDefault(attribute, 0);
|
|
||||||
return getXPToNextAttributeLevel(attribute, level);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getAttributeLevel(String attribute) {
|
|
||||||
return attributes.getOrDefault(attribute, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAttributeLevel(String attribute, int level) {
|
|
||||||
attributes.put(attribute, level);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getAscendLevel() {
|
public int getAscendLevel() {
|
||||||
@@ -95,71 +48,66 @@ public class PlayerStats {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getXPToNextAscendLevel() {
|
public int getXPToNextAscendLevel() {
|
||||||
if (ascendLevel >= MAX_ASCEND_LEVEL) return Integer.MAX_VALUE;
|
if (ascendLevel >= MAX_ASCEND_LEVEL) return 0;
|
||||||
return 50 + (ascendLevel * 25);
|
return 100 * ascendLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void grantAscendXP(int amount) {
|
public int getUnspentPoints() {
|
||||||
if (amount <= 0 || ascendLevel >= MAX_ASCEND_LEVEL) return;
|
return unspentPoints;
|
||||||
ascendXP += amount;
|
|
||||||
while (ascendLevel < MAX_ASCEND_LEVEL) {
|
|
||||||
int needed = getXPToNextAscendLevel();
|
|
||||||
if (ascendXP < needed) break;
|
|
||||||
ascendXP -= needed;
|
|
||||||
ascendLevel++;
|
|
||||||
}
|
}
|
||||||
if (ascendLevel >= MAX_ASCEND_LEVEL) {
|
|
||||||
ascendXP = 0;
|
public void addUnspentPoints(int amount) {
|
||||||
|
unspentPoints += amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean spendPoints(String attribute) {
|
||||||
|
if (unspentPoints <= 0) return false;
|
||||||
|
if (!attributes.containsKey(attribute)) return false;
|
||||||
|
attributes.put(attribute, attributes.get(attribute) + 1);
|
||||||
|
unspentPoints--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCostToUpgrade(String attribute) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAttributeLevel(String attribute) {
|
||||||
|
return attributes.getOrDefault(attribute, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttributeLevel(String attribute, int level) {
|
||||||
|
attributes.put(attribute, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompoundTag serializeNBT() {
|
public CompoundTag serializeNBT() {
|
||||||
CompoundTag tag = new CompoundTag();
|
CompoundTag tag = new CompoundTag();
|
||||||
tag.putInt("UnspentPoints", unspentPoints);
|
|
||||||
tag.putInt("AscendLevel", ascendLevel);
|
tag.putInt("AscendLevel", ascendLevel);
|
||||||
tag.putInt("AscendXP", ascendXP);
|
tag.putInt("AscendXP", ascendXP);
|
||||||
|
tag.putInt("UnspentPoints", unspentPoints);
|
||||||
CompoundTag attrTag = new CompoundTag();
|
CompoundTag attrTag = new CompoundTag();
|
||||||
CompoundTag xpTag = new CompoundTag();
|
for (Map.Entry<String, Integer> entry : attributes.entrySet()) {
|
||||||
for (String key : attributes.keySet()) {
|
attrTag.putInt(entry.getKey(), entry.getValue());
|
||||||
attrTag.putInt(key, attributes.get(key));
|
|
||||||
xpTag.putInt(key, xp.get(key));
|
|
||||||
}
|
}
|
||||||
tag.put("Attributes", attrTag);
|
tag.put("Attributes", attrTag);
|
||||||
tag.put("XP", xpTag);
|
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deserializeNBT(CompoundTag tag) {
|
public void deserializeNBT(CompoundTag tag) {
|
||||||
|
ascendLevel = tag.contains("AscendLevel") ? tag.getInt("AscendLevel") : 1;
|
||||||
|
ascendXP = tag.contains("AscendXP") ? tag.getInt("AscendXP") : 0;
|
||||||
if (tag.contains("UnspentPoints")) {
|
if (tag.contains("UnspentPoints")) {
|
||||||
unspentPoints = tag.getInt("UnspentPoints");
|
unspentPoints = tag.getInt("UnspentPoints");
|
||||||
} else {
|
} else {
|
||||||
unspentPoints = 15;
|
unspentPoints = POINTS_PER_LEVEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tag.contains("AscendLevel")) {
|
|
||||||
ascendLevel = tag.getInt("AscendLevel");
|
|
||||||
} else {
|
|
||||||
ascendLevel = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tag.contains("AscendXP")) {
|
|
||||||
ascendXP = tag.getInt("AscendXP");
|
|
||||||
} else {
|
|
||||||
ascendXP = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tag.contains("Attributes")) {
|
if (tag.contains("Attributes")) {
|
||||||
CompoundTag attrTag = tag.getCompound("Attributes");
|
CompoundTag attrTag = tag.getCompound("Attributes");
|
||||||
for (String key : attributes.keySet()) {
|
for (String key : attributes.keySet()) {
|
||||||
|
if (attrTag.contains(key)) {
|
||||||
attributes.put(key, attrTag.getInt(key));
|
attributes.put(key, attrTag.getInt(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tag.contains("XP")) {
|
|
||||||
CompoundTag xpTag = tag.getCompound("XP");
|
|
||||||
for (String key : xp.keySet()) {
|
|
||||||
xp.put(key, xpTag.getInt(key));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user