From ccfecb43179e58d7bc7317b2edef4a85a71edeb8 Mon Sep 17 00:00:00 2001 From: fretuks Date: Mon, 17 Nov 2025 11:15:17 +0100 Subject: [PATCH] Implement Ascend Compat, Irons spellbooks compat, And rehauled most things. --- build.gradle | 142 +++++------------- gradle.properties | 2 +- .../fretux/mindmotion/client/ClientData.java | 6 +- .../mindmotion/client/SanityTempoOverlay.java | 12 +- .../effects/IronsSpellbooksCompatMM.java | 49 ++++++ .../client/effects/SanityShaderHandler.java | 13 +- .../mindmotion/compat/AscendCompat.java | 31 ++++ .../mindmotion/event/PlayerTickHandler.java | 11 +- .../network/SyncStatsS2CPacket.java | 33 +++- .../mindmotion/player/SanityCapability.java | 60 ++++++-- .../mindmotion/player/TempoCapability.java | 30 +++- 11 files changed, 242 insertions(+), 147 deletions(-) create mode 100644 src/main/java/net/fretux/mindmotion/client/effects/IronsSpellbooksCompatMM.java create mode 100644 src/main/java/net/fretux/mindmotion/compat/AscendCompat.java diff --git a/build.gradle b/build.gradle index c9fc60c..914a437 100644 --- a/build.gradle +++ b/build.gradle @@ -12,68 +12,25 @@ base { archivesName = mod_id } -// Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 17. java.toolchain.languageVersion = JavaLanguageVersion.of(17) println "Java: ${System.getProperty 'java.version'}, JVM: ${System.getProperty 'java.vm.version'} (${System.getProperty 'java.vendor'}), Arch: ${System.getProperty 'os.arch'}" + + minecraft { - // The mappings can be changed at any time and must be in the following format. - // Channel: Version: - // official MCVersion Official field/method names from Mojang mapping files - // parchment YYYY.MM.DD-MCVersion Open community-sourced parameter names and javadocs layered on top of official - // - // You must be aware of the Mojang license when using the 'official' or 'parchment' mappings. - // See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md - // - // Parchment is an unofficial project maintained by ParchmentMC, separate from MinecraftForge - // Additional setup is needed to use their mappings: https://parchmentmc.org/docs/getting-started - // - // Use non-default mappings at your own risk. They may not always work. - // Simply re-run your setup task after changing the mappings to update your workspace. mappings channel: mapping_channel, version: mapping_version - - // When true, this property will have all Eclipse/IntelliJ IDEA run configurations run the "prepareX" task for the given run configuration before launching the game. - // In most cases, it is not necessary to enable. - // enableEclipsePrepareRuns = true - // enableIdeaPrepareRuns = true - - // This property allows configuring Gradle's ProcessResources task(s) to run on IDE output locations before launching the game. - // It is REQUIRED to be set to true for this template to function. - // See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html copyIdeResources = true - // When true, this property will add the folder name of all declared run configurations to generated IDE run configurations. - // The folder name can be set on a run configuration using the "folderName" property. - // By default, the folder name of a run configuration is the name of the Gradle project containing it. - // generateRunFolders = true - - // This property enables access transformers for use in development. - // They will be applied to the Minecraft artifact. - // The access transformer file can be anywhere in the project. - // However, it must be at "META-INF/accesstransformer.cfg" in the final mod jar to be loaded by Forge. - // This default location is a best practice to automatically put the file in the right place in the final jar. - // See https://docs.minecraftforge.net/en/latest/advanced/accesstransformers/ for more information. - // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') - - // Default run configurations. - // These can be tweaked, removed, or duplicated as needed. runs { - // applies to all the run configs below configureEach { workingDirectory project.file('run') - - // Recommended logging data for a userdev environment - // The markers can be added/remove as needed separated by commas. - // "SCAN": For mods scan. - // "REGISTRIES": For firing of registry events. - // "REGISTRYDUMP": For getting the contents of all registries. property 'forge.logging.markers', 'REGISTRIES' - - // Recommended logging level for the console - // You can set various levels here. - // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels property 'forge.logging.console.level', 'debug' + // IMPORTANT: allow Mixin remapping + property 'mixin.env.remapRefMap', 'true' + property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg" + mods { "${mod_id}" { source sourceSets.main @@ -82,59 +39,43 @@ minecraft { } client { - // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. property 'forge.enabledGameTestNamespaces', mod_id } - server { property 'forge.enabledGameTestNamespaces', mod_id args '--nogui' } - // This run config launches GameTestServer and runs all registered gametests, then exits. - // By default, the server will crash when no gametests are provided. - // The gametest system is also enabled by default for other run configs under the /test command. gameTestServer { property 'forge.enabledGameTestNamespaces', mod_id } data { - // example of overriding the workingDirectory set in configureEach above workingDirectory project.file('run-data') - - // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. - args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') + args '--mod', mod_id, '--all', '--output', + file('src/generated/resources/'), + '--existing', file('src/main/resources/') } } } -// Include resources generated by data generators. sourceSets.main.resources { srcDir 'src/generated/resources' } repositories { - // Put repositories for dependencies here - // ForgeGradle automatically adds the Forge maven and Maven Central for you + mavenLocal() // REQUIRED for local Ascend mod + mavenCentral() - // If you have mod jar dependencies in ./libs, you can declare them as a repository like so. - // See https://docs.gradle.org/current/userguide/declaring_repositories.html#sub:flat_dir_resolver - // flatDir { - // dir 'libs' - // } maven { name = "Iron's Maven - Release" url = "https://code.redspace.io/releases" - content { - includeGroup "io.redspace.ironsspellbooks" - } + content { includeGroup "io.redspace.ironsspellbooks" } } - maven { name = "Iron's Maven - Snapshots" url = "https://code.redspace.io/snapshots" - content { - includeGroup "io.redspace.ironsspellbooks" - } + content { includeGroup "io.redspace.ironsspellbooks" } } + maven { url = "https://maven.enginehub.org/repo/" } maven { url = "https://dl.cloudsmith.io/public/geckolib3/geckolib/maven/" } maven { url = "https://maven.theillusivec4.top" } @@ -146,37 +87,44 @@ repositories { dependencies { minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" - // Iron's Spellbooks API only + // Local Ascend mod (works because of mavenLocal()) + implementation fg.deobf("net.fretux.ascend:Ascend:1.0.0") + + // Iron's Spellbooks compileOnly fg.deobf("io.redspace.ironsspellbooks:irons_spellbooks:${irons_spells_version}:api") implementation fg.deobf("io.redspace.ironsspellbooks:irons_spellbooks:${irons_spells_version}") - // GECKOLIB — deobfuscated, full mod + // GECKOLIB implementation fg.deobf("software.bernie.geckolib:geckolib-forge-${geckolib_version}") - // PLAYER ANIMATOR — deobf + // Player Animator implementation fg.deobf("dev.kosmx.player-anim:player-animation-lib-forge:${player_animator_version}") - // CAELUS — API only + // Caelus compileOnly fg.deobf("top.theillusivec4.caelus:caelus-forge:${caelus_version}:api") implementation fg.deobf("top.theillusivec4.caelus:caelus-forge:${caelus_version}") - // CURIOS — API only + // Curios compileOnly fg.deobf("top.theillusivec4.curios:curios-forge:${curios_version}:api") implementation fg.deobf("top.theillusivec4.curios:curios-forge:${curios_version}") } -// This block of code expands all declared replace properties in the specified resource targets. -// A missing property will result in an error. Properties are expanded using ${} Groovy notation. -// When "copyIdeResources" is enabled, this will also run before the game launches in IDE environments. -// See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html + tasks.named('processResources', ProcessResources).configure { var replaceProperties = [ - minecraft_version: minecraft_version, minecraft_version_range: minecraft_version_range, - forge_version: forge_version, forge_version_range: forge_version_range, - loader_version_range: loader_version_range, - mod_id: mod_id, mod_name: mod_name, mod_license: mod_license, mod_version: mod_version, - mod_authors: mod_authors, mod_description: mod_description, + minecraft_version : minecraft_version, + minecraft_version_range : minecraft_version_range, + forge_version : forge_version, + forge_version_range : forge_version_range, + loader_version_range : loader_version_range, + mod_id : mod_id, + mod_name : mod_name, + mod_license : mod_license, + mod_version : mod_version, + mod_authors : mod_authors, + mod_description : mod_description, ] + inputs.properties replaceProperties filesMatching(['META-INF/mods.toml', 'pack.mcmeta']) { @@ -184,30 +132,21 @@ tasks.named('processResources', ProcessResources).configure { } } -// Example for how to get properties into the manifest for reading at runtime. tasks.named('jar', Jar).configure { manifest { attributes([ 'Specification-Title' : mod_id, 'Specification-Vendor' : mod_authors, - 'Specification-Version' : '1', // We are version 1 of ourselves + 'Specification-Version' : '1', 'Implementation-Title' : project.name, 'Implementation-Version' : project.jar.archiveVersion, 'Implementation-Vendor' : mod_authors, 'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") ]) } - - // This is the preferred method to reobfuscate your jar file finalizedBy 'reobfJar' } -// However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing: -// tasks.named('publish').configure { -// dependsOn 'reobfJar' -// } - -// Example configuration to allow publishing using the maven-publish plugin publishing { publications { register('mavenJava', MavenPublication) { @@ -215,12 +154,11 @@ publishing { } } repositories { - maven { - url "file://${project.projectDir}/mcmodsrepo" - } + maven { url "file://${project.projectDir}/mcmodsrepo" } } } tasks.withType(JavaCompile).configureEach { - options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation -} + options.encoding = 'UTF-8' + dependsOn tasks.named("createSrgToMcp") +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index f71bdf9..d92d6a8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ minecraft_version=1.20.1 # The Minecraft version range can use any release version of Minecraft as bounds. # Snapshots, pre-releases, and release candidates are not guaranteed to sort properly # as they do not follow standard versioning conventions. -minecraft_version_range=[1.20.1,1.21) +minecraft_version_range=[1.20.1] # The Forge version must agree with the Minecraft version to get a valid artifact forge_version=47.4.0 # The Forge version range can use any version of Forge as bounds or match the loader version range diff --git a/src/main/java/net/fretux/mindmotion/client/ClientData.java b/src/main/java/net/fretux/mindmotion/client/ClientData.java index 0cca6ad..fdaa1cd 100644 --- a/src/main/java/net/fretux/mindmotion/client/ClientData.java +++ b/src/main/java/net/fretux/mindmotion/client/ClientData.java @@ -5,4 +5,8 @@ public class ClientData { public static float INSANITY = 0f; public static int TEMPO = 0; public static int VENT_COOLDOWN = 0; -} + + // NEW: synced from server + public static float MAX_SANITY = 80f; + public static int MAX_TEMPO = 120; +} \ No newline at end of file diff --git a/src/main/java/net/fretux/mindmotion/client/SanityTempoOverlay.java b/src/main/java/net/fretux/mindmotion/client/SanityTempoOverlay.java index 773a812..4bb65b5 100644 --- a/src/main/java/net/fretux/mindmotion/client/SanityTempoOverlay.java +++ b/src/main/java/net/fretux/mindmotion/client/SanityTempoOverlay.java @@ -19,27 +19,21 @@ public class SanityTempoOverlay { public static void onRenderOverlay(RenderGuiOverlayEvent.Post event) { Minecraft mc = Minecraft.getInstance(); if (mc.player == null || mc.options.hideGui) return; - GuiGraphics gui = event.getGuiGraphics(); int width = event.getWindow().getGuiScaledWidth(); int height = event.getWindow().getGuiScaledHeight(); - int y = height - 48; int xTempo = 8; int xSanity = width - BAR_WIDTH - 8; - float sanity = ClientData.SANITY; float insanity = ClientData.INSANITY; float tempo = ClientData.TEMPO; - - float sanityPercent = sanity / 80f; - float insanityPercent = insanity / 80f; // same max as sanity (80) - float tempoPercent = tempo / 120f; - + float sanityPercent = sanity / ClientData.MAX_SANITY; + float insanityPercent = insanity / ClientData.MAX_SANITY; + float tempoPercent = (float) tempo / (float) ClientData.MAX_TEMPO; int sanityFill = (int) (BAR_WIDTH * sanityPercent); int tempoFill = (int) (BAR_WIDTH * tempoPercent); int insanityFill = (int) (BAR_WIDTH * insanityPercent); - RenderSystem.enableBlend(); drawRoundedBar(gui, xTempo, y, BAR_WIDTH, BAR_HEIGHT, 0xFF33AFFF, tempoFill); gui.drawString(mc.font, Component.literal("Tempo"), xTempo, y - 10, 0x66CCFF, false); diff --git a/src/main/java/net/fretux/mindmotion/client/effects/IronsSpellbooksCompatMM.java b/src/main/java/net/fretux/mindmotion/client/effects/IronsSpellbooksCompatMM.java new file mode 100644 index 0000000..55a9e6c --- /dev/null +++ b/src/main/java/net/fretux/mindmotion/client/effects/IronsSpellbooksCompatMM.java @@ -0,0 +1,49 @@ +package net.fretux.mindmotion.client.effects; + +import io.redspace.ironsspellbooks.api.registry.AttributeRegistry; +import net.fretux.mindmotion.player.PlayerCapabilityProvider; +import net.minecraft.world.entity.ai.attributes.Attribute; +import net.minecraft.world.entity.ai.attributes.AttributeInstance; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.entity.player.Player; +import net.minecraftforge.fml.ModList; + +import java.util.UUID; + +public final class IronsSpellbooksCompatMM { + public static final double TEMPO_PER_PERCENT = 3; + private static final UUID TEMPO_MANA_REGEN_UUID = + UUID.fromString("de4f16ad-73b3-4b99-bf77-44c9878222aa"); + + private IronsSpellbooksCompatMM() {} + + public static boolean isLoaded() { + return ModList.get().isLoaded("irons_spellbooks"); + } + public static void applyTempo(Player player) { + if (!isLoaded()) return; + player.getCapability(PlayerCapabilityProvider.TEMPO).ifPresent(tempoCap -> { + int tempo = tempoCap.getTempo(); + applyTempoToManaRegen(player, tempo); + }); + } + + public static void applyTempoToManaRegen(Player player, int tempo) { + Attribute manaRegenAttr = (Attribute) AttributeRegistry.MANA_REGEN.get(); + if (manaRegenAttr == null) return; + AttributeInstance inst = player.getAttribute(manaRegenAttr); + if (inst == null) return; + inst.removeModifier(TEMPO_MANA_REGEN_UUID); + if (tempo <= 0) { + return; + } + double bonusPercent = (double) tempo / TEMPO_PER_PERCENT; + double multiplier = bonusPercent / 100.0; + inst.addTransientModifier(new AttributeModifier( + TEMPO_MANA_REGEN_UUID, + "MindMotion Tempo mana regen", + multiplier, + AttributeModifier.Operation.MULTIPLY_BASE + )); + } +} \ No newline at end of file diff --git a/src/main/java/net/fretux/mindmotion/client/effects/SanityShaderHandler.java b/src/main/java/net/fretux/mindmotion/client/effects/SanityShaderHandler.java index 9684136..37da596 100644 --- a/src/main/java/net/fretux/mindmotion/client/effects/SanityShaderHandler.java +++ b/src/main/java/net/fretux/mindmotion/client/effects/SanityShaderHandler.java @@ -38,22 +38,17 @@ public class SanityShaderHandler { @SubscribeEvent public static void onRenderWorld(RenderLevelStageEvent event) { if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_LEVEL) return; - Minecraft mc = Minecraft.getInstance(); if (mc.player == null || mc.level == null) return; - float sanity = ClientData.SANITY; float insanity = ClientData.INSANITY; - float maxSanity = 80f; - + float maxSanity = ClientData.MAX_SANITY; float sanityPct = sanity / maxSanity; float insanityPct = insanity / maxSanity; - float baseDesat = 0f; if (sanityPct < 0.70f) { baseDesat = 1f - (sanityPct / 0.70f); } - float insanityBoost = 0.75f * insanityPct; float target = Math.max(baseDesat, insanityBoost); if (sanity <= 0f) target = 1f; @@ -73,7 +68,6 @@ public class SanityShaderHandler { return; } } - PostChain chain = mc.gameRenderer.currentEffect(); if (chain == null) return; try { @@ -107,13 +101,10 @@ public class SanityShaderHandler { blur = Math.min(blur, 1f); vig = Math.min(vig, 1f); fog = Math.min(fog, 1f); - var uBlur = effect.getUniform("BlurAmount"); if (uBlur != null) uBlur.set(blur); - var uVig = effect.getUniform("Vignette"); if (uVig != null) uVig.set(vig); - var uFog = effect.getUniform("FogStrength"); if (uFog != null) uFog.set(fog); float shake = 0f; @@ -151,10 +142,8 @@ public class SanityShaderHandler { @SubscribeEvent public static void onPlayerRespawn(PlayerEvent.PlayerRespawnEvent event) { if (!event.getEntity().level().isClientSide()) return; - Minecraft mc = Minecraft.getInstance(); currentStrength = 0f; - mc.execute(() -> { if (mc.gameRenderer.currentEffect() != null) { mc.gameRenderer.shutdownEffect(); diff --git a/src/main/java/net/fretux/mindmotion/compat/AscendCompat.java b/src/main/java/net/fretux/mindmotion/compat/AscendCompat.java new file mode 100644 index 0000000..380da2c --- /dev/null +++ b/src/main/java/net/fretux/mindmotion/compat/AscendCompat.java @@ -0,0 +1,31 @@ +package net.fretux.mindmotion.compat; + + +import net.fretux.ascend.player.PlayerStatsProvider; +import net.fretux.mindmotion.player.PlayerCapabilityProvider; +import net.fretux.mindmotion.player.SanityCapability; +import net.fretux.mindmotion.player.TempoCapability; +import net.minecraft.world.entity.player.Player; + +public final class AscendCompat { + + private AscendCompat() {} + + public static void applyWillpowerBonuses(Player player) { + player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> { + int willpower = stats.getAttributeLevel("willpower"); + float sanityBonus = willpower * 3.0f; + float tempoBonus = willpower * 0.5f; + player.getCapability(PlayerCapabilityProvider.SANITY).ifPresent(cap -> { + if (cap instanceof SanityCapability impl) { + impl.setBonusMaxSanity(sanityBonus); + } + }); + player.getCapability(PlayerCapabilityProvider.TEMPO).ifPresent(cap -> { + if (cap instanceof TempoCapability impl) { + impl.setBonusMaxTempo(tempoBonus); + } + }); + }); + } +} diff --git a/src/main/java/net/fretux/mindmotion/event/PlayerTickHandler.java b/src/main/java/net/fretux/mindmotion/event/PlayerTickHandler.java index 768861e..c7aed48 100644 --- a/src/main/java/net/fretux/mindmotion/event/PlayerTickHandler.java +++ b/src/main/java/net/fretux/mindmotion/event/PlayerTickHandler.java @@ -1,5 +1,6 @@ package net.fretux.mindmotion.event; +import net.fretux.mindmotion.compat.AscendCompat; import net.fretux.mindmotion.network.ModMessages; import net.fretux.mindmotion.network.SyncStatsS2CPacket; import net.fretux.mindmotion.player.PlayerCapabilityProvider; @@ -17,6 +18,8 @@ import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import static net.fretux.mindmotion.client.effects.IronsSpellbooksCompatMM.applyTempoToManaRegen; + @Mod.EventBusSubscriber(modid = "mindmotion") public class PlayerTickHandler { @@ -32,11 +35,14 @@ public class PlayerTickHandler { if (event.phase != TickEvent.Phase.END) return; Player player = event.player; if (player.level().isClientSide) return; + AscendCompat.applyWillpowerBonuses(player); int tick = player.tickCount; boolean sanityTick = tick % SANITY_TICK_INTERVAL == 0; boolean tempoSyncTick = tick % TEMPO_TICK_INTERVAL == 0; + if (sanityTick) handleSanityAndInsanity(player); handleTempoTick(player, tick); + if (player instanceof ServerPlayer serverPlayer && (sanityTick || tempoSyncTick)) { player.getCapability(PlayerCapabilityProvider.SANITY).ifPresent(sanity -> player.getCapability(PlayerCapabilityProvider.TEMPO).ifPresent(tempo -> @@ -45,7 +51,9 @@ public class PlayerTickHandler { sanity.getSanity(), sanity.getInsanity(), tempo.getTempo(), - tempo.getVentCooldown() + tempo.getVentCooldown(), + sanity.getMaxSanity(), + tempo.getMaxTempo() ), serverPlayer.connection.connection, net.minecraftforge.network.NetworkDirection.PLAY_TO_CLIENT @@ -195,6 +203,7 @@ public class PlayerTickHandler { if (ticksSinceCombat > COMBAT_DECAY_DELAY && value > 0) { tempo.setTempo(value - 1); } + applyTempoToManaRegen(player, tempo.getTempo()); } }); } diff --git a/src/main/java/net/fretux/mindmotion/network/SyncStatsS2CPacket.java b/src/main/java/net/fretux/mindmotion/network/SyncStatsS2CPacket.java index a36aa36..77afadd 100644 --- a/src/main/java/net/fretux/mindmotion/network/SyncStatsS2CPacket.java +++ b/src/main/java/net/fretux/mindmotion/network/SyncStatsS2CPacket.java @@ -11,12 +11,21 @@ public class SyncStatsS2CPacket { private final float insanity; private final int tempo; private final int ventCooldown; + private final float maxSanity; + private final int maxTempo; - public SyncStatsS2CPacket(float sanity, float insanity, int tempo, int ventCooldown) { + public SyncStatsS2CPacket(float sanity, + float insanity, + int tempo, + int ventCooldown, + float maxSanity, + int maxTempo) { this.sanity = sanity; this.insanity = insanity; this.tempo = tempo; this.ventCooldown = ventCooldown; + this.maxSanity = maxSanity; + this.maxTempo = maxTempo; } public static void encode(SyncStatsS2CPacket msg, FriendlyByteBuf buf) { @@ -24,10 +33,18 @@ public class SyncStatsS2CPacket { buf.writeFloat(msg.insanity); buf.writeInt(msg.tempo); buf.writeInt(msg.ventCooldown); + buf.writeFloat(msg.maxSanity); + buf.writeInt(msg.maxTempo); } public static SyncStatsS2CPacket decode(FriendlyByteBuf buf) { - return new SyncStatsS2CPacket(buf.readFloat(), buf.readFloat(), buf.readInt(), buf.readInt()); + float sanity = buf.readFloat(); + float insanity = buf.readFloat(); + int tempo = buf.readInt(); + int ventCooldown = buf.readInt(); + float maxSanity = buf.readFloat(); + int maxTempo = buf.readInt(); + return new SyncStatsS2CPacket(sanity, insanity, tempo, ventCooldown, maxSanity, maxTempo); } public static void handle(SyncStatsS2CPacket msg, Supplier ctx) { @@ -36,8 +53,18 @@ public class SyncStatsS2CPacket { ClientData.INSANITY = msg.insanity; ClientData.TEMPO = msg.tempo; ClientData.VENT_COOLDOWN = msg.ventCooldown; + ClientData.MAX_SANITY = msg.maxSanity; + ClientData.MAX_TEMPO = msg.maxTempo; }); ctx.get().setPacketHandled(true); - System.out.println("[Client] Sanity: " + msg.sanity + ", Insanity: " + msg.insanity + ", Tempo: " + msg.tempo); + + System.out.println( + "[Client] Sanity: " + msg.sanity + + ", Insanity: " + msg.insanity + + ", Tempo: " + msg.tempo + + ", VentCD: " + msg.ventCooldown + + ", MaxSanity: " + msg.maxSanity + + ", MaxTempo: " + msg.maxTempo + ); } } \ No newline at end of file diff --git a/src/main/java/net/fretux/mindmotion/player/SanityCapability.java b/src/main/java/net/fretux/mindmotion/player/SanityCapability.java index 90a32e2..2328328 100644 --- a/src/main/java/net/fretux/mindmotion/player/SanityCapability.java +++ b/src/main/java/net/fretux/mindmotion/player/SanityCapability.java @@ -3,23 +3,61 @@ package net.fretux.mindmotion.player; public class SanityCapability implements ISanity { private float sanity = 80f; private float insanity = 0f; - private final float maxSanity = 80f; + + // Base + bonus so Ascend can modify max + private float baseMaxSanity = 80f; + private float bonusMaxSanity = 0f; // from Ascend willpower etc. @Override - public float getSanity() { return sanity; } - @Override - public void setSanity(float sanity) { this.sanity = Math.max(0, Math.min(maxSanity, sanity)); } + public float getSanity() { + return sanity; + } @Override - public float getInsanity() { return insanity; } - @Override - public void setInsanity(float insanity) { this.insanity = Math.max(0, Math.min(maxSanity, insanity)); } + public void setSanity(float sanity) { + float max = getMaxSanity(); + this.sanity = Math.max(0, Math.min(max, sanity)); + } @Override - public float getMaxSanity() { return maxSanity; } + public float getInsanity() { + return insanity; + } @Override - public void addSanity(float amount) { setSanity(this.sanity + amount); } + public void setInsanity(float insanity) { + float max = getMaxSanity(); + this.insanity = Math.max(0, Math.min(max, insanity)); + } + @Override - public void reduceSanity(float amount) { setSanity(this.sanity - amount); } -} + public float getMaxSanity() { + return baseMaxSanity + bonusMaxSanity; + } + + @Override + public void addSanity(float amount) { + setSanity(this.sanity + amount); + } + + @Override + public void reduceSanity(float amount) { + setSanity(this.sanity - amount); + } + + public void setBaseMaxSanity(float baseMaxSanity) { + this.baseMaxSanity = baseMaxSanity; + setSanity(this.sanity); + setInsanity(this.insanity); + } + + public void setBonusMaxSanity(float bonusMaxSanity) { + this.bonusMaxSanity = Math.max(0f, bonusMaxSanity); + setSanity(this.sanity); + setInsanity(this.insanity); + } + + public float getBonusMaxSanity() { + return bonusMaxSanity; + } +} \ No newline at end of file diff --git a/src/main/java/net/fretux/mindmotion/player/TempoCapability.java b/src/main/java/net/fretux/mindmotion/player/TempoCapability.java index 403dbab..3c722e3 100644 --- a/src/main/java/net/fretux/mindmotion/player/TempoCapability.java +++ b/src/main/java/net/fretux/mindmotion/player/TempoCapability.java @@ -2,7 +2,11 @@ package net.fretux.mindmotion.player; public class TempoCapability implements ITempo { private int tempo = 0; - private final int maxTempo = 120; + + private int baseMaxTempo = 120; + private float bonusMaxTempo = 0f; // from Ascend willpower + + private int ventCooldown = 0; @Override public int getTempo() { @@ -11,12 +15,12 @@ public class TempoCapability implements ITempo { @Override public void setTempo(int tempo) { - this.tempo = Math.max(0, Math.min(maxTempo, tempo)); + this.tempo = Math.max(0, Math.min(getMaxTempo(), tempo)); } @Override public int getMaxTempo() { - return maxTempo; + return Math.max(0, Math.round(baseMaxTempo + bonusMaxTempo)); } @Override @@ -29,8 +33,6 @@ public class TempoCapability implements ITempo { setTempo(this.tempo - amount); } - private int ventCooldown = 0; - @Override public int getVentCooldown() { return ventCooldown; @@ -38,6 +40,20 @@ public class TempoCapability implements ITempo { @Override public void setVentCooldown(int ticks) { - ventCooldown = ticks; + ventCooldown = Math.max(0, ticks); } -} + + public void setBaseMaxTempo(int baseMaxTempo) { + this.baseMaxTempo = baseMaxTempo; + setTempo(this.tempo); + } + + public void setBonusMaxTempo(float bonusMaxTempo) { + this.bonusMaxTempo = Math.max(0f, bonusMaxTempo); + setTempo(this.tempo); + } + + public float getBonusMaxTempo() { + return bonusMaxTempo; + } +} \ No newline at end of file