Move all logic regarding food / regeneration to MatteryFoodData
This commit is contained in:
parent
a34b485e68
commit
c4d5ffefa5
@ -5,15 +5,22 @@ import ru.dbotthepony.mc.otm.core.math.Decimal
|
|||||||
import ru.dbotthepony.mc.otm.core.math.defineDecimal
|
import ru.dbotthepony.mc.otm.core.math.defineDecimal
|
||||||
|
|
||||||
object PlayerConfig : AbstractConfig("player") {
|
object PlayerConfig : AbstractConfig("player") {
|
||||||
|
init {
|
||||||
|
builder.push("Android")
|
||||||
|
}
|
||||||
|
|
||||||
val REGENERATE_ENERGY: Boolean by builder
|
val REGENERATE_ENERGY: Boolean by builder
|
||||||
.comment("If (technically) hunger is above threshold, it turns into energy")
|
|
||||||
.comment("This setting controls whenever to regenerate small amount of energy while eating as Android")
|
.comment("This setting controls whenever to regenerate small amount of energy while eating as Android")
|
||||||
.comment("And also whenever to regenerate energy while in peaceful")
|
.comment("And also whenever to regenerate energy while in peaceful")
|
||||||
.comment("If this is disabled, any (technically) excess hunger will be nullified, unless playing on peaceful difficulty.")
|
|
||||||
.define("REGENERATE_ENERGY", true)
|
.define("REGENERATE_ENERGY", true)
|
||||||
|
|
||||||
|
val REGENERATE_ENERGY_IN_PEACEFUL: Boolean by builder
|
||||||
|
.comment("Regenerate energy while in peaceful")
|
||||||
|
.comment("This is disabled by default because this is easily exploitable")
|
||||||
|
.define("REGENERATE_ENERGY_IN_PEACEFUL", false)
|
||||||
|
|
||||||
val TIME_BETWEEN_NATURAL_REGENERATION: Int by builder
|
val TIME_BETWEEN_NATURAL_REGENERATION: Int by builder
|
||||||
.comment("Time in ticks between natural health regeneration ticks")
|
.comment("Time in ticks between natural health regeneration ticks for Android")
|
||||||
.comment("Default value is meant to be one of downsides of being an android,")
|
.comment("Default value is meant to be one of downsides of being an android,")
|
||||||
.comment("so please, don't blindly buff it, players have ability to research into Nanobots Regeneration,")
|
.comment("so please, don't blindly buff it, players have ability to research into Nanobots Regeneration,")
|
||||||
.comment("which provide superior regeneration on average than human players.")
|
.comment("which provide superior regeneration on average than human players.")
|
||||||
@ -24,6 +31,10 @@ object PlayerConfig : AbstractConfig("player") {
|
|||||||
.comment("for android players, since 'hunger' (for compatibility) is managed by mod in such case")
|
.comment("for android players, since 'hunger' (for compatibility) is managed by mod in such case")
|
||||||
.defineInRange("TIME_BETWEEN_NATURAL_REGENERATION", 120, 0, Int.MAX_VALUE)
|
.defineInRange("TIME_BETWEEN_NATURAL_REGENERATION", 120, 0, Int.MAX_VALUE)
|
||||||
|
|
||||||
|
init {
|
||||||
|
builder.pop()
|
||||||
|
}
|
||||||
|
|
||||||
object NanobotsRegeneration {
|
object NanobotsRegeneration {
|
||||||
init {
|
init {
|
||||||
builder.push("NanobotsRegeneration")
|
builder.push("NanobotsRegeneration")
|
||||||
|
@ -2,6 +2,9 @@ package ru.dbotthepony.mc.otm.player
|
|||||||
|
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.world.Difficulty
|
import net.minecraft.world.Difficulty
|
||||||
|
import net.minecraft.world.damagesource.DamageSource
|
||||||
|
import net.minecraft.world.effect.MobEffectInstance
|
||||||
|
import net.minecraft.world.effect.MobEffects
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.food.FoodConstants
|
import net.minecraft.world.food.FoodConstants
|
||||||
import net.minecraft.world.food.FoodData
|
import net.minecraft.world.food.FoodData
|
||||||
@ -9,15 +12,24 @@ import net.minecraft.world.food.FoodProperties
|
|||||||
import net.minecraft.world.level.GameRules
|
import net.minecraft.world.level.GameRules
|
||||||
import ru.dbotthepony.mc.otm.config.IFoodRegenerationValues
|
import ru.dbotthepony.mc.otm.config.IFoodRegenerationValues
|
||||||
import ru.dbotthepony.mc.otm.config.PlayerConfig
|
import ru.dbotthepony.mc.otm.config.PlayerConfig
|
||||||
|
import ru.dbotthepony.mc.otm.core.damageType
|
||||||
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
|
import ru.dbotthepony.mc.otm.core.math.getDecimal
|
||||||
|
import ru.dbotthepony.mc.otm.core.math.set
|
||||||
import ru.dbotthepony.mc.otm.core.nbt.set
|
import ru.dbotthepony.mc.otm.core.nbt.set
|
||||||
|
import ru.dbotthepony.mc.otm.registry.MDamageTypes
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class MatteryFoodData(private var player: Player) : FoodData() {
|
class MatteryFoodData(private var player: Player) : FoodData() {
|
||||||
private fun add(foodLevel: Int, saturation: Float) {
|
private fun add(foodLevel: Int, saturation: Float) {
|
||||||
this.foodLevel = min(this.foodLevel + foodLevel, PlayerConfig.Food.HARD_FOOD_LIMIT)
|
if (player.matteryPlayer.isAndroid && PlayerConfig.REGENERATE_ENERGY) {
|
||||||
this.saturationLevel = min(this.saturationLevel + saturation, this.foodLevel + PlayerConfig.Food.OVERSATURATION_LIMIT.toFloat()).coerceAtLeast(0f)
|
energyToDrain -= PlayerConfig.ANDROID_ENERGY_PER_HUNGER_POINT * foodLevel + PlayerConfig.ANDROID_ENERGY_PER_HUNGER_POINT * saturation
|
||||||
|
} else if (!player.matteryPlayer.isAndroid) {
|
||||||
|
this.foodLevel = min(this.foodLevel + foodLevel, PlayerConfig.Food.HARD_FOOD_LIMIT)
|
||||||
|
this.saturationLevel = min(this.saturationLevel + saturation, this.foodLevel + PlayerConfig.Food.OVERSATURATION_LIMIT.toFloat()).coerceAtLeast(0f)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun eat(foodLevelModifier: Int, saturationLevelModifier: Float) {
|
override fun eat(foodLevelModifier: Int, saturationLevelModifier: Float) {
|
||||||
@ -29,11 +41,12 @@ class MatteryFoodData(private var player: Player) : FoodData() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun needsFood(): Boolean {
|
override fun needsFood(): Boolean {
|
||||||
return foodLevel < PlayerConfig.Food.SOFT_FOOD_LIMIT
|
return player.matteryPlayer.isAndroid || foodLevel < PlayerConfig.Food.SOFT_FOOD_LIMIT
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addExhaustion(exhaustion: Float) {
|
override fun addExhaustion(exhaustion: Float) {
|
||||||
this.exhaustionLevel = min(this.exhaustionLevel + exhaustion, PlayerConfig.Food.EXHAUSTION_LIMIT.toFloat())
|
// store exhaustion as usual, and handle its reduction in tick for both humans and androids
|
||||||
|
this.exhaustionLevel = min(this.exhaustionLevel + exhaustion, PlayerConfig.Food.EXHAUSTION_LIMIT.toFloat()).coerceAtLeast(0f)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun readAdditionalSaveData(compoundTag: CompoundTag) {
|
override fun readAdditionalSaveData(compoundTag: CompoundTag) {
|
||||||
@ -41,25 +54,35 @@ class MatteryFoodData(private var player: Player) : FoodData() {
|
|||||||
|
|
||||||
if ("lastFoodLevel" in compoundTag)
|
if ("lastFoodLevel" in compoundTag)
|
||||||
lastFoodLevel = compoundTag.getInt("lastFoodLevel")
|
lastFoodLevel = compoundTag.getInt("lastFoodLevel")
|
||||||
|
|
||||||
|
if ("foodAndroidEnergyToDrain" in compoundTag)
|
||||||
|
energyToDrain = compoundTag.getDecimal("foodAndroidEnergyToDrain")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addAdditionalSaveData(compoundTag: CompoundTag) {
|
override fun addAdditionalSaveData(compoundTag: CompoundTag) {
|
||||||
super.addAdditionalSaveData(compoundTag)
|
super.addAdditionalSaveData(compoundTag)
|
||||||
compoundTag["lastFoodLevel"] = lastFoodLevel
|
compoundTag["lastFoodLevel"] = lastFoodLevel
|
||||||
|
compoundTag["foodAndroidEnergyToDrain"] = energyToDrain
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var energyToDrain = Decimal.ZERO
|
||||||
|
|
||||||
private fun tickExhaustion() {
|
private fun tickExhaustion() {
|
||||||
if (exhaustionLevel >= EXHAUSTION_PER_HUNGER_POINT) {
|
if (exhaustionLevel >= EXHAUSTION_PER_HUNGER_POINT) {
|
||||||
var points = (exhaustionLevel / EXHAUSTION_PER_HUNGER_POINT).toInt()
|
var points = (exhaustionLevel / EXHAUSTION_PER_HUNGER_POINT).toInt()
|
||||||
exhaustionLevel %= EXHAUSTION_PER_HUNGER_POINT
|
exhaustionLevel %= EXHAUSTION_PER_HUNGER_POINT
|
||||||
|
|
||||||
if (saturationLevel > 0f) {
|
if (player.matteryPlayer.isAndroid) {
|
||||||
val satisfied = min(saturationLevel.roundToInt(), points)
|
energyToDrain += PlayerConfig.ANDROID_ENERGY_PER_HUNGER_POINT * points
|
||||||
points -= satisfied
|
} else {
|
||||||
saturationLevel -= satisfied
|
if (saturationLevel > 0f) {
|
||||||
}
|
val satisfied = min(saturationLevel.roundToInt(), points)
|
||||||
|
points -= satisfied
|
||||||
|
saturationLevel -= satisfied
|
||||||
|
}
|
||||||
|
|
||||||
foodLevel = max(0, foodLevel - points)
|
foodLevel = max(0, foodLevel - points)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,37 +105,96 @@ class MatteryFoodData(private var player: Player) : FoodData() {
|
|||||||
override fun tick(player: Player) {
|
override fun tick(player: Player) {
|
||||||
this.player = player
|
this.player = player
|
||||||
|
|
||||||
if (player.matteryPlayer.isAndroid)
|
|
||||||
return
|
|
||||||
|
|
||||||
lastFoodLevel = foodLevel
|
|
||||||
tickExhaustion()
|
tickExhaustion()
|
||||||
|
|
||||||
if (
|
if (player.matteryPlayer.isAndroid) {
|
||||||
player.level().gameRules.getBoolean(GameRules.RULE_NATURAL_REGENERATION) &&
|
if (energyToDrain > Decimal.ZERO)
|
||||||
(tickRegeneration(PlayerConfig.Food.FAST_REGEN) || tickRegeneration(PlayerConfig.Food.SLOW_REGEN))
|
energyToDrain -= player.matteryPlayer.androidEnergy.extractEnergy(energyToDrain, false)
|
||||||
) {
|
else if (energyToDrain < Decimal.ZERO)
|
||||||
// do nothing
|
energyToDrain += player.matteryPlayer.androidEnergy.receiveEnergy(-energyToDrain, false)
|
||||||
} else if (PlayerConfig.Food.ENABLE_STARVATION && foodLevel <= 0) {
|
|
||||||
if (++tickTimer >= PlayerConfig.Food.STARVATION_TICKS) {
|
|
||||||
tickTimer = 0
|
|
||||||
|
|
||||||
val threshold = when (player.level().difficulty) {
|
if (player.level().difficulty == Difficulty.PEACEFUL && PlayerConfig.REGENERATE_ENERGY_IN_PEACEFUL)
|
||||||
Difficulty.PEACEFUL -> Float.POSITIVE_INFINITY
|
player.matteryPlayer.androidEnergy.receiveEnergy(PlayerConfig.ANDROID_ENERGY_PER_HUNGER_POINT, false)
|
||||||
Difficulty.EASY -> PlayerConfig.Food.STARVATION_HEALTH_LIMIT_EASY.toFloat()
|
|
||||||
Difficulty.NORMAL -> PlayerConfig.Food.STARVATION_HEALTH_LIMIT_NORMAL.toFloat()
|
if (!player.matteryPlayer.androidHasEnergy) {
|
||||||
Difficulty.HARD -> PlayerConfig.Food.STARVATION_HEALTH_LIMIT_HARD.toFloat()
|
if (++tickTimer >= 20 && player.hurt(DamageSource(player.level().registryAccess().damageType(MDamageTypes.ANDROID_DISCHARGE)), 1f)) {
|
||||||
|
tickTimer = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player.health > threshold) {
|
val effect = player.activeEffectsMap[MobEffects.MOVEMENT_SLOWDOWN]
|
||||||
player.hurt(player.damageSources().starve(), 1.0f)
|
|
||||||
|
if (effect == null || effect.duration < 40 || effect.amplifier < 2) {
|
||||||
|
player.addEffect(MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, effect?.duration?.coerceAtLeast(60) ?: 60, effect?.amplifier?.coerceAtLeast(2) ?: 2, false, false))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (player.isHurt && player.level().gameRules.getBoolean(GameRules.RULE_NATURAL_REGENERATION)) {
|
||||||
|
if (++tickTimer >= PlayerConfig.TIME_BETWEEN_NATURAL_REGENERATION) {
|
||||||
|
player.heal(1f)
|
||||||
|
addExhaustion(6f)
|
||||||
|
tickTimer = 0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tickTimer = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tickTimer = 0
|
lastFoodLevel = foodLevel
|
||||||
|
energyToDrain = Decimal.ZERO
|
||||||
|
|
||||||
|
if (
|
||||||
|
player.level().gameRules.getBoolean(GameRules.RULE_NATURAL_REGENERATION) &&
|
||||||
|
(tickRegeneration(PlayerConfig.Food.FAST_REGEN) || tickRegeneration(PlayerConfig.Food.SLOW_REGEN))
|
||||||
|
) {
|
||||||
|
// do nothing
|
||||||
|
} else if (PlayerConfig.Food.ENABLE_STARVATION && foodLevel <= 0) {
|
||||||
|
if (++tickTimer >= PlayerConfig.Food.STARVATION_TICKS) {
|
||||||
|
tickTimer = 0
|
||||||
|
|
||||||
|
val threshold = when (player.level().difficulty) {
|
||||||
|
Difficulty.PEACEFUL -> Float.POSITIVE_INFINITY
|
||||||
|
Difficulty.EASY -> PlayerConfig.Food.STARVATION_HEALTH_LIMIT_EASY.toFloat()
|
||||||
|
Difficulty.NORMAL -> PlayerConfig.Food.STARVATION_HEALTH_LIMIT_NORMAL.toFloat()
|
||||||
|
Difficulty.HARD -> PlayerConfig.Food.STARVATION_HEALTH_LIMIT_HARD.toFloat()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.health > threshold) {
|
||||||
|
player.hurt(player.damageSources().starve(), 1.0f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tickTimer = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getFoodLevel(): Int {
|
||||||
|
if (player.matteryPlayer.isAndroid)
|
||||||
|
return if (player.matteryPlayer.androidHasEnergy) PlayerConfig.Food.SOFT_FOOD_LIMIT else 0
|
||||||
|
|
||||||
|
return super.getFoodLevel()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLastFoodLevel(): Int {
|
||||||
|
if (player.matteryPlayer.isAndroid)
|
||||||
|
return getFoodLevel()
|
||||||
|
|
||||||
|
return super.getLastFoodLevel()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getExhaustionLevel(): Float {
|
||||||
|
if (player.matteryPlayer.isAndroid && player.matteryPlayer.androidHasEnergy)
|
||||||
|
return 0f
|
||||||
|
|
||||||
|
return super.getExhaustionLevel()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSaturationLevel(): Float {
|
||||||
|
if (player.matteryPlayer.isAndroid)
|
||||||
|
return if (player.matteryPlayer.androidHasEnergy) player.matteryPlayer.androidEnergy.batteryLevel.percentage(player.matteryPlayer.androidEnergy.maxBatteryLevel) * PlayerConfig.Food.SOFT_FOOD_LIMIT else 0f
|
||||||
|
|
||||||
|
return super.getSaturationLevel()
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val EXHAUSTION_PER_HUNGER_POINT = 4f
|
const val EXHAUSTION_PER_HUNGER_POINT = 4f
|
||||||
}
|
}
|
||||||
|
@ -436,8 +436,6 @@ class MatteryPlayer(val ply: Player) {
|
|||||||
|
|
||||||
private var shouldPlaySound = false
|
private var shouldPlaySound = false
|
||||||
private val research = IdentityHashMap<AndroidResearchType, AndroidResearch>()
|
private val research = IdentityHashMap<AndroidResearchType, AndroidResearch>()
|
||||||
private var nextDischargeHurt = 20
|
|
||||||
private var nextHealTick = 0
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This returns if player is an Android or will become one on death/sleep/etc
|
* This returns if player is an Android or will become one on death/sleep/etc
|
||||||
@ -563,6 +561,9 @@ class MatteryPlayer(val ply: Player) {
|
|||||||
*/
|
*/
|
||||||
val androidEnergy = BatteryBackedEnergyStorage(ply, syncher, PlayerConfig.ANDROID_MAX_ENERGY, PlayerConfig.ANDROID_MAX_ENERGY, true)
|
val androidEnergy = BatteryBackedEnergyStorage(ply, syncher, PlayerConfig.ANDROID_MAX_ENERGY, PlayerConfig.ANDROID_MAX_ENERGY, true)
|
||||||
|
|
||||||
|
val androidHasEnergy: Boolean
|
||||||
|
get() = androidEnergy.batteryLevel > Decimal.TEN
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [IMatteryEnergyStorage] instance, representing Exopack battery charge
|
* [IMatteryEnergyStorage] instance, representing Exopack battery charge
|
||||||
*/
|
*/
|
||||||
@ -584,8 +585,6 @@ class MatteryPlayer(val ply: Player) {
|
|||||||
savetables.bool(::isExopackCraftingUpgraded, "isExoSuitCraftingUpgraded")
|
savetables.bool(::isExopackCraftingUpgraded, "isExoSuitCraftingUpgraded")
|
||||||
savetables.bool(::isExopackEnderAccessInstalled, "isExopackEnderAccessUpgraded")
|
savetables.bool(::isExopackEnderAccessInstalled, "isExopackEnderAccessUpgraded")
|
||||||
savetables.bool(::acceptExopackChargeFromWirelessCharger)
|
savetables.bool(::acceptExopackChargeFromWirelessCharger)
|
||||||
savetables.int(::nextDischargeHurt)
|
|
||||||
savetables.int(::nextHealTick)
|
|
||||||
|
|
||||||
savetables.vector(::lastLiquidPosition)
|
savetables.vector(::lastLiquidPosition)
|
||||||
savetables.codec(::lastDimension, ResourceLocation.CODEC)
|
savetables.codec(::lastDimension, ResourceLocation.CODEC)
|
||||||
@ -1213,81 +1212,6 @@ class MatteryPlayer(val ply: Player) {
|
|||||||
|
|
||||||
lastLiquidPosition = ply.position
|
lastLiquidPosition = ply.position
|
||||||
}
|
}
|
||||||
|
|
||||||
val stats = ply.foodData
|
|
||||||
val fourTimesTheHunger = PlayerConfig.ANDROID_ENERGY_PER_HUNGER_POINT * 4
|
|
||||||
|
|
||||||
// истощение
|
|
||||||
if (stats.exhaustionLevel > 0f) {
|
|
||||||
val extracted = androidEnergy.extractEnergy(PlayerConfig.ANDROID_ENERGY_PER_HUNGER_POINT * (stats.exhaustionLevel / 4f), false)
|
|
||||||
stats.setExhaustion(stats.exhaustionLevel - (extracted / PlayerConfig.ANDROID_ENERGY_PER_HUNGER_POINT).toFloat() * 4f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обычный голод
|
|
||||||
while (
|
|
||||||
stats.foodLevel < 18 &&
|
|
||||||
androidEnergy.batteryLevel >= fourTimesTheHunger &&
|
|
||||||
androidEnergy.extractEnergyExact(PlayerConfig.ANDROID_ENERGY_PER_HUNGER_POINT, false)
|
|
||||||
) {
|
|
||||||
stats.foodLevel++
|
|
||||||
}
|
|
||||||
|
|
||||||
// "поглощение" излишек голода, как при мирном режиме, так и при поедании обычной еды
|
|
||||||
if (PlayerConfig.REGENERATE_ENERGY) {
|
|
||||||
while (stats.foodLevel > 18 && androidEnergy.receiveEnergyExact(PlayerConfig.ANDROID_ENERGY_PER_HUNGER_POINT / 2, false)) {
|
|
||||||
stats.foodLevel--
|
|
||||||
}
|
|
||||||
} else if (ply.level().difficulty != Difficulty.PEACEFUL) {
|
|
||||||
stats.foodLevel = stats.foodLevel.coerceAtMost(18)
|
|
||||||
}
|
|
||||||
|
|
||||||
val foodLevel = stats.foodLevel.toFloat()
|
|
||||||
|
|
||||||
// насыщение
|
|
||||||
if (stats.saturationLevel < foodLevel && androidEnergy.batteryLevel >= fourTimesTheHunger) {
|
|
||||||
val extracted = androidEnergy.extractEnergy(PlayerConfig.ANDROID_ENERGY_PER_HUNGER_POINT * (foodLevel - stats.saturationLevel), false)
|
|
||||||
stats.setSaturation(stats.saturationLevel + (extracted / PlayerConfig.ANDROID_ENERGY_PER_HUNGER_POINT).toFloat())
|
|
||||||
}
|
|
||||||
|
|
||||||
if (androidEnergy.batteryLevel <= Decimal.TEN && !ply.isCreative && ply.level().difficulty != Difficulty.PEACEFUL) {
|
|
||||||
if (stats.saturationLevel > 1f) {
|
|
||||||
if (androidEnergy.receiveEnergyExact(PlayerConfig.ANDROID_ENERGY_PER_HUNGER_POINT, false)) {
|
|
||||||
stats.setSaturation(stats.saturationLevel - 1f)
|
|
||||||
}
|
|
||||||
} else if (stats.saturationLevel > 0f) {
|
|
||||||
val received = androidEnergy.receiveEnergy(PlayerConfig.ANDROID_ENERGY_PER_HUNGER_POINT * stats.saturationLevel, false)
|
|
||||||
stats.setSaturation(stats.saturationLevel - (received / PlayerConfig.ANDROID_ENERGY_PER_HUNGER_POINT).toFloat())
|
|
||||||
} else if (stats.foodLevel > 0) {
|
|
||||||
// так как голод не тикает для андроидов, "умереть с голоду" мы не можем
|
|
||||||
// но со стороны будет выглядеть как будто мы умираем с голода
|
|
||||||
if (androidEnergy.receiveEnergyExact(PlayerConfig.ANDROID_ENERGY_PER_HUNGER_POINT, false)) {
|
|
||||||
stats.foodLevel--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (androidEnergy.batteryLevel <= Decimal.TEN) {
|
|
||||||
if (--nextDischargeHurt <= 0 && ply.hurt(DamageSource(ply.level().registryAccess().damageType(MDamageTypes.ANDROID_DISCHARGE)), 1f)) {
|
|
||||||
nextDischargeHurt = 20
|
|
||||||
}
|
|
||||||
|
|
||||||
val effect = ply.activeEffectsMap[MobEffects.MOVEMENT_SLOWDOWN]
|
|
||||||
|
|
||||||
if (effect == null || effect.duration < 40 || effect.amplifier < 2) {
|
|
||||||
ply.addEffect(MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, effect?.duration?.coerceAtLeast(60) ?: 60, effect?.amplifier?.coerceAtLeast(2) ?: 2, false, false))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
nextDischargeHurt = 20
|
|
||||||
|
|
||||||
if (ply.isHurt && ply.level().gameRules.getBoolean(GameRules.RULE_NATURAL_REGENERATION)) {
|
|
||||||
if (--nextHealTick <= 0) {
|
|
||||||
nextHealTick = if (ply.level().difficulty == Difficulty.PEACEFUL) 10 else PlayerConfig.TIME_BETWEEN_NATURAL_REGENERATION
|
|
||||||
ply.heal(1f)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
nextHealTick = if (ply.level().difficulty == Difficulty.PEACEFUL) 10 else PlayerConfig.TIME_BETWEEN_NATURAL_REGENERATION
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (feature in featureMap.values) {
|
for (feature in featureMap.values) {
|
||||||
|
Loading…
Reference in New Issue
Block a user