New Ripple's score server https://ripple.moe

wifipiano2.py 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. """
  2. Wifipiano 2
  3. This file has been written taking by reference code from
  4. osu-performance (https://github.com/ppy/osu-performance)
  5. by Tom94, licensed under the GNU AGPL 3 License.
  6. """
  7. from common.constants import mods
  8. from common.log import logUtils as log
  9. from constants import exceptions
  10. class piano:
  11. __slots__ = ["beatmap", "score", "pp"]
  12. def __init__(self, __beatmap, __score):
  13. self.beatmap = __beatmap
  14. self.score = __score
  15. self.pp = 0
  16. self.getPP()
  17. def getPP(self):
  18. try:
  19. stars = self.beatmap.starsMania
  20. if stars == 0:
  21. # This beatmap can't be converted to mania
  22. raise exceptions.invalidBeatmapException()
  23. od = self.beatmap.OD
  24. objects = self.score.c50+self.score.c100+self.score.c300+self.score.cKatu+self.score.cGeki+self.score.cMiss
  25. score = self.score.score
  26. accuracy = self.score.accuracy
  27. scoreMods = self.score.mods
  28. log.debug("[WIFIPIANO2] SCORE DATA: Stars: {stars}, OD: {od}, obj: {objects}, score: {score}, acc: {acc}, mods: {mods}".format(stars=stars, od=od, objects=objects, score=score, acc=accuracy, mods=scoreMods))
  29. # ---------- STRAIN PP
  30. # Scale score to mods multiplier
  31. scoreMultiplier = 1.0
  32. # Doubles score if EZ/HT
  33. if scoreMods & mods.EASY != 0:
  34. scoreMultiplier *= 0.50
  35. #if scoreMods & mods.HALFTIME != 0:
  36. # scoreMultiplier *= 0.50
  37. # Calculate strain PP
  38. if scoreMultiplier <= 0:
  39. strainPP = 0
  40. else:
  41. score *= int(1.0 / scoreMultiplier)
  42. strainPP = pow(5.0 * max(1.0, stars / 0.0825) - 4.0, 3.0) / 110000.0
  43. strainPP *= 1 + 0.1 * min(1.0, float(objects) / 1500.0)
  44. if score <= 500000:
  45. strainPP *= (float(score) / 500000.0) * 0.1
  46. elif score <= 600000:
  47. strainPP *= 0.1 + float(score - 500000) / 100000.0 * 0.2
  48. elif score <= 700000:
  49. strainPP *= 0.3 + float(score - 600000) / 100000.0 * 0.35
  50. elif score <= 800000:
  51. strainPP *= 0.65 + float(score - 700000) / 100000.0 * 0.20
  52. elif score <= 900000:
  53. strainPP *= 0.85 + float(score - 800000) / 100000.0 * 0.1
  54. else:
  55. strainPP *= 0.95 + float(score - 900000) / 100000.0 * 0.05
  56. # ---------- ACC PP
  57. # Makes sure OD is in range 0-10. If this is done elsewhere, remove this.
  58. scrubbedOD = min(10.0, max(0, 10.0 - od))
  59. # Old formula but done backwards.
  60. hitWindow300 = (34 + 3 * scrubbedOD)
  61. # Increases hitWindow if EZ is on
  62. if scoreMods & mods.EASY != 0:
  63. hitWindow300 *= 1.4
  64. # Fiddles with DT and HT to make them match hitWindow300's ingame.
  65. if scoreMods & mods.DOUBLETIME != 0:
  66. hitWindow300 *= 1.5
  67. elif scoreMods & mods.HALFTIME != 0:
  68. hitWindow300 *= 0.75
  69. # makes hit window match what it is ingame.
  70. hitWindow300 = int(hitWindow300) + 0.5
  71. if scoreMods & mods.DOUBLETIME != 0:
  72. hitWindow300 /= 1.5
  73. elif scoreMods & mods.HALFTIME != 0:
  74. hitWindow300 /= 0.75
  75. # Calculate accuracy PP
  76. accPP = pow((150.0 / hitWindow300) * pow(accuracy, 16), 1.8) * 2.5
  77. accPP *= min(1.15, pow(float(objects) / 1500.0, 0.3))
  78. # ---------- TOTAL PP
  79. multiplier = 1.1
  80. if scoreMods & mods.NOFAIL != 0:
  81. multiplier *= 0.90
  82. if scoreMods & mods.SPUNOUT != 0:
  83. multiplier *= 0.95
  84. if scoreMods & mods.EASY != 0:
  85. multiplier *= 0.50
  86. pp = pow(pow(strainPP, 1.1) + pow(accPP, 1.1), 1.0 / 1.1) * multiplier
  87. log.debug("[WIFIPIANO2] Calculated PP: {}".format(pp))
  88. self.pp = pp
  89. except exceptions.invalidBeatmapException:
  90. log.warning("Invalid beatmap {}".format(self.beatmap.beatmapID))
  91. self.pp = 0
  92. finally:
  93. return self.pp