allow to replace android's battery with crude battery in-world

* discharges up to 20% stored energy from ejected battery
* applies debuffs for a short amount of time (5 to 10 seconds)
* deals up to 2.5 hearts of damage to player (lower damage = longers debuffs)
This commit is contained in:
YuRaNnNzZZ 2022-09-10 02:29:41 +03:00
parent 4371ca4f26
commit 05170ca2e0
Signed by: YuRaNnNzZZ
GPG Key ID: 5F71738C85A6006D
3 changed files with 97 additions and 10 deletions

View File

@ -67,6 +67,9 @@ private fun misc(provider: MatteryLanguageProvider) {
gui("exosuit_upgrades.slots_upgrade", "Using this will permanently grant %s slots in Exosuit inventory.")
gui("exosuit_upgrades.crafting_upgrade", "Using this will permanently grant 3x3 crafting grid in Exosuit inventory.")
gui("crude_battery.replace_in_world", "Simplistic nature of this battery allows to replace your energy source in the field without using Android Station.")
gui("crude_battery.replace_in_world_warning", "This operation is very unstable and causes serious damage to your systems!")
gui("power_supplier.active_nodes", "Currently demanding nodes: %s")
misc("battery.single_use", "Single use battery, can not be recharged.")

View File

@ -3,20 +3,26 @@ package ru.dbotthepony.mc.otm.item
import net.minecraft.ChatFormatting
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Rarity
import net.minecraft.world.item.TooltipFlag
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.InteractionHand
import net.minecraft.world.InteractionResultHolder
import net.minecraft.world.effect.MobEffectInstance
import net.minecraft.world.effect.MobEffects
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.*
import net.minecraft.world.level.Level
import net.minecraftforge.common.capabilities.ForgeCapabilities
import net.minecraftforge.common.capabilities.ICapabilityProvider
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.capability.*
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.formatPower
import ru.dbotthepony.mc.otm.core.ifPresentK
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.core.*
import ru.dbotthepony.mc.otm.registry.MRegistry
import ru.dbotthepony.mc.otm.runIfClient
import kotlin.math.roundToInt
class BatteryItem : Item {
open class BatteryItem : Item {
private inner class Power(stack: ItemStack) : EnergyCapacitorItem(stack, this@BatteryItem.storage, this@BatteryItem.receive, this@BatteryItem.extract, initialBatteryLevel = this@BatteryItem.initialBatteryLevel) {
override fun extractEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
if (isCreative) return howMuch
@ -120,4 +126,82 @@ class BatteryItem : Item {
private val INFINITE_STORAGE: Component =
TranslatableComponent("otm.item.power.infinite.storage").withStyle(ChatFormatting.GRAY)
}
}
class CrudeBatteryItem : BatteryItem(MAX_STORAGE, extract = MAX_EXTRACT, receive = MAX_RECEIVE, initialBatteryLevel = INITIAL_STORAGE) {
override fun appendHoverText(
stack: ItemStack,
p_41422_: Level?,
p_41423_: MutableList<Component>,
p_41424_: TooltipFlag
) {
super.appendHoverText(stack, p_41422_, p_41423_, p_41424_)
val isAndroid = runIfClient(false) {
return@runIfClient minecraft.player?.matteryPlayer?.isAndroid ?: false
}
if (isAndroid) {
p_41423_.add(TranslatableComponent("otm.gui.crude_battery.replace_in_world").withStyle(ChatFormatting.GRAY))
p_41423_.add(TranslatableComponent("otm.gui.crude_battery.replace_in_world_warning").withStyle(ChatFormatting.DARK_RED))
}
}
override fun getUseAnimation(itemStack: ItemStack): UseAnim {
return UseAnim.BOW
}
override fun getUseDuration(itemStack: ItemStack): Int {
return 100
}
override fun use(level: Level, player: Player, hand: InteractionHand): InteractionResultHolder<ItemStack> {
if (player.matteryPlayer?.isAndroid == true) {
player.startUsingItem(hand)
return InteractionResultHolder.consume(player.getItemInHand(hand))
}
return super.use(level, player, hand)
}
override fun finishUsingItem(itemStack: ItemStack, level: Level, player: LivingEntity): ItemStack {
if (player !is Player) return super.finishUsingItem(itemStack, level, player)
val mattery = player.matteryPlayer ?: return super.finishUsingItem(itemStack, level, player)
if (!mattery.isAndroid) return super.finishUsingItem(itemStack, level, player)
if (player is ServerPlayer) {
if (!mattery.androidEnergy.item.isEmpty) {
mattery.androidEnergy.item.getCapability(ForgeCapabilities.ENERGY).ifPresentK {
it.extractEnergy((it.maxEnergyStored * level.random.nextFloat() * .2f).roundToInt(), false)
}
mattery.dropBattery()
}
val copyStack = itemStack.copy()
copyStack.count = 1
mattery.androidEnergy.item = copyStack
val extraDamageMult = level.random.nextFloat()
player.hurt(MRegistry.DAMAGE_EMP, 1.5f + extraDamageMult * 3.5f)
val debuffDuration = 100 + (100 * (1f - extraDamageMult)).roundToInt()
player.addEffect(MobEffectInstance(MobEffects.BLINDNESS, debuffDuration), player)
player.addEffect(MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, debuffDuration, 1), player)
player.addEffect(MobEffectInstance(MobEffects.DIG_SLOWDOWN, debuffDuration, 2), player)
player.addEffect(MobEffectInstance(MobEffects.WEAKNESS, debuffDuration, 2), player)
}
if (!player.abilities.instabuild)
itemStack.shrink(1)
return itemStack
}
companion object {
val MAX_STORAGE = ImpreciseFraction(100_000)
val MAX_EXTRACT = ImpreciseFraction(160)
val MAX_RECEIVE = ImpreciseFraction(40)
val INITIAL_STORAGE = MAX_STORAGE * .8f
}
}

View File

@ -209,7 +209,7 @@ object MItems {
val PILL_OBLIVION: Item by registry.register(MNames.PILL_OBLIVION) { PillItem(PillType.OBLIVION) }
val PILL_HEAL: Item by registry.register(MNames.PILL_HEAL) { HealPillItem() }
val BATTERY_CRUDE: Item by registry.register(MNames.BATTERY_CRUDE) { BatteryItem(ImpreciseFraction(100_000), extract = ImpreciseFraction(160), receive = ImpreciseFraction(40), initialBatteryLevel = ImpreciseFraction(80_000)) }
val BATTERY_CRUDE: Item by registry.register(MNames.BATTERY_CRUDE) { CrudeBatteryItem() }
val BATTERY_BASIC: Item by registry.register(MNames.BATTERY_BASIC) { BatteryItem(ImpreciseFraction(400_000), ImpreciseFraction(600)) }
val BATTERY_NORMAL: Item by registry.register(MNames.BATTERY_NORMAL) { BatteryItem(ImpreciseFraction(2_000_000), ImpreciseFraction(1_000)) }
val BATTERY_DENSE: Item by registry.register(MNames.BATTERY_DENSE) { BatteryItem(ImpreciseFraction(10_000_000), ImpreciseFraction(2_000)) }