diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/DamageTypes.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/DamageTypes.kt index 40bcca1c9..525fbf309 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/DamageTypes.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/DamageTypes.kt @@ -23,6 +23,7 @@ fun registerDamageTypes(context: BootstapContext) { context.register(MDamageTypes.COSMIC_RAYS, DamageType("otm_cosmic_rays", DamageScaling.NEVER, 0f)) context.register(MDamageTypes.EXPLOSIVE_HAMMER, DamageType("otm_explosive_hammer", DamageScaling.NEVER, 0.1f)) context.register(MDamageTypes.HAMMER_NAIL, DamageType("otm_hammer_nail", DamageScaling.NEVER, 0.1f)) + context.register(MDamageTypes.ANDROID_DISCHARGE, DamageType("otm_android_discharge", DamageScaling.NEVER, 4.0f)) } fun registerDamageTypeTags(provider: TagsProvider.Delegate) { @@ -38,14 +39,17 @@ fun registerDamageTypeTags(provider: TagsProvider.Delegate) { .add(MDamageTypes.EMP) .add(MDamageTypes.SHOCKWAVE) .add(MDamageTypes.COSMIC_RAYS) + .add(MDamageTypes.ANDROID_DISCHARGE) ignoreMagic .add(MDamageTypes.EXOPACK_PROBE) .add(MDamageTypes.BECOME_ANDROID) .add(MDamageTypes.BECOME_HUMANE) .add(MDamageTypes.COSMIC_RAYS) + .add(MDamageTypes.ANDROID_DISCHARGE) ignoreInvl .add(MDamageTypes.BECOME_HUMANE) .add(MDamageTypes.BECOME_ANDROID) + .add(MDamageTypes.ANDROID_DISCHARGE) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryPlayerCapability.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryPlayerCapability.kt index f7bccfebb..eb75317a7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryPlayerCapability.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryPlayerCapability.kt @@ -11,6 +11,7 @@ import net.minecraft.resources.ResourceLocation import net.minecraft.server.level.ServerPlayer import net.minecraft.tags.TagKey import net.minecraft.world.Difficulty +import net.minecraft.world.damagesource.DamageSource import net.minecraft.world.effect.MobEffect import net.minecraft.world.effect.MobEffectInstance import net.minecraft.world.effect.MobEffects @@ -51,6 +52,8 @@ import ru.dbotthepony.mc.otm.android.AndroidResearchManager import ru.dbotthepony.mc.otm.android.AndroidResearchType import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature import ru.dbotthepony.mc.otm.capability.energy.AndroidPowerSource +import ru.dbotthepony.mc.otm.capability.energy.extractEnergyExact +import ru.dbotthepony.mc.otm.capability.energy.receiveEnergyExact import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.config.AndroidConfig import ru.dbotthepony.mc.otm.container.MatteryContainer @@ -277,6 +280,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial private var shouldPlaySound = false private val research = IdentityHashMap() + private var nextDischargeHurt = 20 // players tracking us // stored separately because EntityTracker and ChunkMup, etc are buried deep and @@ -335,6 +339,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial savetables.bool(::hasExoPack, "hasExoSuit") savetables.bool(::displayExoPack, "displayExoSuit") savetables.bool(::isExoPackCraftingUpgraded, "isExoSuitCraftingUpgraded") + savetables.int(::nextDischargeHurt) savetables.vector(::lastOutsideLiquid) savetables.location(::lastDimension) @@ -876,18 +881,21 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial } val stats = ply.foodData + val fourTimesTheHunger = AndroidConfig.ANDROID_ENERGY_PER_HUNGER_POINT * 4 - while (stats.foodLevel < 18 && androidEnergy.extractEnergy(AndroidConfig.ANDROID_ENERGY_PER_HUNGER_POINT, true) >= AndroidConfig.ANDROID_ENERGY_PER_HUNGER_POINT) { - androidEnergy.extractEnergy(AndroidConfig.ANDROID_ENERGY_PER_HUNGER_POINT, false) - stats.foodLevel = stats.foodLevel + 1 + // Обычный голод + while ( + stats.foodLevel < 18 && + androidEnergy.batteryLevel >= fourTimesTheHunger && + androidEnergy.extractEnergyExact(AndroidConfig.ANDROID_ENERGY_PER_HUNGER_POINT, false) + ) { + stats.foodLevel++ } - // "block" quick regeneration - // also cause power to generate while in peaceful + // "поглощение" излишек голода, как при мирном режиме, так и при поедании обычной еды if (AndroidConfig.REGENERATE_ENERGY) { - while (stats.foodLevel > 18 && androidEnergy.receiveEnergy(AndroidConfig.ANDROID_ENERGY_PER_HUNGER_POINT, true) >= AndroidConfig.ANDROID_ENERGY_PER_HUNGER_POINT) { - androidEnergy.receiveEnergy(AndroidConfig.ANDROID_ENERGY_PER_HUNGER_POINT, false) - stats.foodLevel = stats.foodLevel - 1 + while (stats.foodLevel > 18 && androidEnergy.receiveEnergyExact(AndroidConfig.ANDROID_ENERGY_PER_HUNGER_POINT, false)) { + stats.foodLevel-- } } else if (ply.level().server?.worldData?.difficulty != Difficulty.PEACEFUL) { stats.foodLevel = stats.foodLevel.coerceAtMost(18) @@ -895,15 +903,33 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial val foodLevel = stats.foodLevel.toFloat() - if (stats.saturationLevel < foodLevel) { + // насыщение + if (stats.saturationLevel < foodLevel && androidEnergy.batteryLevel >= fourTimesTheHunger) { val extracted = androidEnergy.extractEnergy(AndroidConfig.ANDROID_ENERGY_PER_HUNGER_POINT * (foodLevel - stats.saturationLevel), false) stats.setSaturation(stats.saturationLevel + (extracted / AndroidConfig.ANDROID_ENERGY_PER_HUNGER_POINT).toFloat()) } - if (stats.exhaustionLevel > 0f) { + // истощение + if (stats.exhaustionLevel > 0f && androidEnergy.batteryLevel >= fourTimesTheHunger) { val extracted = androidEnergy.extractEnergy(AndroidConfig.ANDROID_ENERGY_PER_HUNGER_POINT * (stats.exhaustionLevel / 4f), false) stats.setExhaustion(stats.exhaustionLevel - (extracted / AndroidConfig.ANDROID_ENERGY_PER_HUNGER_POINT).toFloat() * 4f) } + + if (androidEnergy.batteryLevel <= Decimal.TEN && !ply.isCreative && ply.level().server?.worldData?.difficulty != Difficulty.PEACEFUL) { + if (stats.foodLevel <= 6 || !androidEnergy.receiveEnergyExact(AndroidConfig.ANDROID_ENERGY_PER_HUNGER_POINT, false).also { if (it) stats.foodLevel-- }) { + 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 + } } for (feature in featureMap.values) { @@ -1223,6 +1249,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial mattery.iteration++ mattery.shouldSendIteration = true mattery.deathLog.addLast(ply.tickCount to ply.combatTracker.deathMessage) + mattery.androidEnergy.fillBattery() // если смерть была от разряда батареи, то предотвращаем софтлок while (mattery.deathLog.size > 6) { mattery.deathLog.removeFirst() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MDamageTypes.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MDamageTypes.kt index f4f3b8e8d..a1af1bade 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MDamageTypes.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MDamageTypes.kt @@ -20,4 +20,5 @@ object MDamageTypes { val COSMIC_RAYS = register("cosmic_rays") val EXPLOSIVE_HAMMER = register("explosive_hammer") val HAMMER_NAIL = register("hammer_nail") + val ANDROID_DISCHARGE = register("android_discharge") }