Split server config, energy sword discharge variance

This commit is contained in:
DBotThePony 2023-02-09 21:37:54 +07:00
parent d7af3774de
commit f0fadcc852
Signed by: DBot
GPG Key ID: DCC23B5715498507
30 changed files with 414 additions and 338 deletions

View File

@ -35,8 +35,12 @@ import ru.dbotthepony.mc.otm.client.render.blockentity.BatteryBankRenderer;
import ru.dbotthepony.mc.otm.client.render.blockentity.MatterBatteryBankRenderer;
import ru.dbotthepony.mc.otm.compat.mekanism.QIOKt;
import ru.dbotthepony.mc.otm.compat.mekanism.TooltipsKt;
import ru.dbotthepony.mc.otm.config.AndroidConfig;
import ru.dbotthepony.mc.otm.config.ClientConfig;
import ru.dbotthepony.mc.otm.config.ItemsConfig;
import ru.dbotthepony.mc.otm.config.MachinesConfig;
import ru.dbotthepony.mc.otm.config.ServerConfig;
import ru.dbotthepony.mc.otm.config.ToolsConfig;
import ru.dbotthepony.mc.otm.core.math.Decimal;
import ru.dbotthepony.mc.otm.item.ItemTritaniumArmor;
import ru.dbotthepony.mc.otm.item.QuantumBatteryItem;
@ -125,6 +129,10 @@ public final class OverdriveThatMatters {
ClientConfig.INSTANCE.register();
ServerConfig.INSTANCE.register();
AndroidConfig.INSTANCE.register();
ItemsConfig.INSTANCE.register();
MachinesConfig.INSTANCE.register();
ToolsConfig.INSTANCE.register();
}
private void setup(final FMLCommonSetupEvent event) {

View File

@ -26,7 +26,6 @@ import net.minecraftforge.event.ForgeEventFactory
import net.minecraftforge.event.entity.living.LivingDeathEvent
import ru.dbotthepony.mc.otm.NULLABLE_MINECRAFT_SERVER
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.config.ServerConfig
import ru.dbotthepony.mc.otm.android.AndroidActiveFeature
import ru.dbotthepony.mc.otm.android.AndroidResearchManager
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
@ -36,6 +35,7 @@ import ru.dbotthepony.mc.otm.client.render.DynamicBufferSource
import ru.dbotthepony.mc.otm.client.render.ResearchIcons
import ru.dbotthepony.mc.otm.client.render.sprite
import ru.dbotthepony.mc.otm.client.render.linesIgnoreZRenderType
import ru.dbotthepony.mc.otm.config.AndroidConfig
import ru.dbotthepony.mc.otm.core.math.Vector
import ru.dbotthepony.mc.otm.core.math.asVector
import ru.dbotthepony.mc.otm.core.math.component1
@ -61,10 +61,10 @@ class EnderTeleporterFeature(capability: MatteryPlayerCapability) : AndroidActiv
private set
override val maxCooldown: Int
get() = ServerConfig.EnderTeleporter.COOLDOWN
get() = AndroidConfig.EnderTeleporter.COOLDOWN
private fun canUse(): Boolean {
return !isOnCooldown && android.androidEnergy.extractEnergyExact(ServerConfig.EnderTeleporter.ENERGY_COST, true)
return !isOnCooldown && android.androidEnergy.extractEnergyExact(AndroidConfig.EnderTeleporter.ENERGY_COST, true)
}
private fun isValidGround(blockPos: BlockPos): Boolean {
@ -113,14 +113,14 @@ class EnderTeleporterFeature(capability: MatteryPlayerCapability) : AndroidActiv
}
private fun tryToPhaseThroughWall(blockPos: BlockPos, normal: Vec3i): TraceResult? {
val phasedBlocks = ArrayList<BlockPos>(ServerConfig.EnderTeleporter.MAX_PHASE_DISTANCE)
val phasedBlocks = ArrayList<BlockPos>(AndroidConfig.EnderTeleporter.MAX_PHASE_DISTANCE)
phasedBlocks.add(blockPos)
for (extend in 1 .. ServerConfig.EnderTeleporter.MAX_PHASE_DISTANCE) {
for (extend in 1 .. AndroidConfig.EnderTeleporter.MAX_PHASE_DISTANCE) {
val pos = blockPos + normal * extend
if (isAirGap(pos)) {
for (y in 0 .. ServerConfig.EnderTeleporter.MAX_PHASE_DISTANCE - extend) {
for (y in 0 .. AndroidConfig.EnderTeleporter.MAX_PHASE_DISTANCE - extend) {
val newPos = BlockPos(pos.x, pos.y - y, pos.z)
if (isValidPosition(newPos)) {
@ -143,7 +143,7 @@ class EnderTeleporterFeature(capability: MatteryPlayerCapability) : AndroidActiv
val result = ply.level.clip(ClipContext(
headPosition,
headPosition + aimVector * (ServerConfig.EnderTeleporter.MAX_DISTANCE * 2.0),
headPosition + aimVector * (AndroidConfig.EnderTeleporter.MAX_DISTANCE * 2.0),
ClipContext.Block.COLLIDER,
ClipContext.Fluid.NONE,
ply
@ -159,7 +159,7 @@ class EnderTeleporterFeature(capability: MatteryPlayerCapability) : AndroidActiv
!ply.isShiftKeyDown &&
result.direction == Direction.UP &&
isValidPosition(result.blockPos.above()) &&
shortestDistanceBetween(testPositions, result.blockPos.above().asVector()) <= ServerConfig.EnderTeleporter.MAX_DISTANCE
shortestDistanceBetween(testPositions, result.blockPos.above().asVector()) <= AndroidConfig.EnderTeleporter.MAX_DISTANCE
) {
return TraceResult(result.blockPos.above())
}
@ -217,14 +217,14 @@ class EnderTeleporterFeature(capability: MatteryPlayerCapability) : AndroidActiv
if (!isAirGap(pos)) {
phasedBlocks++
if (phasedBlocks >= ServerConfig.EnderTeleporter.MAX_PHASE_DISTANCE) {
if (phasedBlocks >= AndroidConfig.EnderTeleporter.MAX_PHASE_DISTANCE) {
break
}
phasedBlocksList.add(pos)
}
if (shortestDistanceBetween(testPositions, pos.asVector()) > ServerConfig.EnderTeleporter.MAX_DISTANCE) {
if (shortestDistanceBetween(testPositions, pos.asVector()) > AndroidConfig.EnderTeleporter.MAX_DISTANCE) {
break
}
@ -271,14 +271,14 @@ class EnderTeleporterFeature(capability: MatteryPlayerCapability) : AndroidActiv
if (!isAirGap(pos)) {
phasedBlocks++
if (phasedBlocks >= ServerConfig.EnderTeleporter.MAX_PHASE_DISTANCE) {
if (phasedBlocks >= AndroidConfig.EnderTeleporter.MAX_PHASE_DISTANCE) {
break
}
phasedBlocksList.add(pos)
}
if (shortestDistanceBetween(testPositions, pos.asVector()) > ServerConfig.EnderTeleporter.MAX_DISTANCE) {
if (shortestDistanceBetween(testPositions, pos.asVector()) > AndroidConfig.EnderTeleporter.MAX_DISTANCE) {
break
}
@ -309,7 +309,7 @@ class EnderTeleporterFeature(capability: MatteryPlayerCapability) : AndroidActiv
putOnCooldown()
lastTeleport = ply.server!!.tickCount
android.androidEnergy.extractEnergy(ServerConfig.EnderTeleporter.ENERGY_COST, false)
android.androidEnergy.extractEnergy(AndroidConfig.EnderTeleporter.ENERGY_COST, false)
ply.level.playSound(null, ply, SoundEvents.ENDERMAN_TELEPORT, SoundSource.PLAYERS, 0.3f, 0.8f + ply.level.random.nextFloat() * 0.4f)
ply.teleportTo(event.targetX, event.targetY, event.targetZ)
@ -400,7 +400,7 @@ class EnderTeleporterFeature(capability: MatteryPlayerCapability) : AndroidActiv
AndroidResearchManager.descriptionFunc(
ResourceLocation(OverdriveThatMatters.MOD_ID, MNames.ENDER_TELEPORTER),
"otm.gui.power_cost_per_use",
{ ServerConfig.EnderTeleporter.ENERGY_COST.formatPower().copy().withStyle(ChatFormatting.YELLOW) })
{ AndroidConfig.EnderTeleporter.ENERGY_COST.formatPower().copy().withStyle(ChatFormatting.YELLOW) })
fun onEntityDeath(event: LivingDeathEvent) {
val android = event.entity.matteryPlayer ?: return

View File

@ -8,7 +8,7 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.android.AndroidFeature
import ru.dbotthepony.mc.otm.android.AndroidResearchManager
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
import ru.dbotthepony.mc.otm.config.ServerConfig
import ru.dbotthepony.mc.otm.config.AndroidConfig
import ru.dbotthepony.mc.otm.core.TextComponent
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
@ -18,7 +18,7 @@ import ru.dbotthepony.mc.otm.triggers.FallDampenersSaveTrigger
class FallDampenersFeature(capability: MatteryPlayerCapability) : AndroidFeature(AndroidFeatures.FALL_DAMPENERS, capability) {
override fun onHurt(event: LivingHurtEvent) {
if (event.source.isFall) {
val reduction = (ServerConfig.FALL_DAMAGE_REDUCTION_PER_LEVEL * (level + 1)).toFloat()
val reduction = (AndroidConfig.FALL_DAMAGE_REDUCTION_PER_LEVEL * (level + 1)).toFloat()
val old = event.amount
@ -37,7 +37,7 @@ class FallDampenersFeature(capability: MatteryPlayerCapability) : AndroidFeature
companion object {
val DESCRIPTION = AndroidResearchManager.descriptionFuncs.register(ResourceLocation(OverdriveThatMatters.MOD_ID, MNames.FALL_DAMPENERS)) { level: Int ->
TranslatableComponent("otm.fall_dampeners.description", TextComponent("%.1f".format((ServerConfig.FALL_DAMAGE_REDUCTION_PER_LEVEL * level).toFloat().coerceAtLeast(0f).coerceAtMost(1f) * 100f)).withStyle(ChatFormatting.YELLOW))
TranslatableComponent("otm.fall_dampeners.description", TextComponent("%.1f".format((AndroidConfig.FALL_DAMAGE_REDUCTION_PER_LEVEL * level).toFloat().coerceAtLeast(0f).coerceAtMost(1f) * 100f)).withStyle(ChatFormatting.YELLOW))
}
}
}

View File

@ -9,7 +9,7 @@ import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.item.ItemEntity
import net.minecraftforge.network.NetworkEvent
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.config.ServerConfig
import ru.dbotthepony.mc.otm.config.AndroidConfig
import ru.dbotthepony.mc.otm.android.AndroidResearchManager
import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
@ -73,13 +73,13 @@ class ItemMagnetFeature(capability: MatteryPlayerCapability) : AndroidSwitchable
private val clientPredicate = Predicate<Entity> { it is ItemEntity && (datatable[it] ?: SharedItemEntityData.EMPTY).let { !it.hasPickupDelay && (it.owner == null || it.owner != ply.uuid || it.lifespan - it.age <= 200) } }
private fun doTick(server: Boolean) {
if (ply.isSpectator || server && !android.androidEnergy.extractEnergyExact(ServerConfig.AndroidItemMagnet.POWER_DRAW, true)) {
if (ply.isSpectator || server && !android.androidEnergy.extractEnergyExact(AndroidConfig.Magnet.POWER_DRAW, true)) {
return
}
val entities = ply.level.getEntitiesInEllipsoid(
ply.position,
Vector(ServerConfig.AndroidItemMagnet.RADIUS_HORIZONTAL, ServerConfig.AndroidItemMagnet.RADIUS_VERTICAL, ServerConfig.AndroidItemMagnet.RADIUS_HORIZONTAL),
Vector(AndroidConfig.Magnet.RADIUS_HORIZONTAL, AndroidConfig.Magnet.RADIUS_VERTICAL, AndroidConfig.Magnet.RADIUS_HORIZONTAL),
if (server) Predicate<Entity> { it is ItemEntity } else clientPredicate
)
@ -98,7 +98,7 @@ class ItemMagnetFeature(capability: MatteryPlayerCapability) : AndroidSwitchable
if (data.position.distanceToSqr(ent.position) < 1.0) {
data.ticksSinceActivity++
} else {
if (!android.androidEnergy.extractEnergyExact(ServerConfig.AndroidItemMagnet.POWER_DRAW, false)) {
if (!android.androidEnergy.extractEnergyExact(AndroidConfig.Magnet.POWER_DRAW, false)) {
return
}
@ -114,7 +114,7 @@ class ItemMagnetFeature(capability: MatteryPlayerCapability) : AndroidSwitchable
override fun tickClient() {
super.tickClient()
if (!ply.isSpectator && isActive && android.androidEnergy.extractEnergyExact(ServerConfig.AndroidItemMagnet.POWER_DRAW, true)) {
if (!ply.isSpectator && isActive && android.androidEnergy.extractEnergyExact(AndroidConfig.Magnet.POWER_DRAW, true)) {
doTick(false)
}
}
@ -136,6 +136,6 @@ class ItemMagnetFeature(capability: MatteryPlayerCapability) : AndroidSwitchable
AndroidResearchManager.descriptionFunc(ResourceLocation(
OverdriveThatMatters.MOD_ID, MNames.ITEM_MAGNET),
"otm.gui.power_cost_per_tick",
{ ServerConfig.AndroidItemMagnet.POWER_DRAW.formatPower().copy().withStyle(ChatFormatting.YELLOW) })
{ AndroidConfig.Magnet.POWER_DRAW.formatPower().copy().withStyle(ChatFormatting.YELLOW) })
}
}

View File

@ -10,7 +10,7 @@ import net.minecraft.sounds.SoundSource
import net.minecraftforge.network.NetworkEvent
import ru.dbotthepony.mc.otm.config.ClientConfig
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.config.ServerConfig
import ru.dbotthepony.mc.otm.config.AndroidConfig
import ru.dbotthepony.mc.otm.android.AndroidResearchManager
import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
@ -46,7 +46,7 @@ object TriggerJumpBoostPacket : MatteryPacket {
val feature = mattery.getFeature(AndroidFeatures.JUMP_BOOST) as JumpBoostFeature? ?: return@enqueueWork
if (feature.isActive && feature.cooldown <= 4 && mattery.androidEnergy.extractEnergyExact(ServerConfig.AndroidJumpBoost.ENERGY_COST, false)) {
if (feature.isActive && feature.cooldown <= 4 && mattery.androidEnergy.extractEnergyExact(AndroidConfig.JumpBoost.ENERGY_COST, false)) {
feature.putOnCooldown()
context.sender?.let {
@ -68,7 +68,7 @@ class JumpBoostFeature(capability: MatteryPlayerCapability) : AndroidSwitchableF
private var tickCooldownClient = false
override val maxCooldown: Int
get() = (ServerConfig.AndroidJumpBoost.BASE_COOLDOWN - ServerConfig.AndroidJumpBoost.COOLDOWN_REDUCTION * level).coerceAtLeast(0)
get() = (AndroidConfig.JumpBoost.BASE_COOLDOWN - AndroidConfig.JumpBoost.COOLDOWN_REDUCTION * level).coerceAtLeast(0)
override var cooldown by synchronizer.int(setter = setter@{ value, access, setByRemote ->
access.write(value)
@ -90,8 +90,8 @@ class JumpBoostFeature(capability: MatteryPlayerCapability) : AndroidSwitchableF
val old = lastGround
lastGround = ply.isOnGround
if (isActive && cooldown <= 0 && old != lastGround && !lastGround && isJumping && isShifting && ply.xRot <= ClientConfig.JUMP_BOOST_LOOK_ANGLE && android.androidEnergy.extractEnergyExact(ServerConfig.AndroidJumpBoost.ENERGY_COST, true)) {
ply.deltaMovement += Vector(0.0, ServerConfig.AndroidJumpBoost.POWER * (level + 1) / 20.0, 0.0)
if (isActive && cooldown <= 0 && old != lastGround && !lastGround && isJumping && isShifting && ply.xRot <= ClientConfig.JUMP_BOOST_LOOK_ANGLE && android.androidEnergy.extractEnergyExact(AndroidConfig.JumpBoost.ENERGY_COST, true)) {
ply.deltaMovement += Vector(0.0, AndroidConfig.JumpBoost.POWER * (level + 1) / 20.0, 0.0)
putOnCooldown()
MatteryPlayerNetworkChannel.sendToServer(TriggerJumpBoostPacket)
@ -130,6 +130,6 @@ class JumpBoostFeature(capability: MatteryPlayerCapability) : AndroidSwitchableF
AndroidResearchManager.descriptionFunc(
ResourceLocation(OverdriveThatMatters.MOD_ID, MNames.JUMP_BOOST),
"otm.gui.power_cost_per_use",
{ ServerConfig.AndroidJumpBoost.ENERGY_COST.formatPower().copy().withStyle(ChatFormatting.YELLOW) })
{ AndroidConfig.JumpBoost.ENERGY_COST.formatPower().copy().withStyle(ChatFormatting.YELLOW) })
}
}

View File

@ -3,7 +3,7 @@ package ru.dbotthepony.mc.otm.android.feature
import net.minecraft.nbt.CompoundTag
import net.minecraft.server.level.ServerPlayer
import net.minecraftforge.event.entity.living.LivingHurtEvent
import ru.dbotthepony.mc.otm.config.ServerConfig
import ru.dbotthepony.mc.otm.config.AndroidConfig
import ru.dbotthepony.mc.otm.android.AndroidFeature
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
@ -19,16 +19,16 @@ class NanobotsRegenerationFeature(android: MatteryPlayerCapability) : AndroidFea
if (ply.health > 0f && ply.health < ply.maxHealth) {
ticksPassed++
val waitTime = ServerConfig.NanobotsRegeneration.COOLDOWN.getOrElse(healTicks) { ServerConfig.NanobotsRegeneration.COOLDOWN.last() }
val waitTime = AndroidConfig.NanobotsRegeneration.COOLDOWN.getOrElse(healTicks) { AndroidConfig.NanobotsRegeneration.COOLDOWN.last() }
if (ticksPassed > waitTime) {
val missingHealth = (ply.maxHealth - ply.health).coerceAtMost(2f)
val power = ServerConfig.NanobotsRegeneration.ENERGY_PER_HITPOINT * missingHealth
val power = AndroidConfig.NanobotsRegeneration.ENERGY_PER_HITPOINT * missingHealth
val extracted = android.androidEnergy.extractEnergy(power, false)
if (extracted.isPositive) {
healTicks = (healTicks + 1).coerceAtMost(level)
val healed = (extracted / ServerConfig.NanobotsRegeneration.ENERGY_PER_HITPOINT).toFloat()
val healed = (extracted / AndroidConfig.NanobotsRegeneration.ENERGY_PER_HITPOINT).toFloat()
ply.heal(healed)
(ply as ServerPlayer?)?.awardStat(StatNames.HEALTH_REGENERATED, (healed * 10f).roundToInt())
ticksPassed = 0

View File

@ -8,6 +8,7 @@ import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
import ru.dbotthepony.mc.otm.capability.energy.extractEnergyExact
import ru.dbotthepony.mc.otm.client.render.ResearchIcons
import ru.dbotthepony.mc.otm.config.AndroidConfig
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
class NightVisionFeature(android: MatteryPlayerCapability) : AndroidSwitchableFeature(AndroidFeatures.NIGHT_VISION, android) {
@ -18,7 +19,7 @@ class NightVisionFeature(android: MatteryPlayerCapability) : AndroidSwitchableFe
if (isActive) {
val effect = android.ply.activeEffectsMap[MobEffects.NIGHT_VISION]
if ((effect == null || effect.duration < 220) && (ply.isSpectator || android.androidEnergy.extractEnergyExact(ServerConfig.NIGHT_VISION_POWER_DRAW, false))) {
if ((effect == null || effect.duration < 220) && (ply.isSpectator || android.androidEnergy.extractEnergyExact(AndroidConfig.NIGHT_VISION_POWER_DRAW, false))) {
android.ply.addEffect(MobEffectInstance(MobEffects.NIGHT_VISION, 220, 0, false, false))
}
}

View File

@ -13,7 +13,7 @@ import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.monster.warden.Warden
import net.minecraftforge.network.NetworkEvent
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.config.ServerConfig
import ru.dbotthepony.mc.otm.config.AndroidConfig
import ru.dbotthepony.mc.otm.android.AndroidResearchManager
import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
@ -68,7 +68,7 @@ object TriggerShockwavePacket : MatteryPacket {
class ShockwaveFeature(capability: MatteryPlayerCapability) : AndroidSwitchableFeature(AndroidFeatures.SHOCKWAVE, capability) {
override val maxCooldown: Int
get() = ServerConfig.Shockwave.COOLDOWN
get() = AndroidConfig.Shockwave.COOLDOWN
private var wasMidair = false
private var highestSpeed = 0.0
@ -83,18 +83,18 @@ class ShockwaveFeature(capability: MatteryPlayerCapability) : AndroidSwitchableF
isActive &&
ply.isShiftKeyDown &&
!isOnCooldown &&
android.androidEnergy.extractEnergyExact(ServerConfig.Shockwave.ENERGY_COST, true) &&
android.androidEnergy.extractEnergyExact(AndroidConfig.Shockwave.ENERGY_COST, true) &&
ply.deltaMovement.y < -0.01 &&
creativeFlightTicks == 0
) {
ply.deltaMovement += Vector(0.0, -ServerConfig.Shockwave.ACCELERATION / 20.0, 0.0)
ply.deltaMovement += Vector(0.0, -AndroidConfig.Shockwave.ACCELERATION / 20.0, 0.0)
}
ticker(true)
}
fun shockwave() {
if (ply.isSpectator || isOnCooldown || !android.androidEnergy.extractEnergyExact(ServerConfig.Shockwave.ENERGY_COST, false)) {
if (ply.isSpectator || isOnCooldown || !android.androidEnergy.extractEnergyExact(AndroidConfig.Shockwave.ENERGY_COST, false)) {
return
}
@ -117,14 +117,14 @@ class ShockwaveFeature(capability: MatteryPlayerCapability) : AndroidSwitchableF
// TODO: raycasting
val entities = ply.level.getEntitiesInEllipsoid(
ply.position,
Vector(ServerConfig.Shockwave.RADIUS_HORIZONTAL, ServerConfig.Shockwave.RADIUS_VERTICAL, ServerConfig.Shockwave.RADIUS_HORIZONTAL),
Vector(AndroidConfig.Shockwave.RADIUS_HORIZONTAL, AndroidConfig.Shockwave.RADIUS_VERTICAL, AndroidConfig.Shockwave.RADIUS_HORIZONTAL),
except = ply,
) { (it !is LivingEntity || !it.isSpectator && it.isAlive) }
val wardens = ply.level.getEntitiesInEllipsoid(
Warden::class.java,
ply.position,
Vector(ServerConfig.Shockwave.RADIUS_HORIZONTAL_WARDEN, ServerConfig.Shockwave.RADIUS_VERTICAL_WARDEN, ServerConfig.Shockwave.RADIUS_HORIZONTAL_WARDEN),
Vector(AndroidConfig.Shockwave.RADIUS_HORIZONTAL_WARDEN, AndroidConfig.Shockwave.RADIUS_VERTICAL_WARDEN, AndroidConfig.Shockwave.RADIUS_HORIZONTAL_WARDEN),
) { true }
val seen = ReferenceArraySet<Entity>()
@ -134,7 +134,7 @@ class ShockwaveFeature(capability: MatteryPlayerCapability) : AndroidSwitchableF
val multiplier = (1.0 - distanceMultiplier).pow(0.5)
val source = ShockwaveDamageSource(ply)
val damage = multiplier.toFloat() * ServerConfig.Shockwave.DAMAGE.toFloat() * ServerConfig.Shockwave.WARDEN_DAMAGE_MULT.toFloat()
val damage = multiplier.toFloat() * AndroidConfig.Shockwave.DAMAGE.toFloat() * AndroidConfig.Shockwave.WARDEN_DAMAGE_MULT.toFloat()
entity.hurt(source, damage)
entity.deltaMovement += (entity.position - ply.position).normalize() * (multiplier * 3.0)
@ -150,7 +150,7 @@ class ShockwaveFeature(capability: MatteryPlayerCapability) : AndroidSwitchableF
// don't hurt items, arrows, etc etc
if (entity is LivingEntity) {
val source = ShockwaveDamageSource(ply)
val damage = multiplier.toFloat() * ServerConfig.Shockwave.DAMAGE.toFloat()
val damage = multiplier.toFloat() * AndroidConfig.Shockwave.DAMAGE.toFloat()
entity.hurt(source, damage)
entity.deltaMovement += (entity.position - ply.position).normalize() * (multiplier * 3.0)
@ -163,10 +163,10 @@ class ShockwaveFeature(capability: MatteryPlayerCapability) : AndroidSwitchableF
}
}
if (ServerConfig.Shockwave.BREAK_BLOCKS) {
if (AndroidConfig.Shockwave.BREAK_BLOCKS) {
val rounded = ply.position.roundToIntVector()
for (blockPos in getEllipsoidBlockPositions(ServerConfig.Shockwave.RADIUS_HORIZONTAL.roundToInt(), ServerConfig.Shockwave.RADIUS_VERTICAL.roundToInt(), ServerConfig.Shockwave.RADIUS_HORIZONTAL.roundToInt())) {
for (blockPos in getEllipsoidBlockPositions(AndroidConfig.Shockwave.RADIUS_HORIZONTAL.roundToInt(), AndroidConfig.Shockwave.RADIUS_VERTICAL.roundToInt(), AndroidConfig.Shockwave.RADIUS_HORIZONTAL.roundToInt())) {
val newBlockPos = blockPos + rounded
val blockState = ply.level.getBlockState(newBlockPos)
@ -199,7 +199,7 @@ class ShockwaveFeature(capability: MatteryPlayerCapability) : AndroidSwitchableF
!ply.isSpectator &&
isActive &&
!isOnCooldown &&
android.androidEnergy.extractEnergyExact(ServerConfig.Shockwave.ENERGY_COST, true) &&
android.androidEnergy.extractEnergyExact(AndroidConfig.Shockwave.ENERGY_COST, true) &&
creativeFlightTicks == 0
) {
val old = wasMidair
@ -209,7 +209,7 @@ class ShockwaveFeature(capability: MatteryPlayerCapability) : AndroidSwitchableF
highestSpeed = (-ply.deltaMovement.y).coerceAtLeast(highestSpeed)
}
if (old != wasMidair && !wasMidair && ServerConfig.Shockwave.TERMINAL_VELOCITY <= (highestSpeed * 20.0) && ply.isShiftKeyDown) {
if (old != wasMidair && !wasMidair && AndroidConfig.Shockwave.TERMINAL_VELOCITY <= (highestSpeed * 20.0) && ply.isShiftKeyDown) {
if (isClient) {
// I HATE SELF-UPDATING PLAYERS
// I HATE SELF-UPDATING PLAYERS
@ -253,6 +253,6 @@ class ShockwaveFeature(capability: MatteryPlayerCapability) : AndroidSwitchableF
AndroidResearchManager.descriptionFunc(
ResourceLocation(OverdriveThatMatters.MOD_ID, MNames.SHOCKWAVE),
"otm.gui.power_cost_per_use",
{ ServerConfig.Shockwave.ENERGY_COST.formatPower().copy().withStyle(ChatFormatting.YELLOW) })
{ AndroidConfig.Shockwave.ENERGY_COST.formatPower().copy().withStyle(ChatFormatting.YELLOW) })
}
}

View File

@ -18,6 +18,7 @@ import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.menu.storage.DriveRackMenu
import ru.dbotthepony.mc.otm.core.nbt.map
@ -29,7 +30,7 @@ import ru.dbotthepony.mc.otm.storage.*
class DriveRackBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
MatteryPoweredBlockEntity(MBlockEntities.DRIVE_RACK, p_155229_, p_155230_) {
override val energy = WorkerEnergyStorage(this, ServerConfig.DRIVE_RACK)
override val energy = WorkerEnergyStorage(this, MachinesConfig.DRIVE_RACK)
val container: MatteryContainer = object : MatteryContainer(this::setChanged, 4) {
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {

View File

@ -18,6 +18,7 @@ import ru.dbotthepony.mc.otm.block.storage.DriveViewerBlock
import ru.dbotthepony.mc.otm.block.entity.WorkerState
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.core.nbt.map
@ -44,7 +45,7 @@ class DriveViewerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
}
}
override val energy = WorkerEnergyStorage(this, ServerConfig.DRIVE_VIEWER)
override val energy = WorkerEnergyStorage(this, MachinesConfig.DRIVE_VIEWER)
val container: MatteryContainer = object : MatteryContainer(this::setChanged, 1) {
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {

View File

@ -31,6 +31,7 @@ import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.get
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
@ -182,7 +183,7 @@ class ItemMonitorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
MatteryPoweredBlockEntity(MBlockEntities.ITEM_MONITOR, p_155229_, p_155230_),
IStorageEventConsumer<ItemStackWrapper> {
override val energy = WorkerEnergyStorage(this, ServerConfig.ITEM_MONITOR)
override val energy = WorkerEnergyStorage(this, MachinesConfig.ITEM_MONITOR)
var poweredView: PoweredVirtualComponent<ItemStackWrapper>? = null
private set

View File

@ -24,6 +24,7 @@ import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
import ru.dbotthepony.mc.otm.block.entity.storage.AbstractStorageImportExport.Companion.FILTER_KEY
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.config.ServerConfig
import ru.dbotthepony.mc.otm.container.ItemFilter
import ru.dbotthepony.mc.otm.core.*
@ -76,7 +77,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
return StorageBusMenu(containerID, inventory, this)
}
override val energy = WorkerEnergyStorage(this::setChangedLight, ServerConfig.STORAGE_INTERFACES)
override val energy = WorkerEnergyStorage(this::setChangedLight, MachinesConfig.STORAGE_INTERFACES)
val cell: BasicStorageGraphNode = object : BasicStorageGraphNode(energy), GraphNodeListener {
override fun onNeighbour(node: Graph6Node<*>, direction: Direction) {

View File

@ -24,6 +24,7 @@ import ru.dbotthepony.mc.otm.capability.*
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.capability.energy.extractEnergyExact
import ru.dbotthepony.mc.otm.config.ConciseBalanceValues
import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.config.ServerConfig
import ru.dbotthepony.mc.otm.container.ItemFilter
import ru.dbotthepony.mc.otm.core.*
@ -53,7 +54,7 @@ abstract class AbstractStorageImportExport<T>(
blockType: BlockEntityType<*>,
blockPos: BlockPos,
blockState: BlockState,
energyValues: ConciseBalanceValues = ServerConfig.STORAGE_INTERFACES
energyValues: ConciseBalanceValues = MachinesConfig.STORAGE_INTERFACES
) : MatteryPoweredBlockEntity(blockType, blockPos, blockState) {
final override val energy = WorkerEnergyStorage(this::setChangedLight, energyValues)

View File

@ -19,6 +19,7 @@ import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.capability.energy.transferChecked
import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
@ -92,7 +93,7 @@ class StoragePowerSupplierBlockEntity(blockPos: BlockPos, blockState: BlockState
var demand = Decimal.ZERO
var i = 0
val available = energy.batteryLevel.coerceAtMost(ServerConfig.STORAGE_POWER_SUPPLIER.throughput)
val available = energy.batteryLevel.coerceAtMost(MachinesConfig.STORAGE_POWER_SUPPLIER.throughput)
for (demanding in graph.powerDemandingNodes) {
val received = demanding.receiveEnergy(available, true)
@ -118,7 +119,7 @@ class StoragePowerSupplierBlockEntity(blockPos: BlockPos, blockState: BlockState
}
}
override val energy = WorkerEnergyStorage(this, ServerConfig.STORAGE_POWER_SUPPLIER)
override val energy = WorkerEnergyStorage(this, MachinesConfig.STORAGE_POWER_SUPPLIER)
override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt)

View File

@ -21,6 +21,7 @@ import ru.dbotthepony.mc.otm.block.IDroppableContainer
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.MatteryContainerHooks
import ru.dbotthepony.mc.otm.core.math.Decimal
@ -37,7 +38,7 @@ class PlatePressBlockEntity(
p_155230_: BlockState
) : MatteryWorkerBlockEntity<MatteryWorkerBlockEntity.ItemJob>(MBlockEntities.PLATE_PRESS, p_155229_, p_155230_, ::ItemJob), IDroppableContainer {
val container = MatteryContainer(this::setChangedLight, 2)
override val energy = WorkerEnergyStorage(this::setChangedLight, ServerConfig.PLATE_PRESS)
override val energy = WorkerEnergyStorage(this::setChangedLight, MachinesConfig.PLATE_PRESS)
var experience = 0.0

View File

@ -46,14 +46,13 @@ 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.client.minecraft
import ru.dbotthepony.mc.otm.config.ServerConfig
import ru.dbotthepony.mc.otm.config.AndroidConfig
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.stream
import ru.dbotthepony.mc.otm.core.*
import ru.dbotthepony.mc.otm.core.collect.UUIDIntModifiersMap
import ru.dbotthepony.mc.otm.core.collect.nonEmpty
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.set
import ru.dbotthepony.mc.otm.core.nbt.getCompoundList
import ru.dbotthepony.mc.otm.core.nbt.map
import ru.dbotthepony.mc.otm.core.nbt.set
@ -274,7 +273,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
/**
* [IMatteryEnergyStorage] instance, representing Android' battery charge
*/
val androidEnergy = AndroidPowerSource(ply, synchronizer, ServerConfig.ANDROID_MAX_ENERGY, ServerConfig.ANDROID_MAX_ENERGY)
val androidEnergy = AndroidPowerSource(ply, synchronizer, AndroidConfig.ANDROID_MAX_ENERGY, AndroidConfig.ANDROID_MAX_ENERGY)
fun invalidateNetworkState() {
synchronizer.invalidate()
@ -324,8 +323,8 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
shouldPlaySound = false
iteration = 0
deathLog.clear()
androidEnergy.batteryLevel = ServerConfig.ANDROID_MAX_ENERGY
androidEnergy.maxBatteryLevel = ServerConfig.ANDROID_MAX_ENERGY
androidEnergy.batteryLevel = AndroidConfig.ANDROID_MAX_ENERGY
androidEnergy.maxBatteryLevel = AndroidConfig.ANDROID_MAX_ENERGY
if (ply is ServerPlayer) {
BecomeAndroidTrigger.trigger(ply)
@ -372,7 +371,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
iteration = 0
deathLog.clear()
androidEnergy.batteryLevel = Decimal.ZERO
androidEnergy.maxBatteryLevel = ServerConfig.ANDROID_MAX_ENERGY
androidEnergy.maxBatteryLevel = AndroidConfig.ANDROID_MAX_ENERGY
dropBattery()
if (ply is ServerPlayer) {
@ -788,16 +787,16 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
if (!ply.isSpectator) {
val stats = ply.foodData
while (stats.foodLevel < 18 && androidEnergy.extractEnergy(ServerConfig.ANDROID_ENERGY_PER_HUNGER_POINT, true) >= ServerConfig.ANDROID_ENERGY_PER_HUNGER_POINT) {
androidEnergy.extractEnergy(ServerConfig.ANDROID_ENERGY_PER_HUNGER_POINT, false)
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
}
// "block" quick regeneration
// also cause power to generate while in peaceful
if (ServerConfig.REGENERATE_ENERGY) {
while (stats.foodLevel > 18 && androidEnergy.receiveEnergy(ServerConfig.ANDROID_ENERGY_PER_HUNGER_POINT, true) >= ServerConfig.ANDROID_ENERGY_PER_HUNGER_POINT) {
androidEnergy.receiveEnergy(ServerConfig.ANDROID_ENERGY_PER_HUNGER_POINT, false)
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
}
} else if (ply.level.server?.worldData?.difficulty != Difficulty.PEACEFUL) {
@ -807,13 +806,13 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
val foodLevel = stats.foodLevel.toFloat()
if (stats.saturationLevel < foodLevel) {
val extracted = androidEnergy.extractEnergy(ServerConfig.ANDROID_ENERGY_PER_HUNGER_POINT * (foodLevel - stats.saturationLevel), false)
stats.setSaturation(stats.saturationLevel + (extracted / ServerConfig.ANDROID_ENERGY_PER_HUNGER_POINT).toFloat())
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) {
val extracted = androidEnergy.extractEnergy(ServerConfig.ANDROID_ENERGY_PER_HUNGER_POINT * (stats.exhaustionLevel / 4f), false)
stats.setExhaustion(stats.exhaustionLevel - (extracted / ServerConfig.ANDROID_ENERGY_PER_HUNGER_POINT).toFloat() * 4f)
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)
}
}

View File

@ -7,6 +7,7 @@ import com.mojang.blaze3d.vertex.VertexFormat
import net.minecraft.client.renderer.GameRenderer
import net.minecraftforge.client.event.RenderLevelStageEvent
import org.lwjgl.opengl.GL11.GL_LESS
import ru.dbotthepony.mc.otm.config.AndroidConfig
import ru.dbotthepony.mc.otm.config.ServerConfig
import ru.dbotthepony.mc.otm.core.math.Vector
import ru.dbotthepony.mc.otm.core.math.component1
@ -82,6 +83,6 @@ object ShockwaveRenderer {
}
fun handle(packet: ShockwaveEffectPacket) {
State(packet.pos, ServerConfig.Shockwave.RADIUS_HORIZONTAL.toFloat())
State(packet.pos, AndroidConfig.Shockwave.RADIUS_HORIZONTAL.toFloat())
}
}

View File

@ -0,0 +1,20 @@
package ru.dbotthepony.mc.otm.config
import net.minecraftforge.common.ForgeConfigSpec
import net.minecraftforge.fml.ModLoadingContext
import net.minecraftforge.fml.config.ModConfig
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.core.util.WriteOnce
abstract class AbstractConfig(private val configName: String, private val type: ModConfig.Type = ModConfig.Type.SERVER) {
private var spec: ForgeConfigSpec by WriteOnce()
protected val builder = ForgeConfigSpec.Builder()
private var registered = false
fun register() {
check(!registered) { "Already registered config" }
registered = true
spec = builder.build()
ModLoadingContext.get().registerConfig(type, spec, "${OverdriveThatMatters.MOD_ID}-$configName.toml")
}
}

View File

@ -0,0 +1,108 @@
package ru.dbotthepony.mc.otm.config
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.defineDecimal
object AndroidConfig : AbstractConfig("androids") {
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("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)
object NanobotsRegeneration {
val COOLDOWN: List<Int> by builder
.comment("In ticks, time between heal ticks")
.comment("One heal tick restores 1 heart (2 health points) at most")
.comment("If not getting hurt in specified period of ticks, heal tick takes place, tick timer resets to zero and THIS array' index advances by 1")
.comment("Index inside this array can not exceed of one of ability's")
.comment("")
.comment("Wording in pseudocode:")
.comment("if (ticksSinceTakingDamage >= cooldownConfigOption[healTicks /* or config's biggest index, whichever is smaller */]) {")
.comment(" healTicks = min(healTicks + 1, level /* ability level */)")
.comment(" ticksSinceTakingDamage = 0")
.comment(" this.ply.heal(...)")
.comment("}")
.defineList("COOLDOWN", { mutableListOf(80, 60, 40, 20) }) { it is Int }
val ENERGY_PER_HITPOINT by builder
.comment("Energy required to regenerate 1 health point (half a heart)")
.defineDecimal("ENERGY_PER_HITPOINT", Decimal(800))
}
val ANDROID_ENERGY_PER_HUNGER_POINT by builder.defineDecimal("energyPerHunger", Decimal(2000), Decimal.ZERO)
val ANDROID_MAX_ENERGY by builder.comment("Internal battery of every android has this much storage").defineDecimal("capacity", Decimal(80_000), Decimal.ZERO)
val NIGHT_VISION_POWER_DRAW by builder.defineDecimal("nightVisionPowerDraw", Decimal(8), Decimal.ZERO)
val FALL_DAMAGE_REDUCTION_PER_LEVEL: Double by builder.comment("In percent. Level of feature is multiplied by this").defineInRange("fallDamageReductionPerDampenerLevel", 0.25, 0.01, 1.0)
object EnderTeleporter {
init {
builder.comment("Ender Teleporter ability").push("EnderTeleporter")
}
val ENERGY_COST by builder.defineDecimal("ENERGY_COST", Decimal(4096), Decimal.ZERO)
val COOLDOWN: Int by builder.comment("In ticks").defineInRange("COOLDOWN", 40, 0, Int.MAX_VALUE)
val MAX_PHASE_DISTANCE: Int by builder.comment("Determines how much blocks can we 'phase' through to teleport on solid surface").defineInRange("MAX_PHASE_DISTANCE", 6, 0, Int.MAX_VALUE)
val MAX_DISTANCE: Double by builder.comment("In blocks, euclidean distance").defineInRange("MAX_DISTANCE", 12.0, 2.0, Int.MAX_VALUE.toDouble())
init {
builder.pop()
}
}
object JumpBoost {
init {
builder.comment("Jump boost ability").push("JumpBoost")
}
val ENERGY_COST by builder.defineDecimal("ENERGY_COST", Decimal(1024), Decimal.ZERO)
val POWER: Double by builder.comment("The jump height on jump boost, as (level + 1) of feature, in meters per second").defineInRange("POWER", 6.0, 0.0, Double.MAX_VALUE)
val BASE_COOLDOWN: Int by builder.comment("In ticks").defineInRange("BASE_COOLDOWN", 40, 0, Int.MAX_VALUE)
val COOLDOWN_REDUCTION: Int by builder.comment("In ticks, per level of feature").defineInRange("COOLDOWN_REDUCTION", 20, 0, Int.MAX_VALUE)
init {
builder.pop()
}
}
object Magnet {
init {
builder.comment("Item magnet ability").push("Magnet")
}
val POWER_DRAW by builder.comment("Per tick per stack").defineDecimal("POWER_DRAW", Decimal(8), Decimal.ZERO)
val RADIUS_HORIZONTAL: Double by builder.defineInRange("RADIUS_HORIZONTAL", 6.0, 0.0, Double.MAX_VALUE / 4.0)
val RADIUS_VERTICAL: Double by builder.defineInRange("RADIUS_VERTICAL", 3.0, 0.0, Double.MAX_VALUE / 4.0)
init {
builder.pop()
}
}
object Shockwave {
init {
builder.comment("Shockwave ability").push("Shockwave")
}
val TERMINAL_VELOCITY: Double by builder.comment("In meters per second vertically").defineInRange("TERMINAL_VELOCITY", 5.6, 0.0)
val ACCELERATION: Double by builder.comment("In meters per second vertically").defineInRange("ACCELERATION", 4.0, 0.0)
val COOLDOWN: Int by builder.comment("In ticks").defineInRange("COOLDOWN", 30, 1)
val RADIUS_HORIZONTAL: Double by builder.comment("In meters").defineInRange("RADIUS_HORIZONTAL", 4.0, 0.0)
val RADIUS_VERTICAL: Double by builder.comment("In meters").defineInRange("RADIUS_VERTICAL", 1.0, 0.0)
val RADIUS_HORIZONTAL_WARDEN: Double by builder.comment("In meters, when searching for Warden").defineInRange("RADIUS_HORIZONTAL_WARDEN", 16.0, 0.0)
val RADIUS_VERTICAL_WARDEN: Double by builder.comment("In meters, when searching for Warden").defineInRange("RADIUS_VERTICAL_WARDEN", 6.0, 0.0)
val BREAK_BLOCKS: Boolean by builder.comment("Break blocks without any blast resistance").define("BREAK_BLOCKS", true)
val DAMAGE: Double by builder.comment("Max potential damage done by shockwave").defineInRange("DAMAGE", 12.0, 0.0, Float.MAX_VALUE.toDouble())
val WARDEN_DAMAGE_MULT: Double by builder.defineInRange("WARDEN_DAMAGE_MULT", 4.0, 0.0, Float.MAX_VALUE.toDouble())
val ENERGY_COST by builder.defineDecimal("ENERGY_COST", Decimal(2048), Decimal.ZERO)
init {
builder.pop()
}
}
}

View File

@ -0,0 +1,92 @@
package ru.dbotthepony.mc.otm.config
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.defineDecimal
import ru.dbotthepony.mc.otm.registry.MNames
object ItemsConfig : AbstractConfig("items") {
private fun verboseValues(name: String, storage: Decimal, receive: Decimal, extract: Decimal = receive): VerboseBalanceValues {
builder.push(name)
val obj = object : VerboseBalanceValues {
override val capacity: Decimal by builder.defineDecimal("capacity", storage, minimum = Decimal.ONE)
override val receive: Decimal by builder.defineDecimal("receive", receive, minimum = Decimal.ONE)
override val extract: Decimal by builder.defineDecimal("extract", extract, minimum = Decimal.ONE)
}
builder.pop()
return obj
}
private fun batteryValues(name: String, storage: Decimal, receive: Decimal, extract: Decimal = receive, initialBatteryLevel: Decimal = Decimal.ZERO): BatteryBalanceValues {
builder.push(name)
val obj = object : BatteryBalanceValues {
override val capacity: Decimal by builder.defineDecimal("capacity", storage, minimum = Decimal.ONE)
override val receive: Decimal by builder.defineDecimal("receive", receive, minimum = Decimal.ONE)
override val extract: Decimal by builder.defineDecimal("extract", extract, minimum = Decimal.ONE)
override val initialBatteryLevel: Decimal by builder.defineDecimal("initialBatteryLevel", initialBatteryLevel, minimum = Decimal.ZERO)
}
builder.pop()
return obj
}
private fun conciseValues(name: String, storage: Decimal, throughput: Decimal): ConciseBalanceValues {
builder.push(name)
val obj = object : ConciseBalanceValues {
override val capacity: Decimal by builder.defineDecimal("capacity", storage, minimum = Decimal.ONE)
override val throughput: Decimal by builder.defineDecimal("throughput", throughput, minimum = Decimal.ONE)
}
builder.pop()
return obj
}
init {
builder.push("EnergyBatteries")
}
object Batteries {
val BATTERY_CRUDE = batteryValues(MNames.BATTERY_CRUDE, Decimal(100_000), Decimal(160), Decimal(40), Decimal(80_000))
val BATTERY_BASIC = batteryValues(MNames.BATTERY_BASIC, Decimal(400_000), Decimal(600))
val BATTERY_NORMAL = batteryValues(MNames.BATTERY_NORMAL, Decimal(2_000_000), Decimal(1_000))
val BATTERY_DENSE = batteryValues(MNames.BATTERY_DENSE, Decimal(10_000_000), Decimal(2_000))
val BATTERY_CAPACITOR = batteryValues(MNames.BATTERY_CAPACITOR, Decimal(500_000), Decimal(50_000))
val QUANTUM_BATTERY = conciseValues(MNames.QUANTUM_BATTERY, Decimal(40_000_000), Decimal(10_000))
val QUANTUM_CAPACITOR = conciseValues(MNames.QUANTUM_CAPACITOR, Decimal(1_000_000), Decimal(200_000))
val ZPM_BATTERY = conciseValues(MNames.ZPM_BATTERY, Decimal(200_000_000_000_000L), Decimal(200_000_000L))
}
init {
Batteries
builder.pop()
}
val MATTER_DUST_CAPACITY by builder.comment("Maximal matter value one matter dust item can have").defineDecimal("matterDustCapacity", Decimal(2_000), minimum = Decimal.ONE_TENTH)
init {
builder.push("MatterCapacitors")
}
object Capacitors {
val MATTER_CAPACITOR_BASIC by builder.defineDecimal(MNames.MATTER_CAPACITOR_BASIC, Decimal(2_000), minimum = Decimal.ONE_TENTH)
val MATTER_CAPACITOR_NORMAL by builder.defineDecimal(MNames.MATTER_CAPACITOR_NORMAL, Decimal(40_000), minimum = Decimal.ONE_TENTH)
val MATTER_CAPACITOR_DENSE by builder.defineDecimal(MNames.MATTER_CAPACITOR_DENSE, Decimal(400_000), minimum = Decimal.ONE_TENTH)
}
init {
Capacitors
builder.pop()
}
object PatternDrives {
val NORMAL: Int by builder.defineInRange(MNames.PATTERN_DRIVE_NORMAL, 4, 1, Int.MAX_VALUE)
}
}

View File

@ -0,0 +1,32 @@
package ru.dbotthepony.mc.otm.config
import ru.dbotthepony.mc.otm.block.entity.matter.MatterBottlerBlockEntity
import ru.dbotthepony.mc.otm.block.entity.matter.MatterDecomposerBlockEntity
import ru.dbotthepony.mc.otm.block.entity.matter.MatterRecyclerBlockEntity
import ru.dbotthepony.mc.otm.block.entity.matter.MatterReplicatorBlockEntity
import ru.dbotthepony.mc.otm.block.entity.matter.MatterScannerBlockEntity
import ru.dbotthepony.mc.otm.block.entity.tech.AndroidStationBlockEntity
import ru.dbotthepony.mc.otm.block.entity.tech.ChemicalGeneratorBlockEntity
import ru.dbotthepony.mc.otm.capability.energy.BlockEnergyStorageImpl
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.registry.MNames
object MachinesConfig : AbstractConfig("machines") {
init {
AndroidStationBlockEntity.registerConfig(builder)
ChemicalGeneratorBlockEntity.registerConfig(builder)
MatterRecyclerBlockEntity.registerConfig(builder)
MatterBottlerBlockEntity.registerConfig(builder)
MatterReplicatorBlockEntity.registerConfig(builder)
MatterScannerBlockEntity.registerConfig(builder)
MatterDecomposerBlockEntity.registerConfig(builder)
}
val PLATE_PRESS = BlockEnergyStorageImpl.makeConfigEntry(builder, MNames.PLATE_PRESS)
val STORAGE_POWER_SUPPLIER = BlockEnergyStorageImpl.makeConfigEntry(builder, MNames.STORAGE_POWER_SUPPLIER, capacity = Decimal(100_000), throughput = Decimal(320))
val STORAGE_INTERFACES = BlockEnergyStorageImpl.makeConfigEntry(builder, "STORAGE_INTERFACES", capacity = Decimal(10_000))
val ITEM_MONITOR = BlockEnergyStorageImpl.makeConfigEntry(builder, MNames.ITEM_MONITOR)
val DRIVE_VIEWER = BlockEnergyStorageImpl.makeConfigEntry(builder, MNames.DRIVE_VIEWER)
val DRIVE_RACK = BlockEnergyStorageImpl.makeConfigEntry(builder, MNames.DRIVE_RACK, capacity = Decimal(80_000))
}

View File

@ -16,245 +16,7 @@ import ru.dbotthepony.mc.otm.core.math.defineDecimal
import ru.dbotthepony.mc.otm.item.EnergySwordItem
import ru.dbotthepony.mc.otm.registry.MNames
object ServerConfig {
private val specBuilder = ForgeConfigSpec.Builder()
@Suppress("JoinDeclarationAndAssignment")
private val spec: ForgeConfigSpec
private var registered = false
private fun verboseValues(name: String, storage: Decimal, receive: Decimal, extract: Decimal = receive): VerboseBalanceValues {
specBuilder.push(name)
val obj = object : VerboseBalanceValues {
override val capacity: Decimal by specBuilder.defineDecimal("capacity", storage, minimum = Decimal.ONE)
override val receive: Decimal by specBuilder.defineDecimal("receive", receive, minimum = Decimal.ONE)
override val extract: Decimal by specBuilder.defineDecimal("extract", extract, minimum = Decimal.ONE)
}
specBuilder.pop()
return obj
}
private fun batteryValues(name: String, storage: Decimal, receive: Decimal, extract: Decimal = receive, initialBatteryLevel: Decimal = Decimal.ZERO): BatteryBalanceValues {
specBuilder.push(name)
val obj = object : BatteryBalanceValues {
override val capacity: Decimal by specBuilder.defineDecimal("capacity", storage, minimum = Decimal.ONE)
override val receive: Decimal by specBuilder.defineDecimal("receive", receive, minimum = Decimal.ONE)
override val extract: Decimal by specBuilder.defineDecimal("extract", extract, minimum = Decimal.ONE)
override val initialBatteryLevel: Decimal by specBuilder.defineDecimal("initialBatteryLevel", initialBatteryLevel, minimum = Decimal.ZERO)
}
specBuilder.pop()
return obj
}
private fun conciseValues(name: String, storage: Decimal, throughput: Decimal): ConciseBalanceValues {
specBuilder.push(name)
val obj = object : ConciseBalanceValues {
override val capacity: Decimal by specBuilder.defineDecimal("capacity", storage, minimum = Decimal.ONE)
override val throughput: Decimal by specBuilder.defineDecimal("throughput", throughput, minimum = Decimal.ONE)
}
specBuilder.pop()
return obj
}
val LABORATORY_LAMP_LIGHT_LENGTH: Int by specBuilder.comment("In blocks").defineInRange("LABORATORY_LAMP_LIGHT_LENGTH", 6, 1, 128)
init {
specBuilder.comment("Energy batteries balance values").push("energyBatteries")
}
val BATTERY_CRUDE = batteryValues(MNames.BATTERY_CRUDE, Decimal(100_000), Decimal(160), Decimal(40), Decimal(80_000))
val BATTERY_BASIC = batteryValues(MNames.BATTERY_BASIC, Decimal(400_000), Decimal(600))
val BATTERY_NORMAL = batteryValues(MNames.BATTERY_NORMAL, Decimal(2_000_000), Decimal(1_000))
val BATTERY_DENSE = batteryValues(MNames.BATTERY_DENSE, Decimal(10_000_000), Decimal(2_000))
val BATTERY_CAPACITOR = batteryValues(MNames.BATTERY_CAPACITOR, Decimal(500_000), Decimal(50_000))
val QUANTUM_BATTERY = conciseValues(MNames.QUANTUM_BATTERY, Decimal(40_000_000), Decimal(10_000))
val QUANTUM_CAPACITOR = conciseValues(MNames.QUANTUM_CAPACITOR, Decimal(1_000_000), Decimal(200_000))
val ZPM_BATTERY = conciseValues(MNames.ZPM_BATTERY, Decimal(200_000_000_000_000L), Decimal(200_000_000L))
init {
specBuilder.pop()
specBuilder.comment("Matter capacitors and pattern drives balance values").push("matterCapacitorsAndDrives")
}
val MATTER_CAPACITOR_BASIC by specBuilder.defineDecimal(MNames.MATTER_CAPACITOR_BASIC, Decimal(2_000), minimum = Decimal.ONE_TENTH)
val MATTER_CAPACITOR_NORMAL by specBuilder.defineDecimal(MNames.MATTER_CAPACITOR_NORMAL, Decimal(40_000), minimum = Decimal.ONE_TENTH)
val MATTER_CAPACITOR_DENSE by specBuilder.defineDecimal(MNames.MATTER_CAPACITOR_DENSE, Decimal(400_000), minimum = Decimal.ONE_TENTH)
val MATTER_DUST_CAPACITY by specBuilder.comment("Maximal matter value one matter dust item can have").defineDecimal("matterDustCapacity", Decimal(2_000), minimum = Decimal.ONE_TENTH)
val PATTERN_DRIVE_NORMAL: Int by specBuilder.defineInRange(MNames.PATTERN_DRIVE_NORMAL, 4, 1, Int.MAX_VALUE)
init {
specBuilder.pop()
specBuilder.comment("Balance values of machinery").push("machines")
AndroidStationBlockEntity.registerConfig(specBuilder)
ChemicalGeneratorBlockEntity.registerConfig(specBuilder)
MatterRecyclerBlockEntity.registerConfig(specBuilder)
MatterBottlerBlockEntity.registerConfig(specBuilder)
MatterReplicatorBlockEntity.registerConfig(specBuilder)
MatterScannerBlockEntity.registerConfig(specBuilder)
MatterDecomposerBlockEntity.registerConfig(specBuilder)
}
val PLATE_PRESS = BlockEnergyStorageImpl.makeConfigEntry(specBuilder, MNames.PLATE_PRESS)
val STORAGE_POWER_SUPPLIER = BlockEnergyStorageImpl.makeConfigEntry(specBuilder, MNames.STORAGE_POWER_SUPPLIER, capacity = Decimal(100_000), throughput = Decimal(320))
val STORAGE_INTERFACES = BlockEnergyStorageImpl.makeConfigEntry(specBuilder, "STORAGE_INTERFACES", capacity = Decimal(10_000))
val ITEM_MONITOR = BlockEnergyStorageImpl.makeConfigEntry(specBuilder, MNames.ITEM_MONITOR)
val DRIVE_VIEWER = BlockEnergyStorageImpl.makeConfigEntry(specBuilder, MNames.DRIVE_VIEWER)
val DRIVE_RACK = BlockEnergyStorageImpl.makeConfigEntry(specBuilder, MNames.DRIVE_RACK, capacity = Decimal(80_000))
init {
specBuilder.pop()
specBuilder.comment("Tweaking of android players").push("androidPlayer")
}
val REGENERATE_ENERGY: Boolean by specBuilder
.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("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)
object NanobotsRegeneration {
val COOLDOWN: List<Int> by specBuilder
.comment("In ticks, time between heal ticks")
.comment("One heal tick restores 1 heart (2 health points) at most")
.comment("If not getting hurt in specified period of ticks, heal tick takes place, tick timer resets to zero and THIS array' index advances by 1")
.comment("Index inside this array can not exceed of one of ability's")
.comment("")
.comment("Wording in pseudocode:")
.comment("if (ticksSinceTakingDamage >= cooldownConfigOption[healTicks /* or config's biggest index, whichever is smaller */]) {")
.comment(" healTicks = min(healTicks + 1, level /* ability level */)")
.comment(" ticksSinceTakingDamage = 0")
.comment(" this.ply.heal(...)")
.comment("}")
.defineList("COOLDOWN", { mutableListOf(80, 60, 40, 20) }) { it is Int }
val ENERGY_PER_HITPOINT by specBuilder
.comment("Energy required to regenerate 1 health point (half a heart)")
.defineDecimal("ENERGY_PER_HITPOINT", Decimal(800))
}
val ANDROID_ENERGY_PER_HUNGER_POINT by specBuilder.defineDecimal("energyPerHunger", Decimal(2000), Decimal.ZERO)
val ANDROID_MAX_ENERGY by specBuilder.comment("Internal battery of every android has this much storage").defineDecimal("capacity", Decimal(80_000), Decimal.ZERO)
val NIGHT_VISION_POWER_DRAW by specBuilder.defineDecimal("nightVisionPowerDraw", Decimal(8), Decimal.ZERO)
val FALL_DAMAGE_REDUCTION_PER_LEVEL: Double by specBuilder.comment("In percent. Level of feature is multiplied by this").defineInRange("fallDamageReductionPerDampenerLevel", 0.25, 0.01, 1.0)
object EnderTeleporter {
init {
specBuilder.comment("Ender Teleporter ability").push("EnderTeleporter")
}
val ENERGY_COST by specBuilder.defineDecimal("ENERGY_COST", Decimal(4096), Decimal.ZERO)
val COOLDOWN: Int by specBuilder.comment("In ticks").defineInRange("COOLDOWN", 40, 0, Int.MAX_VALUE)
val MAX_PHASE_DISTANCE: Int by specBuilder.comment("Determines how much blocks can we 'phase' through to teleport on solid surface").defineInRange("MAX_PHASE_DISTANCE", 6, 0, Int.MAX_VALUE)
val MAX_DISTANCE: Double by specBuilder.comment("In blocks, euclidean distance").defineInRange("MAX_DISTANCE", 12.0, 2.0, Int.MAX_VALUE.toDouble())
init {
specBuilder.pop()
}
}
object AndroidJumpBoost {
init {
specBuilder.comment("Jump boost ability").push("AndroidJumpBoost")
}
val ENERGY_COST by specBuilder.defineDecimal("ENERGY_COST", Decimal(1024), Decimal.ZERO)
val POWER: Double by specBuilder.comment("The jump height on jump boost, as (level + 1) of feature, in meters per second").defineInRange("POWER", 6.0, 0.0, Double.MAX_VALUE)
val BASE_COOLDOWN: Int by specBuilder.comment("In ticks").defineInRange("BASE_COOLDOWN", 40, 0, Int.MAX_VALUE)
val COOLDOWN_REDUCTION: Int by specBuilder.comment("In ticks, per level of feature").defineInRange("COOLDOWN_REDUCTION", 20, 0, Int.MAX_VALUE)
init {
specBuilder.pop()
}
}
object AndroidItemMagnet {
init {
specBuilder.comment("Item magnet ability").push("AndroidItemMagnet")
}
val POWER_DRAW by specBuilder.comment("Per tick per stack").defineDecimal("POWER_DRAW", Decimal(8), Decimal.ZERO)
val RADIUS_HORIZONTAL: Double by specBuilder.defineInRange("RADIUS_HORIZONTAL", 6.0, 0.0, Double.MAX_VALUE / 4.0)
val RADIUS_VERTICAL: Double by specBuilder.defineInRange("RADIUS_VERTICAL", 3.0, 0.0, Double.MAX_VALUE / 4.0)
init {
specBuilder.pop()
}
}
object Shockwave {
init {
specBuilder.comment("Shockwave ability").push("Shockwave")
}
val TERMINAL_VELOCITY: Double by specBuilder.comment("In meters per second vertically").defineInRange("TERMINAL_VELOCITY", 5.6, 0.0)
val ACCELERATION: Double by specBuilder.comment("In meters per second vertically").defineInRange("ACCELERATION", 4.0, 0.0)
val COOLDOWN: Int by specBuilder.comment("In ticks").defineInRange("COOLDOWN", 30, 1)
val RADIUS_HORIZONTAL: Double by specBuilder.comment("In meters").defineInRange("RADIUS_HORIZONTAL", 4.0, 0.0)
val RADIUS_VERTICAL: Double by specBuilder.comment("In meters").defineInRange("RADIUS_VERTICAL", 1.0, 0.0)
val RADIUS_HORIZONTAL_WARDEN: Double by specBuilder.comment("In meters, when searching for Warden").defineInRange("RADIUS_HORIZONTAL_WARDEN", 16.0, 0.0)
val RADIUS_VERTICAL_WARDEN: Double by specBuilder.comment("In meters, when searching for Warden").defineInRange("RADIUS_VERTICAL_WARDEN", 6.0, 0.0)
val BREAK_BLOCKS: Boolean by specBuilder.comment("Break blocks without any blast resistance").define("BREAK_BLOCKS", true)
val DAMAGE: Double by specBuilder.comment("Max potential damage done by shockwave").defineInRange("DAMAGE", 12.0, 0.0, Float.MAX_VALUE.toDouble())
val WARDEN_DAMAGE_MULT: Double by specBuilder.defineInRange("WARDEN_DAMAGE_MULT", 4.0, 0.0, Float.MAX_VALUE.toDouble())
val ENERGY_COST by specBuilder.defineDecimal("ENERGY_COST", Decimal(2048), Decimal.ZERO)
init {
specBuilder.pop()
}
}
object Tools {
val AXES_BREAK_LEAVES_INSTANTLY: Boolean by specBuilder.define("AXES_BREAK_LEAVES_INSTANTLY", true)
}
init {
// access instances so spec is built
NanobotsRegeneration
EnderTeleporter
AndroidJumpBoost
AndroidItemMagnet
Shockwave
Tools
specBuilder.pop()
specBuilder.comment("Tweaking of exosuits").push("exosuitPlayer")
}
val INFINITE_EXOSUIT_UPGRADES: Boolean by specBuilder.comment("Allows to apply the same upgrade over and over again.", "Obviously completely breaks balance.").define("INFINITE_EXOSUIT_UPGRADES", false)
init {
specBuilder.pop()
EnergySwordItem.registerConfig(specBuilder)
}
init {
spec = specBuilder.build()
}
fun register() {
check(!registered) { "Already registered config" }
registered = true
ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, spec)
}
object ServerConfig : AbstractConfig("misc") {
val LABORATORY_LAMP_LIGHT_LENGTH: Int by builder.comment("In blocks").defineInRange("LABORATORY_LAMP_LIGHT_LENGTH", 6, 1, 128)
val INFINITE_EXOSUIT_UPGRADES: Boolean by builder.comment("Allows to apply the same upgrade over and over again.", "Obviously completely breaks balance.").define("INFINITE_EXOSUIT_UPGRADES", false)
}

View File

@ -0,0 +1,11 @@
package ru.dbotthepony.mc.otm.config
import ru.dbotthepony.mc.otm.item.EnergySwordItem
object ToolsConfig : AbstractConfig("tools") {
val AXES_BREAK_LEAVES_INSTANTLY: Boolean by builder.define("AXES_BREAK_LEAVES_INSTANTLY", true)
init {
EnergySwordItem.registerConfig(builder)
}
}

View File

@ -5,6 +5,7 @@ import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.StringTag
import net.minecraft.nbt.Tag
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.util.RandomSource
import net.minecraftforge.common.ForgeConfigSpec
import ru.dbotthepony.mc.otm.config.ObservedConfigValue
import ru.dbotthepony.mc.otm.core.util.readDouble
@ -937,3 +938,17 @@ fun ForgeConfigSpec.Builder.defineDecimal(path: List<String>, defaultValue: Deci
comment("Default: $defaultValue")
return DecimalConfigValue(define(path, defaultValue.toString()), minimum, maximum)
}
fun RandomSource.nextDecimal(min: Decimal, max: Decimal, round: Boolean = false): Decimal {
val value = nextDouble()
if (round) {
return Decimal((min + (max - min) * value).whole)
} else {
return min + (max - min) * value
}
}
fun RandomSource.nextVariance(value: Decimal, round: Boolean = false): Decimal {
return nextDecimal(-value / 2, value / 2, round)
}

View File

@ -22,6 +22,7 @@ import ru.dbotthepony.mc.otm.capability.energy.ItemEnergyStorageImpl
import ru.dbotthepony.mc.otm.capability.energy.getBarColor
import ru.dbotthepony.mc.otm.capability.energy.getBarWidth
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.config.ItemsConfig
import ru.dbotthepony.mc.otm.core.*
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.registry.MRegistry
@ -159,7 +160,7 @@ open class BatteryItem : Item {
}
}
class CrudeBatteryItem : BatteryItem(ServerConfig.BATTERY_CRUDE) {
class CrudeBatteryItem : BatteryItem(ItemsConfig.Batteries.BATTERY_CRUDE) {
override fun appendHoverText(
stack: ItemStack,
p_41422_: Level?,

View File

@ -40,6 +40,7 @@ import ru.dbotthepony.mc.otm.core.math.DecimalConfigValue
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.math.defineDecimal
import ru.dbotthepony.mc.otm.core.ifPresentK
import ru.dbotthepony.mc.otm.core.math.nextVariance
import ru.dbotthepony.mc.otm.core.orNull
import ru.dbotthepony.mc.otm.registry.EMPDamageSource
import ru.dbotthepony.mc.otm.core.util.WriteOnce
@ -123,9 +124,10 @@ class EnergySwordItem : Item(Properties().stacksTo(1).rarity(Rarity.RARE)), Vani
itemStack.getCapability(MatteryCapability.ENERGY).ifPresentK {
if (it.extractEnergyExact(ENERGY_PER_SWING, false)) {
it.extractEnergy(attacker.level.random.nextVariance(ENERGY_PER_SWING_VARIANCE), false)
victim.matteryPlayer?.let {
if (it.isAndroid) {
it.androidEnergy.extractEnergy(ENERGY_ZAP, false)
if (it.isAndroid && it.androidEnergy.extractEnergyExact(ENERGY_ZAP, false)) {
it.androidEnergy.extractEnergy(attacker.level.random.nextVariance(ENERGY_ZAP_VARIANCE), false)
victim.hurt(EMPDamageSource(attacker), 8f)
}
}
@ -168,18 +170,20 @@ class EnergySwordItem : Item(Properties().stacksTo(1).rarity(Rarity.RARE)), Vani
p_41417_: Level,
blockState: BlockState,
p_41419_: BlockPos,
p_41420_: LivingEntity
user: LivingEntity
): Boolean {
if (blockState.getDestroySpeed(p_41417_, p_41419_) != 0f && (p_41420_ !is Player || !p_41420_.isCreative)) {
if (blockState.getDestroySpeed(p_41417_, p_41419_) != 0f && (user !is Player || !user.isCreative)) {
val energy = itemStack.matteryEnergy
when (blockState.material) {
Material.PLANT, Material.REPLACEABLE_PLANT, Material.VEGETABLE, Material.LEAVES ->
energy?.extractEnergyExact(PLANT_POWER_COST, false)
if (energy?.extractEnergyExact(PLANT_POWER_COST, false) == true)
energy.extractEnergyExact(user.level.random.nextVariance(PLANT_POWER_COST_VARIANCE), false)
}
if (blockState.`is`(Blocks.COBWEB)) {
energy?.extractEnergyExact(COBWEB_POWER_COST, false)
if (energy?.extractEnergyExact(COBWEB_POWER_COST, false) == true)
energy.extractEnergyExact(user.level.random.nextVariance(COBWEB_POWER_COST_VARIANCE), false)
}
}
@ -218,24 +222,36 @@ class EnergySwordItem : Item(Properties().stacksTo(1).rarity(Rarity.RARE)), Vani
companion object {
val MAX_ENERGY get() = _MAX_ENERGY.get()
val ENERGY_ZAP get() = _ENERGY_ZAP.get()
val ENERGY_ZAP_VARIANCE get() = _ENERGY_ZAP_VARIANCE.get()
val ENERGY_PER_SWING get() = _ENERGY_PER_SWING.get()
val ENERGY_PER_SWING_VARIANCE get() = _ENERGY_PER_SWING_VARIANCE.get()
val COBWEB_POWER_COST get() = _COBWEB_POWER_COST.get()
val COBWEB_POWER_COST_VARIANCE get() = _COBWEB_POWER_COST_VARIANCE.get()
val PLANT_POWER_COST get() = _PLANT_POWER_COST.get()
val PLANT_POWER_COST_VARIANCE get() = _PLANT_POWER_COST_VARIANCE.get()
private var _MAX_ENERGY: DecimalConfigValue by WriteOnce()
private var _ENERGY_ZAP: DecimalConfigValue by WriteOnce()
private var _ENERGY_ZAP_VARIANCE: DecimalConfigValue by WriteOnce()
private var _ENERGY_PER_SWING: DecimalConfigValue by WriteOnce()
private var _ENERGY_PER_SWING_VARIANCE: DecimalConfigValue by WriteOnce()
private var _COBWEB_POWER_COST: DecimalConfigValue by WriteOnce()
private var _COBWEB_POWER_COST_VARIANCE: DecimalConfigValue by WriteOnce()
private var _PLANT_POWER_COST: DecimalConfigValue by WriteOnce()
private var _PLANT_POWER_COST_VARIANCE: DecimalConfigValue by WriteOnce()
fun registerConfig(builder: ForgeConfigSpec.Builder) {
builder.comment("Energy sword values").push("energy_sword")
builder.comment("Energy sword values").push("EnergySword")
_MAX_ENERGY = builder.defineDecimal("MAX_ENERGY", Decimal(500_000), Decimal.ZERO)
_ENERGY_ZAP = builder.defineDecimal("ENERGY_ZAP", Decimal(4_000), Decimal.ZERO)
_ENERGY_ZAP = builder.comment("Extra energy required when hitting androids").defineDecimal("ENERGY_ZAP", Decimal(4_000), Decimal.ZERO)
_ENERGY_ZAP_VARIANCE = builder.comment("Random deviation from ENERGY_ZAP").defineDecimal("ENERGY_ZAP_VARIANCE", Decimal(800), Decimal.ZERO)
_ENERGY_PER_SWING = builder.defineDecimal("ENERGY_PER_SWING", Decimal(2_000), Decimal.ZERO)
_ENERGY_PER_SWING_VARIANCE = builder.comment("Random deviation from ENERGY_PER_SWING").defineDecimal("ENERGY_PER_SWING_VARIANCE", Decimal(500), Decimal.ZERO)
_COBWEB_POWER_COST = builder.defineDecimal("COBWEB_POWER_COST", Decimal(2_500), Decimal.ZERO)
_COBWEB_POWER_COST_VARIANCE = builder.comment("Random deviation from COBWEB_POWER_COST").defineDecimal("COBWEB_POWER_COST_VARIANCE", Decimal(500), Decimal.ZERO)
_PLANT_POWER_COST = builder.defineDecimal("PLANT_POWER_COST", Decimal(500), Decimal.ZERO)
_PLANT_POWER_COST_VARIANCE = builder.comment("Random deviation from PLANT_POWER_COST").defineDecimal("PLANT_POWER_COST_VARIANCE", Decimal(100), Decimal.ZERO)
builder.pop()
}

View File

@ -6,6 +6,7 @@ import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.level.Level
import ru.dbotthepony.mc.otm.config.ItemsConfig
import ru.dbotthepony.mc.otm.config.ServerConfig
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.math.Decimal
@ -56,10 +57,10 @@ class MatterDustItem : Item(Properties().stacksTo(64)), IMatterItem {
val matterThis = matter(stack)
if (matterThis >= ServerConfig.MATTER_DUST_CAPACITY)
if (matterThis >= ItemsConfig.MATTER_DUST_CAPACITY)
return Decimal.ZERO
val newMatter = (matterThis + matter).coerceAtMost(ServerConfig.MATTER_DUST_CAPACITY)
val newMatter = (matterThis + matter).coerceAtMost(ItemsConfig.MATTER_DUST_CAPACITY)
val diff = newMatter - matterThis
if (!simulate)
@ -69,7 +70,7 @@ class MatterDustItem : Item(Properties().stacksTo(64)), IMatterItem {
}
fun isFull(stack: ItemStack): Boolean {
return matter(stack) >= ServerConfig.MATTER_DUST_CAPACITY
return matter(stack) >= ItemsConfig.MATTER_DUST_CAPACITY
}
companion object {

View File

@ -5,11 +5,11 @@ import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Tier
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.material.Material
import ru.dbotthepony.mc.otm.config.ServerConfig
import ru.dbotthepony.mc.otm.config.ToolsConfig
class MatteryAxeItem(pTier: Tier, pAttackDamageModifier: Float, pAttackSpeedModifier: Float, pProperties: Properties) : AxeItem(pTier, pAttackDamageModifier, pAttackSpeedModifier, pProperties) {
override fun getDestroySpeed(pStack: ItemStack, pState: BlockState): Float {
if (pState.material == Material.LEAVES && ServerConfig.Tools.AXES_BREAK_LEAVES_INSTANTLY)
if (pState.material == Material.LEAVES && ToolsConfig.AXES_BREAK_LEAVES_INSTANTLY)
return 64f
return super.getDestroySpeed(pStack, pState)

View File

@ -17,6 +17,7 @@ import ru.dbotthepony.mc.otm.capability.energy.EnergyProducerItem
import ru.dbotthepony.mc.otm.capability.energy.ItemEnergyStorageImpl
import ru.dbotthepony.mc.otm.capability.energy.getBarColor
import ru.dbotthepony.mc.otm.capability.energy.getBarWidth
import ru.dbotthepony.mc.otm.config.ItemsConfig
import ru.dbotthepony.mc.otm.core.*
import ru.dbotthepony.mc.otm.core.math.Decimal
@ -63,7 +64,7 @@ open class SingleUseBatteryItem(
}
}
class ZPMItem : SingleUseBatteryItem(ServerConfig.ZPM_BATTERY, Properties().stacksTo(1).rarity(Rarity.EPIC)) {
class ZPMItem : SingleUseBatteryItem(ItemsConfig.Batteries.ZPM_BATTERY, Properties().stacksTo(1).rarity(Rarity.EPIC)) {
override fun appendHoverText(
itemStack: ItemStack,
p_41422_: Level?,

View File

@ -14,6 +14,7 @@ import net.minecraftforge.eventbus.api.IEventBus
import net.minecraftforge.registries.DeferredRegister
import net.minecraftforge.registries.ForgeRegistries
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.config.ItemsConfig
import ru.dbotthepony.mc.otm.config.ServerConfig
import ru.dbotthepony.mc.otm.core.collect.SupplierList
import ru.dbotthepony.mc.otm.core.TranslatableComponent
@ -200,14 +201,14 @@ object MItems {
)
val BATTERY_CRUDE: Item by registry.register(MNames.BATTERY_CRUDE) { CrudeBatteryItem() }
val BATTERY_BASIC: Item by registry.register(MNames.BATTERY_BASIC) { BatteryItem(ServerConfig.BATTERY_BASIC) }
val BATTERY_NORMAL: Item by registry.register(MNames.BATTERY_NORMAL) { BatteryItem(ServerConfig.BATTERY_NORMAL) }
val BATTERY_DENSE: Item by registry.register(MNames.BATTERY_DENSE) { BatteryItem(ServerConfig.BATTERY_DENSE) }
val BATTERY_CAPACITOR: Item by registry.register(MNames.BATTERY_CAPACITOR) { BatteryItem(ServerConfig.BATTERY_CAPACITOR) }
val BATTERY_BASIC: Item by registry.register(MNames.BATTERY_BASIC) { BatteryItem(ItemsConfig.Batteries.BATTERY_BASIC) }
val BATTERY_NORMAL: Item by registry.register(MNames.BATTERY_NORMAL) { BatteryItem(ItemsConfig.Batteries.BATTERY_NORMAL) }
val BATTERY_DENSE: Item by registry.register(MNames.BATTERY_DENSE) { BatteryItem(ItemsConfig.Batteries.BATTERY_DENSE) }
val BATTERY_CAPACITOR: Item by registry.register(MNames.BATTERY_CAPACITOR) { BatteryItem(ItemsConfig.Batteries.BATTERY_CAPACITOR) }
val BATTERY_CREATIVE: Item by registry.register(MNames.BATTERY_CREATIVE) { BatteryItem() }
val QUANTUM_BATTERY: Item by registry.register(MNames.QUANTUM_BATTERY) { QuantumBatteryItem(MNames.QUANTUM_BATTERY, ServerConfig.QUANTUM_BATTERY) }
val QUANTUM_CAPACITOR: Item by registry.register(MNames.QUANTUM_CAPACITOR) { QuantumBatteryItem(MNames.QUANTUM_CAPACITOR, ServerConfig.QUANTUM_CAPACITOR) }
val QUANTUM_BATTERY: Item by registry.register(MNames.QUANTUM_BATTERY) { QuantumBatteryItem(MNames.QUANTUM_BATTERY, ItemsConfig.Batteries.QUANTUM_BATTERY) }
val QUANTUM_CAPACITOR: Item by registry.register(MNames.QUANTUM_CAPACITOR) { QuantumBatteryItem(MNames.QUANTUM_CAPACITOR, ItemsConfig.Batteries.QUANTUM_CAPACITOR) }
val QUANTUM_BATTERY_CREATIVE: Item by registry.register(MNames.QUANTUM_BATTERY_CREATIVE) { QuantumBatteryItem(MNames.QUANTUM_BATTERY_CREATIVE) }
val ZPM_BATTERY: Item by registry.register(MNames.ZPM_BATTERY) { ZPMItem() }
@ -240,9 +241,9 @@ object MItems {
::ZPM_BATTERY,
)
val MATTER_CAPACITOR_BASIC: Item by registry.register(MNames.MATTER_CAPACITOR_BASIC) { MatterCapacitorItem(ServerConfig::MATTER_CAPACITOR_BASIC) }
val MATTER_CAPACITOR_NORMAL: Item by registry.register(MNames.MATTER_CAPACITOR_NORMAL) { MatterCapacitorItem(ServerConfig::MATTER_CAPACITOR_NORMAL) }
val MATTER_CAPACITOR_DENSE: Item by registry.register(MNames.MATTER_CAPACITOR_DENSE) { MatterCapacitorItem(ServerConfig::MATTER_CAPACITOR_DENSE) }
val MATTER_CAPACITOR_BASIC: Item by registry.register(MNames.MATTER_CAPACITOR_BASIC) { MatterCapacitorItem(ItemsConfig.Capacitors::MATTER_CAPACITOR_BASIC) }
val MATTER_CAPACITOR_NORMAL: Item by registry.register(MNames.MATTER_CAPACITOR_NORMAL) { MatterCapacitorItem(ItemsConfig.Capacitors::MATTER_CAPACITOR_NORMAL) }
val MATTER_CAPACITOR_DENSE: Item by registry.register(MNames.MATTER_CAPACITOR_DENSE) { MatterCapacitorItem(ItemsConfig.Capacitors::MATTER_CAPACITOR_DENSE) }
val MATTER_CAPACITOR_CREATIVE: Item by registry.register(MNames.MATTER_CAPACITOR_CREATIVE) { MatterCapacitorItem() }
val MATTER_CAPACITORS = SupplierList(
@ -252,7 +253,7 @@ object MItems {
::MATTER_CAPACITOR_CREATIVE,
)
val PATTERN_DRIVE_NORMAL: Item by registry.register(MNames.PATTERN_DRIVE_NORMAL) { PatternStorageItem(ServerConfig::PATTERN_DRIVE_NORMAL) }
val PATTERN_DRIVE_NORMAL: Item by registry.register(MNames.PATTERN_DRIVE_NORMAL) { PatternStorageItem(ItemsConfig.PatternDrives::NORMAL) }
val PATTERN_DRIVE_CREATIVE: Item by registry.register(MNames.PATTERN_DRIVE_CREATIVE) { PatternStorageItem() }
val PATTERN_DRIVE_CREATIVE2: Item by registry.register(MNames.PATTERN_DRIVE_CREATIVE2) { CreativePatternItem() }