From 8ff3fb51ba111a262291ee83551e459f0e3df8d8 Mon Sep 17 00:00:00 2001 From: Harley Date: Thu, 8 May 2025 18:19:25 -0700 Subject: [PATCH] feat: Replace dynamicXPMod setting with flexible experienceRateMin/Max --- .../character/player/skill/exp/Experience.kt | 23 +++++++++---------- .../player/skill/level/Interpolation.kt | 3 ++- game/src/main/resources/game.properties | 6 ++++- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/player/skill/exp/Experience.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/player/skill/exp/Experience.kt index 1400a7aea7..eb0fdf3815 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/player/skill/exp/Experience.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/player/skill/exp/Experience.kt @@ -33,22 +33,21 @@ class Experience( } fun add(skill: Skill, baseExperience: Double) { - if (baseExperience <= 0.0) { - return - } + if (baseExperience <= 0.0) return + + val rateMin = Settings["world.experienceRateMin", 1.0] + val rateMax = Settings["world.experienceRateMax", 1.0] - val xpModSetting = Settings["world.dynamicXPMod", "off"].lowercase() - val playerMaxLevel = level(skill, get(skill)) - val maxLevel = Level.MAX_LEVEL + val playerLevel = level(skill, get(skill)).toDouble() + val maxLevel = Level.MAX_LEVEL.toDouble() - val modifier = when (xpModSetting) { - "linear" -> interpolate(1.0, 5.0, playerMaxLevel.toDouble() / maxLevel) - "inverse" -> interpolate(5.0, 1.0, playerMaxLevel.toDouble() / maxLevel) - else -> 1.0 + val modifier = if (rateMin != rateMax) { + interpolate(rateMin, rateMax, playerLevel / maxLevel) + } else { + rateMin } - val experienceRate = Settings["world.experienceRate", DEFAULT_EXPERIENCE_RATE] - val adjustedExperience = baseExperience * modifier * experienceRate + val adjustedExperience = baseExperience * modifier if (blocked.contains(skill)) { events.emit(BlockedExperience(skill, adjustedExperience)) diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/player/skill/level/Interpolation.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/player/skill/level/Interpolation.kt index 942c804efb..802f319ad7 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/player/skill/level/Interpolation.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/player/skill/level/Interpolation.kt @@ -12,7 +12,8 @@ object Interpolation { } fun interpolate(start: Double, end: Double, fraction: Double): Double { - return start + fraction * (end - start) + val result = start + fraction * (end - start) + return kotlin.math.round(result * 10) / 10.0 } fun lerp(value: Int, inRange: IntRange, result: IntRange): Int { diff --git a/game/src/main/resources/game.properties b/game/src/main/resources/game.properties index 100332e31d..637f93cbaf 100644 --- a/game/src/main/resources/game.properties +++ b/game/src/main/resources/game.properties @@ -68,7 +68,11 @@ world.home.y=3219 world.messages=false # Experience multiplier (1.0 = normal XP rate) -world.experienceRate=1.0 +# Set both to the same value (e.g., 1.0) for static XP +# Set min < max for increasing XP at higher levels +# Set min > max for decreasing XP at higher levels +world.experienceRateMin=1.0 +world.experienceRateMax=1.0 # world.dynamicXPMod - Linear (1x-5x multiplier) or inverse (5x-1x multiplier) XP scaling: "off", "linear", or "inverse" world.dynamicXPMod=off