Speed Calculator
- This speed calculator does not factor in Ebony (+2.5%) and Silver/black bonuses (?). You will have to add those percentages yourself.
- Based on the creature's soul strength the traits will flip on and off at random, so in-game you can expect the actual speed to fluctuate anywhere between the min and max values.
- The author (below) thinks unicorns are immune to soul strength checks, but he's not definite.
Credit: Wulvarik, April 11, 2018
I butchered together some decompiled WU code into a horse speed calculator to see how much of an effect the various factors (traits, weight, gear QL) can have.
To use it, go to the link below:
Copy the code presented there, then go to this link:
https://www.jdoodle.com/online-java-compiler
Erase anything in the box, and paste the code you copied.
Click Execute at the bottom to make sure it gives some output. That’ll be for an untraited, ungeared horse, being ridden by somebody carrying 50 Kg of gear. Even if it’s not being factored in for the speed boost, the horse’s weight value still has saddle/shoes added in since I assumed that would be the most likely thing tested. Set mountCarriedWeight to 0 for a true reading of an ungeared horse.
(My comments say that unicorns are exempt from soul strength checks, but don’t take that as a hard truth.)
Set the values in the first little bit to whatever you’d like to see, then Execute. Make sure to set isSaddled, isShoed to true to see those values have an effect.
Based on the creature’s soul strength the traits will flip on and off at random, so in-game you can expect the actual speed to fluctuate anywhere between the min and max values.
Feedback and reports of any inaccuracies are appreciated.
Disclaimer: This comes from WU code, who the hell knows what WO code really says, but they’re usually pretty similar.
public class MyClass { public static void main(String args[]) { boolean horse = true; boolean hellHorse = false; boolean unicorn = false; // Unicorns are exempt from SoulStrength checks on traits, not modeled here. boolean isRidden = true; boolean isSecondRider = false; boolean isSaddled = false; boolean isShoed = false; float saddleQL = 70.0F; byte saddleRarity = 0; //0 normal, 1 rare, 2 supreme, 3 fantastic float saddleWoA = 0.0F; float horseShoe1QL = 70.0F; byte horseShoe1Rarity = 0; float horseShoe1WoA = 0.0F; float horseShoe2QL = 70.0F; byte horseShoe2Rarity = 0; float horseShoe2WoA = 0.0F; float horseShoe3QL = 70.0F; byte horseShoe3Rarity = 0; float horseShoe3WoA = 0.0F; float horseShoe4QL = 70.0F; byte horseShoe4Rarity = 0; float horseShoe4WoA = 0.0F; boolean trait1 = false; //It has fleeter movement than normal boolean trait3 = false; //It has a strong body boolean trait4 = false; //It has lightning movement boolean trait5 = false; //It can carry more than average boolean trait6 = false; //It has very strong leg muscles boolean trait8 = false; //It has malformed hindlegs boolean trait9 = false; //The legs are of different length boolean trait11 = false; //It looks very unmotivated boolean trait23 = false; //Color is ebony black float mountCarriedWeight = 6500; // Assumes four 500 gram shoes and one 4500 saddle float riderOneFatLevel = 125; // 0 - 125, Only matters if under 30 float riderOneCarriedWeight = 50000; // Weight in grams float riderTwoFatLevel = 0; float riderTwoCarriedWeight = 0; int hungerPercent = 0; int damagePercent = 0; //The below are calculated values, do not change float mountStrength = 0; float mountMaxSpeed = 0; boolean isHorse = false; boolean isUnicorn = false; float shoeBonus = 0; float saddleBonus = 0; if (horse) { mountStrength = 25; mountMaxSpeed = 30; isHorse = true; isUnicorn = false; } if (hellHorse) { mountStrength = 35; mountMaxSpeed = 32; isHorse = true; isUnicorn = false; } if (unicorn) { mountStrength = 30; mountMaxSpeed = 33; isHorse = false; isUnicorn = true; } int hunger = hungerPercent * 65535 / 100; int damage = damagePercent * 65535 / 100; float factor = 0.5F; if (hunger < 45000) { factor += 0.2F; } if (hunger < 10000) { factor += 0.1F; } if (damage < 10000) { factor += 0.1F; } else if (damage > 20000) { factor -= 0.5F; } else if (damage > 45000) { factor -= 0.7F; } if ((isHorse) || (isUnicorn)) { if (isShoed) { shoeBonus += Math.max(10.0F, horseShoe1QL) / 2000.0F; shoeBonus += horseShoe1WoA / 2000.0F; shoeBonus += horseShoe1Rarity * 0.03F; shoeBonus += Math.max(10.0F, horseShoe2QL) / 2000.0F; shoeBonus += horseShoe2WoA / 2000.0F; shoeBonus += horseShoe2Rarity * 0.03F; shoeBonus += Math.max(10.0F, horseShoe3QL) / 2000.0F; shoeBonus += horseShoe3WoA / 2000.0F; shoeBonus += horseShoe3Rarity * 0.03F; shoeBonus += Math.max(10.0F, horseShoe4QL) / 2000.0F; shoeBonus += horseShoe4WoA / 2000.0F; shoeBonus += horseShoe4Rarity * 0.03F; factor += shoeBonus; } } float postperc = 0; float negtperc = 0; float tperc = 0; float poswmod = 0; float negwmod = 0; float wmod = 0; float weightPenalty = 0; if (trait1) { postperc += 0.1; } if (trait3) { poswmod += 10000; } if (trait4) { postperc += 0.2; } if (trait5) { poswmod += 20000; } if (trait6) { postperc += 0.1; } if (trait6) { poswmod += 10000; } if (trait8) { negtperc -= 0.1; } if (trait9) { negtperc -= 0.3; } if (trait11) {negwmod -= 30000; } if (trait23) {postperc += 0.025; } if (isRidden) { if (isSaddled) { saddleBonus += Math.max(10.0F, saddleQL) / 1000.0F; saddleBonus += saddleRarity * 0.03F; saddleBonus += saddleWoA / 2000.0F; } factor += saddleBonus; mountCarriedWeight += Math.max(30000, riderOneFatLevel * 1000); mountCarriedWeight += riderOneCarriedWeight; if (isUnicorn) { if (isSecondRider) { mountCarriedWeight += Math.max(30000, riderTwoFatLevel * 1000); mountCarriedWeight += riderTwoCarriedWeight; } } } float allFactor = 0; float minFactor = 0; float maxFactor = 0; float allWeightPenalty = 0; float minWeightPenalty = 0; float maxWeightPenalty = 0; //factor += tperc; allFactor = factor + negtperc + postperc; minFactor = factor + negtperc; maxFactor = factor + postperc; if (mountCarriedWeight > (mountStrength * 5000 + poswmod + negwmod)) { allWeightPenalty = (float)(0.15D * (mountCarriedWeight - mountStrength * 5000.0D - poswmod - negwmod) / 50000.0D); } allFactor -= allWeightPenalty; if (mountCarriedWeight > (mountStrength * 5000 + negwmod)) { minWeightPenalty = (float)(0.15D * (mountCarriedWeight - mountStrength * 5000.0D - negwmod) / 50000.0D); } minFactor -= minWeightPenalty; if (mountCarriedWeight > (mountStrength * 5000 + poswmod)) { maxWeightPenalty = (float)(0.15D * (mountCarriedWeight - mountStrength * 5000.0D - poswmod) / 50000.0D); } maxFactor -= maxWeightPenalty; int allSpeed = (int)Math.max(0.0D, Math.min(127.0D, allFactor * mountMaxSpeed)); int minSpeed = (int)Math.max(0.0D, Math.min(127.0D, minFactor * mountMaxSpeed)); int maxSpeed = (int)Math.max(0.0D, Math.min(127.0D, maxFactor * mountMaxSpeed)); System.out.println("If the mount is classified as a horse, all traits (even negative ones) must pass"); System.out.println("intermittent Soul Strength checks to stay active."); System.out.println(""); System.out.println(""); System.out.println("shoeBonus = " + shoeBonus); System.out.println("saddleBonus = " + saddleBonus); System.out.println(""); System.out.println("All traits active weight penalty = " + allWeightPenalty); System.out.println("Worst traits active weight penalty = " + minWeightPenalty); System.out.println("Best traits active weight penalty = " + maxWeightPenalty); System.out.println(""); System.out.println("All traits active speed = " + allSpeed); System.out.println("Worst traits active speed = " + minSpeed); System.out.println("Best traits active speed = " + maxSpeed); } }