mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2025-12-09 16:45:44 -07:00
Backported probabilistic runes. Can now toggle between revision 581, 573 and 570 behavior via runecrafting_formula_revision in server config
This commit is contained in:
parent
a74583b13b
commit
fee56ae528
6 changed files with 84 additions and 19 deletions
|
|
@ -9,19 +9,19 @@ import core.game.node.item.Item;
|
||||||
* @date 01/11/2013
|
* @date 01/11/2013
|
||||||
*/
|
*/
|
||||||
public enum Rune {
|
public enum Rune {
|
||||||
AIR(Runes.AIR_RUNE.transform(), 1, 5, new int[] { 1, 11, 22, 33, 44, 55, 66, 77, 88, 99 }),
|
AIR(Runes.AIR_RUNE.transform(), 1, 5, new int[] { 1, 11, 22, 33, 44, 55, 66, 77, 88, 99, 110 }),
|
||||||
MIND(Runes.MIND_RUNE.transform(), 2, 5.5, new int[] { 1, 14, 28, 42, 56, 70, 84, 98 }),
|
MIND(Runes.MIND_RUNE.transform(), 2, 5.5, new int[] { 1, 14, 28, 42, 56, 70, 84, 98, 112 }),
|
||||||
WATER(Runes.WATER_RUNE.transform(), 5, 6, new int[] { 1, 19, 38, 57, 76, 95 }),
|
WATER(Runes.WATER_RUNE.transform(), 5, 6, new int[] { 1, 19, 38, 57, 76, 95, 114 }),
|
||||||
EARTH(Runes.EARTH_RUNE.transform(), 9, 6.5, new int[] { 1, 26, 52, 78 }),
|
EARTH(Runes.EARTH_RUNE.transform(), 9, 6.5, new int[] { 1, 26, 52, 78, 104 }),
|
||||||
FIRE(Runes.FIRE_RUNE.transform(), 14, 7, new int[] { 1, 35, 70 }),
|
FIRE(Runes.FIRE_RUNE.transform(), 14, 7, new int[] { 1, 35, 70, 105 }),
|
||||||
BODY(Runes.BODY_RUNE.transform(), 20, 7.5, new int[] { 1, 46, 92 }),
|
BODY(Runes.BODY_RUNE.transform(), 20, 7.5, new int[] { 1, 46, 92, 138 }),
|
||||||
COSMIC(Runes.COSMIC_RUNE.transform(), 27, 8, new int[] { 1, 59 }),
|
COSMIC(Runes.COSMIC_RUNE.transform(), 27, 8, new int[] { 1, 59, 118 }),
|
||||||
CHAOS(Runes.CHAOS_RUNE.transform(), 35, 8.5, new int[] { 1, 74 }),
|
CHAOS(Runes.CHAOS_RUNE.transform(), 35, 8.5, new int[] { 1, 74, 148 }),
|
||||||
ASTRAL(Runes.ASTRAL_RUNE.transform(), 40, 8.7, new int[] { 1, 82 }),
|
ASTRAL(Runes.ASTRAL_RUNE.transform(), 40, 8.7, new int[] { 1, 82, 164 }),
|
||||||
NATURE(Runes.NATURE_RUNE.transform(), 44, 9, new int[] { 1, 91 }),
|
NATURE(Runes.NATURE_RUNE.transform(), 44, 9, new int[] { 1, 91, 182 }),
|
||||||
LAW(Runes.LAW_RUNE.transform(), 54, 9.5),
|
LAW(Runes.LAW_RUNE.transform(), 54, 9.5, new int[] { 1, 110, }),
|
||||||
DEATH(Runes.DEATH_RUNE.transform(), 65, 10),
|
DEATH(Runes.DEATH_RUNE.transform(), 65, 10, new int[] { 1, 131 }),
|
||||||
BLOOD(Runes.BLOOD_RUNE.transform(), 77, 10.5),
|
BLOOD(Runes.BLOOD_RUNE.transform(), 77, 10.5, new int[] { 1, 154 }),
|
||||||
SOUL(Runes.SOUL_RUNE.transform(), 90, 11);
|
SOUL(Runes.SOUL_RUNE.transform(), 90, 11);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package content.global.skill.runecrafting;
|
package content.global.skill.runecrafting;
|
||||||
|
|
||||||
import content.global.handlers.item.equipment.fistofguthixgloves.FOGGlovesManager;
|
import content.global.handlers.item.equipment.fistofguthixgloves.FOGGlovesManager;
|
||||||
|
import core.ServerConstants;
|
||||||
import core.game.container.impl.EquipmentContainer;
|
import core.game.container.impl.EquipmentContainer;
|
||||||
import core.game.node.entity.impl.Animator.Priority;
|
import core.game.node.entity.impl.Animator.Priority;
|
||||||
import core.game.node.entity.player.Player;
|
import core.game.node.entity.player.Player;
|
||||||
|
|
@ -333,6 +334,12 @@ public final class RuneCraftPulse extends SkillPulse<Item> {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
int rcLevel = player.getSkills().getLevel(Skills.RUNECRAFTING);
|
int rcLevel = player.getSkills().getLevel(Skills.RUNECRAFTING);
|
||||||
|
int runecraftingFormulaRevision = ServerConstants.RUNECRAFTING_FORMULA_REVISION;
|
||||||
|
boolean lumbridgeDiary = player.getAchievementDiaryManager().getDiary(DiaryType.LUMBRIDGE).isComplete(1);
|
||||||
|
return RuneCraftPulse.getMultiplier(rcLevel, rune, runecraftingFormulaRevision, lumbridgeDiary);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getMultiplier(int rcLevel, Rune rune, int runecraftingFormulaRevision, boolean lumbridgeDiary) {
|
||||||
int[] multipleLevels = rune.getMultiple();
|
int[] multipleLevels = rune.getMultiple();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (int level : multipleLevels) {
|
for (int level : multipleLevels) {
|
||||||
|
|
@ -341,17 +348,18 @@ public final class RuneCraftPulse extends SkillPulse<Item> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(multipleLevels.length > i) {
|
if(multipleLevels.length > i && runecraftingFormulaRevision >= 573) {
|
||||||
int a = Math.max(multipleLevels[i-1], rune.getLevel());
|
int a = Math.max(multipleLevels[i-1], rune.getLevel());
|
||||||
int b = multipleLevels[i];
|
int b = multipleLevels[i];
|
||||||
double chance = ((double)rcLevel - (double)a) / ((double)b - (double)a);
|
if(b <= 99 || runecraftingFormulaRevision >= 581) {
|
||||||
player.debug(String.format("%d %d %d, %f", a, b, rcLevel, chance));
|
double chance = ((double)rcLevel - (double)a) / ((double)b - (double)a);
|
||||||
if(RandomFunction.random(0.0, 1.0) < chance) {
|
if(RandomFunction.random(0.0, 1.0) < chance) {
|
||||||
i += 1;
|
i += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player.getAchievementDiaryManager().getDiary(DiaryType.LUMBRIDGE).isComplete(1)
|
if (lumbridgeDiary
|
||||||
&& new ArrayList<>(Arrays.asList(Rune.AIR, Rune.WATER, Rune.FIRE, Rune.EARTH)).contains(rune)
|
&& new ArrayList<>(Arrays.asList(Rune.AIR, Rune.WATER, Rune.FIRE, Rune.EARTH)).contains(rune)
|
||||||
&& RandomFunction.getRandom(10) == 0) { //approximately 10% chance
|
&& RandomFunction.getRandom(10) == 0) { //approximately 10% chance
|
||||||
i += 1;
|
i += 1;
|
||||||
|
|
|
||||||
|
|
@ -317,5 +317,8 @@ class ServerConstants {
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
var FORCE_HALLOWEEN_RANDOMS = false
|
var FORCE_HALLOWEEN_RANDOMS = false
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
var RUNECRAFTING_FORMULA_REVISION = 581
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -163,6 +163,7 @@ object ServerConfigParser {
|
||||||
ServerConstants.NEW_PLAYER_ANNOUNCEMENT = data.getBoolean("world.new_player_announcement", true)
|
ServerConstants.NEW_PLAYER_ANNOUNCEMENT = data.getBoolean("world.new_player_announcement", true)
|
||||||
ServerConstants.HOLIDAY_EVENT_RANDOMS = data.getBoolean("world.holiday_event_randoms", true)
|
ServerConstants.HOLIDAY_EVENT_RANDOMS = data.getBoolean("world.holiday_event_randoms", true)
|
||||||
ServerConstants.FORCE_HALLOWEEN_RANDOMS = data.getBoolean("world.force_halloween_randoms", false)
|
ServerConstants.FORCE_HALLOWEEN_RANDOMS = data.getBoolean("world.force_halloween_randoms", false)
|
||||||
|
ServerConstants.RUNECRAFTING_FORMULA_REVISION = data.getLong("world.runecrafting_formula_revision", 581).toInt()
|
||||||
|
|
||||||
val logLevel = data.getString("server.log_level", "VERBOSE").uppercase()
|
val logLevel = data.getString("server.log_level", "VERBOSE").uppercase()
|
||||||
ServerConstants.LOG_LEVEL = parseEnumEntry<LogLevel>(logLevel) ?: LogLevel.VERBOSE
|
ServerConstants.LOG_LEVEL = parseEnumEntry<LogLevel>(logLevel) ?: LogLevel.VERBOSE
|
||||||
|
|
|
||||||
51
Server/src/test/kotlin/RunecraftingTests.kt
Normal file
51
Server/src/test/kotlin/RunecraftingTests.kt
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
import content.global.skill.runecrafting.RuneCraftPulse;
|
||||||
|
import content.global.skill.runecrafting.Rune;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
|
class RunecraftTests {
|
||||||
|
fun rollRc(rcLevel: Int, rune: Rune, revision: Int, lo: Double, hi: Double) {
|
||||||
|
var total = 0.0
|
||||||
|
for(i in 0 until 1000) {
|
||||||
|
total += RuneCraftPulse.getMultiplier(rcLevel, rune, revision, false)
|
||||||
|
}
|
||||||
|
val average = total / 1000.0
|
||||||
|
Assertions.assertTrue(lo <= average && average <= hi, "rollRc: ${rcLevel} ${rune.name} ${revision}: ${average}")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun testNatureRcMultipliers() {
|
||||||
|
rollRc(44, Rune.NATURE, 530, 1.0, 1.0);
|
||||||
|
rollRc(44, Rune.NATURE, 573, 1.0, 1.0);
|
||||||
|
rollRc(44, Rune.NATURE, 581, 1.0, 1.0);
|
||||||
|
|
||||||
|
rollRc(68, Rune.NATURE, 530, 1.0, 1.0);
|
||||||
|
rollRc(68, Rune.NATURE, 573, 1.45, 1.55);
|
||||||
|
rollRc(68, Rune.NATURE, 581, 1.45, 1.55);
|
||||||
|
|
||||||
|
rollRc(91, Rune.NATURE, 530, 2.0, 2.0);
|
||||||
|
rollRc(91, Rune.NATURE, 573, 2.0, 2.0);
|
||||||
|
rollRc(91, Rune.NATURE, 581, 2.0, 2.0);
|
||||||
|
|
||||||
|
rollRc(90, Rune.NATURE, 530, 1.0, 1.0);
|
||||||
|
rollRc(90, Rune.NATURE, 573, 1.95, 2.0);
|
||||||
|
rollRc(90, Rune.NATURE, 581, 1.95, 2.0);
|
||||||
|
|
||||||
|
rollRc(99, Rune.NATURE, 530, 2.0, 2.0);
|
||||||
|
rollRc(99, Rune.NATURE, 573, 2.0, 2.0);
|
||||||
|
rollRc(99, Rune.NATURE, 581, 2.0, 2.1);
|
||||||
|
}
|
||||||
|
@Test fun testLawRcMultipliers() {
|
||||||
|
rollRc(54, Rune.LAW, 530, 1.0, 1.0);
|
||||||
|
rollRc(54, Rune.LAW, 573, 1.0, 1.0);
|
||||||
|
rollRc(54, Rune.LAW, 581, 1.0, 1.0);
|
||||||
|
|
||||||
|
rollRc(77, Rune.LAW, 530, 1.0, 1.0);
|
||||||
|
rollRc(77, Rune.LAW, 573, 1.0, 1.0);
|
||||||
|
rollRc(77, Rune.LAW, 581, 1.35, 1.45);
|
||||||
|
|
||||||
|
rollRc(99, Rune.LAW, 530, 1.0, 1.0);
|
||||||
|
rollRc(99, Rune.LAW, 573, 1.0, 1.0);
|
||||||
|
rollRc(99, Rune.LAW, 581, 1.75, 1.85);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -101,6 +101,8 @@ new_player_announcement = true
|
||||||
holiday_event_randoms = true
|
holiday_event_randoms = true
|
||||||
#force holiday randoms (can only force one at a time)
|
#force holiday randoms (can only force one at a time)
|
||||||
force_halloween_randoms = false
|
force_halloween_randoms = false
|
||||||
|
# runecrafting formula revision (573 introduced probabilistic multiple runes, 581 extrapolated probabilistic runes past 99)
|
||||||
|
runecrafting_formula_revision = 581
|
||||||
|
|
||||||
[paths]
|
[paths]
|
||||||
#path to the data folder, which contains the cache subfolder and such
|
#path to the data folder, which contains the cache subfolder and such
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue