blob: 6f98d4df774786e92da1001c7a1adf39073aea85 [file] [log] [blame] [raw]
package li.cil.oc.server.component
import li.cil.oc.Settings
import li.cil.oc.api
import li.cil.oc.api.machine.Arguments
import li.cil.oc.api.machine.Callback
import li.cil.oc.api.machine.Context
import li.cil.oc.api.network.Visibility
import li.cil.oc.api.prefab
import net.minecraft.nbt.NBTTagCompound
class UpgradeExperience extends prefab.ManagedEnvironment {
override val node = api.Network.newNode(this, Visibility.Network).
withComponent("experience").
withConnector(30 * Settings.get.bufferPerLevel).
create()
var experience = 0.0
var level = 0
def xpForLevel(level: Int) =
if (level == 0) 0
else Settings.get.baseXpToLevel + Math.pow(level * Settings.get.constantXpGrowth, Settings.get.exponentialXpGrowth)
def xpForNextLevel = xpForLevel(level + 1)
def addExperience(value: Double) {
if (level < 30) {
experience = experience + value
if (experience >= xpForNextLevel) {
updateXpInfo()
}
}
}
def updateXpInfo() {
// xp(level) = base + (level * const) ^ exp
// pow(xp(level) - base, 1/exp) / const = level
level = math.min((Math.pow(experience - Settings.get.baseXpToLevel, 1 / Settings.get.exponentialXpGrowth) / Settings.get.constantXpGrowth).toInt, 30)
if (node != null) {
node.setLocalBufferSize(Settings.get.bufferPerLevel * level)
}
}
@Callback(direct = true, doc = """function():number -- The current level of experience stored in this experience upgrade.""")
def level(context: Context, args: Arguments): Array[AnyRef] = {
val xpNeeded = xpForNextLevel - xpForLevel(level)
val xpProgress = math.max(0, experience - xpForLevel(level))
result(level + xpProgress / xpNeeded)
}
override def save(nbt: NBTTagCompound) {
super.save(nbt)
nbt.setDouble(Settings.namespace + "xp", experience)
}
override def load(nbt: NBTTagCompound) {
super.load(nbt)
experience = nbt.getDouble(Settings.namespace + "xp") max 0
updateXpInfo()
}
}