Jump boost android feature

This commit is contained in:
DBotThePony 2022-09-26 20:32:20 +07:00
parent 144c84dabd
commit 5f652e7714
Signed by: DBot
GPG Key ID: DCC23B5715498507
12 changed files with 220 additions and 35 deletions

View File

@ -7,6 +7,7 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.android.AndroidResearchType
import ru.dbotthepony.mc.otm.android.feature.FallDampenersFeature
import ru.dbotthepony.mc.otm.android.feature.ItemMagnetFeature
import ru.dbotthepony.mc.otm.android.feature.JumpBoostFeature
import ru.dbotthepony.mc.otm.android.feature.NanobotsArmorFeature
import ru.dbotthepony.mc.otm.android.feature.ShockwaveFeature
import ru.dbotthepony.mc.otm.client.render.ResearchIcons
@ -345,6 +346,36 @@ fun addResearchData(serializer: Consumer<AndroidResearchType>, lang: MatteryLang
serializer.accept(PHANTOM_ATTRACTOR)
val JUMP_BOOST_1 =
AndroidResearchType.Builder(modLocation(MNames.JUMP_BOOST + "_1"))
.withExperience(27)
.withDescription(0 .. 1)
.appendDescription(JumpBoostFeature.POWER_COST_DESCRIPTION)
.withIcon(ResearchIcons.ICON_JUMP_BOOST)
.addFeatureResult(AndroidFeatures.JUMP_BOOST, 0)
.addItem(MItemTags.PISTONS, 2)
.addItem(MItemTags.GOLD_WIRES, 4)
.addItem(MItems.ELECTROMAGNET, 2)
.withIconText(TextComponent("1"))
.addPrerequisite(FALL_DAMPENERS_1)
.build()
val JUMP_BOOST_2 =
AndroidResearchType.Builder(modLocation(MNames.JUMP_BOOST + "_2"))
.withExperience(34)
.withDescription()
.appendDescription(JumpBoostFeature.POWER_COST_DESCRIPTION)
.withIcon(ResearchIcons.ICON_JUMP_BOOST)
.addFeatureResult(AndroidFeatures.JUMP_BOOST, 1)
.addItem(MItems.ELECTRIC_PARTS, 4)
.addItem(MItems.ELECTROMAGNET, 4)
.addPrerequisite(JUMP_BOOST_1)
.withIconText(TextComponent("2"))
.build()
serializer.accept(JUMP_BOOST_1)
serializer.accept(JUMP_BOOST_2)
with(lang.english) {
misc("fall_dampeners.description", "Reduces fall damage by %s%%")
@ -399,6 +430,13 @@ fun addResearchData(serializer: Consumer<AndroidResearchType>, lang: MatteryLang
add(PHANTOM_ATTRACTOR, "Builtin Phantom Attractor")
add(PHANTOM_ATTRACTOR, "description", "Allows unit to attract phantoms while active under same conditions as non-androids")
add(JUMP_BOOST_1, "Jump Boost")
add(JUMP_BOOST_1, "description0", "Allows unit to perform higher jump")
add(JUMP_BOOST_1, "description1", "Can be activated by crouching and jumping at the same time")
add(JUMP_BOOST_2, "Jump Boost 2")
add(JUMP_BOOST_2, "description", "Allows unit to perform extra higher jump")
add(attackBoostList[0], "Attack Boost %s")
add(attackBoostList[0], "description", "Increases total melee attack strength by %s%%")
}

View File

@ -491,6 +491,7 @@ private fun androidFeatures(provider: MatteryLanguageProvider) {
add(AndroidFeatures.ITEM_MAGNET, "Item Magnet")
add(AndroidFeatures.STEP_ASSIST, "Step Assist")
add(AndroidFeatures.PHANTOM_ATTRACTOR, "Phantom Attractor")
add(AndroidFeatures.JUMP_BOOST, "Jump Boost")
}
}

View File

@ -5,25 +5,28 @@ import net.minecraftforge.fml.ModLoadingContext
import net.minecraftforge.fml.config.ModConfig
object ClientConfig {
private val specBuilder = ForgeConfigSpec.Builder()
private val spec: ForgeConfigSpec
private var registered = false
private val _exosuitInventoryRows: ForgeConfigSpec.IntValue
init {
val specBuilder = ForgeConfigSpec.Builder()
specBuilder.comment("Clientside Config").push("client")
_exosuitInventoryRows = specBuilder
.comment("Amount of inventory rows to show when wearing Exosuit")
.defineInRange("exosuitInventoryRows", 3, 3, 6)
}
var EXOSUIT_INVENTORY_ROWS: Int by specBuilder
.comment("Amount of inventory rows to show when wearing Exosuit")
.defineInRange("exosuitInventoryRows", 3, 3, 6)
var JUMP_BOOST_LOOK_ANGLE: Double by specBuilder
.comment("If looking below this angle (actually, looking 'above' as you see in game, but not as you expect it, check with debug screen), Crouch + Jump will trigger jump boost android ability")
.defineInRange("jumpBoostTriggerAngle", 30.0, -180.0, 180.0)
init {
specBuilder.pop()
spec = specBuilder.build()
}
var exosuitInventoryRows: Int by _exosuitInventoryRows
fun register() {
check(!registered) { "Already registered config" }
registered = true

View File

@ -147,6 +147,21 @@ object ServerConfig {
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 AndroidJumpBoost {
init {
specBuilder.comment("Jump boost ability").push("jump_boost")
}
val ENERGY_COST by specBuilder.defineImpreciseFraction("energyCost", ImpreciseFraction(1024), ImpreciseFraction.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("baseCooldown", 40, 0, Int.MAX_VALUE)
val COOLDOWN_REDUCTION: Int by specBuilder.comment("In ticks, per level of feature").defineInRange("cooldownReduction", 20, 0, Int.MAX_VALUE)
init {
specBuilder.pop()
}
}
object AndroidItemMagnet {
init {
specBuilder.comment("Item magnet ability").push("item_magnet")
@ -182,6 +197,7 @@ object ServerConfig {
init {
// access shockwave class so spec is built
AndroidJumpBoost
AndroidItemMagnet
Shockwave

View File

@ -0,0 +1,115 @@
package ru.dbotthepony.mc.otm.android.feature
import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.PoseStack
import net.minecraft.ChatFormatting
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraftforge.network.NetworkEvent
import ru.dbotthepony.mc.otm.ClientConfig
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.ServerConfig
import ru.dbotthepony.mc.otm.android.AndroidResearchManager
import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
import ru.dbotthepony.mc.otm.capability.extractEnergyInnerExact
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.client.render.ResearchIcons
import ru.dbotthepony.mc.otm.core.Vector
import ru.dbotthepony.mc.otm.core.formatPower
import ru.dbotthepony.mc.otm.core.plus
import ru.dbotthepony.mc.otm.network.MatteryPacket
import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel
import ru.dbotthepony.mc.otm.network.enqueueWork
import ru.dbotthepony.mc.otm.network.packetHandled
import ru.dbotthepony.mc.otm.network.sender
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
import ru.dbotthepony.mc.otm.registry.MNames
import java.util.function.Supplier
object TriggerJumpBoostPacket : MatteryPacket {
override fun write(buff: FriendlyByteBuf) {
// no op
}
override fun play(context: Supplier<NetworkEvent.Context>) {
context.packetHandled = true
context.enqueueWork {
val mattery = context.sender?.matteryPlayer ?: return@enqueueWork
if (!mattery.isAndroid)
return@enqueueWork
val feature = mattery.getFeature(AndroidFeatures.JUMP_BOOST) as JumpBoostFeature? ?: return@enqueueWork
if (feature.isActive && feature.cooldown <= 4 && mattery.androidEnergy.extractEnergyInnerExact(ServerConfig.AndroidJumpBoost.ENERGY_COST, false).isPositive) {
feature.putOnCooldown()
}
}
}
}
class JumpBoostFeature(capability: MatteryPlayerCapability) : AndroidSwitchableFeature(AndroidFeatures.JUMP_BOOST, capability) {
private var tickCooldownClient = false
var cooldown by synchronizer.int(setter = setter@{ value, access, setByRemote ->
access.write(value)
if (setByRemote) {
tickCooldownClient = false
}
})
fun putOnCooldown() {
cooldown = (ServerConfig.AndroidJumpBoost.BASE_COOLDOWN - ServerConfig.AndroidJumpBoost.COOLDOWN_REDUCTION * level).coerceAtLeast(0)
}
private var lastGround = false
fun movementTick(isJumping: Boolean, isShifting: Boolean) {
check(ply !is ServerPlayer) { "Invalid side" }
val old = lastGround
lastGround = ply.isOnGround
if (isActive && cooldown <= 0 && old != lastGround && !lastGround && isJumping && isShifting && ply.xRot <= ClientConfig.JUMP_BOOST_LOOK_ANGLE && android.androidEnergy.extractEnergyInnerExact(ServerConfig.AndroidJumpBoost.ENERGY_COST, true).isPositive) {
ply.deltaMovement += Vector(0.0, ServerConfig.AndroidJumpBoost.POWER * (level + 1) / 20.0, 0.0)
putOnCooldown()
MatteryPlayerNetworkChannel.sendToServer(TriggerJumpBoostPacket)
}
}
override fun tickClient() {
if (tickCooldownClient && cooldown > 0) {
cooldown--
}
}
override fun tickServer() {
if (cooldown > 0) {
cooldown--
}
}
override fun renderIcon(stack: PoseStack, x: Float, y: Float, width: Float, height: Float) {
if (cooldown > 0) {
RenderSystem.setShaderColor(1f, 0.4f, 0.4f, 1f)
}
ResearchIcons.ICON_JUMP_BOOST.render(stack, x, y, width, height)
if (cooldown > 0) {
RenderSystem.setShaderColor(1f, 1f, 1f, 1f)
}
}
companion object {
val POWER_COST_DESCRIPTION =
AndroidResearchManager.descriptionFunc(
ResourceLocation(OverdriveThatMatters.MOD_ID, MNames.JUMP_BOOST),
"otm.gui.power_cost_per_use",
{ ServerConfig.AndroidJumpBoost.ENERGY_COST.formatPower().copy().withStyle(ChatFormatting.YELLOW) })
}
}

View File

@ -3,10 +3,10 @@ package ru.dbotthepony.mc.otm.android.feature
import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.PoseStack
import net.minecraft.ChatFormatting
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.level.block.Block
import net.minecraft.world.phys.AABB
import net.minecraftforge.network.NetworkEvent
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.ServerConfig
import ru.dbotthepony.mc.otm.android.AndroidResearchManager
@ -14,10 +14,8 @@ import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
import ru.dbotthepony.mc.otm.capability.extractEnergyInnerExact
import ru.dbotthepony.mc.otm.client.render.ResearchIcons
import ru.dbotthepony.mc.otm.core.TextComponent
import ru.dbotthepony.mc.otm.core.Vector
import ru.dbotthepony.mc.otm.core.formatPower
import ru.dbotthepony.mc.otm.core.formatSi
import ru.dbotthepony.mc.otm.core.getEllipsoidBlockPositions
import ru.dbotthepony.mc.otm.core.getEntitiesInEllipsoid
import ru.dbotthepony.mc.otm.core.getExplosionResistance
@ -27,13 +25,35 @@ import ru.dbotthepony.mc.otm.core.position
import ru.dbotthepony.mc.otm.core.roundToIntVector
import ru.dbotthepony.mc.otm.core.times
import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel
import ru.dbotthepony.mc.otm.network.TriggerShockwavePacket
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.network.MatteryPacket
import ru.dbotthepony.mc.otm.network.enqueueWork
import ru.dbotthepony.mc.otm.network.packetHandled
import ru.dbotthepony.mc.otm.network.sender
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
import ru.dbotthepony.mc.otm.registry.MNames
import ru.dbotthepony.mc.otm.registry.ShockwaveDamageSource
import java.util.function.Supplier
import kotlin.math.pow
import kotlin.math.roundToInt
object TriggerShockwavePacket : MatteryPacket {
override fun write(buff: FriendlyByteBuf) {
// no op
}
override fun play(context: Supplier<NetworkEvent.Context>) {
context.packetHandled = true
context.enqueueWork {
val shockwave = context.sender?.matteryPlayer?.getFeature(AndroidFeatures.SHOCKWAVE) as ShockwaveFeature? ?: return@enqueueWork
if (shockwave.cooldown <= 0 && shockwave.isActive && shockwave.airTicks > 0) {
shockwave.shockwave()
}
}
}
}
class ShockwaveFeature(capability: MatteryPlayerCapability) : AndroidSwitchableFeature(AndroidFeatures.SHOCKWAVE, capability) {
var cooldown by synchronizer.int()

View File

@ -6,6 +6,7 @@ import net.minecraft.client.gui.screens.inventory.InventoryScreen
import net.minecraft.world.inventory.InventoryMenu
import net.minecraftforge.client.event.MovementInputUpdateEvent
import net.minecraftforge.client.event.ScreenEvent
import ru.dbotthepony.mc.otm.android.feature.JumpBoostFeature
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
import ru.dbotthepony.mc.otm.client.render.Widgets18
@ -22,6 +23,10 @@ fun onMovementInputUpdate(event: MovementInputUpdateEvent) {
val cap = ply.matteryPlayer ?: return
if (cap.isAndroid) {
(cap.getFeature(AndroidFeatures.JUMP_BOOST) as JumpBoostFeature?)?.movementTick(input.jumping, input.shiftKeyDown)
}
if (!cap.isAndroid || cap.hasFeature(AndroidFeatures.AIR_BAGS))
return

View File

@ -578,6 +578,6 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
const val MAX_ROWS = 6
var lastScroll = 0
var lastRows by ClientConfig::exosuitInventoryRows
var lastRows by ClientConfig::EXOSUIT_INVENTORY_ROWS
}
}

View File

@ -9,13 +9,12 @@ import net.minecraftforge.network.NetworkDirection.PLAY_TO_CLIENT
import net.minecraftforge.network.NetworkDirection.PLAY_TO_SERVER
import net.minecraftforge.network.NetworkEvent
import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.android.AndroidFeature
import ru.dbotthepony.mc.otm.android.AndroidFeatureType
import ru.dbotthepony.mc.otm.android.AndroidResearch
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.android.feature.ShockwaveFeature
import ru.dbotthepony.mc.otm.android.feature.TriggerJumpBoostPacket
import ru.dbotthepony.mc.otm.android.feature.TriggerShockwavePacket
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.client.MatteryGUI
import ru.dbotthepony.mc.otm.client.minecraft
@ -23,7 +22,6 @@ import ru.dbotthepony.mc.otm.menu.AndroidStationMenu
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
import ru.dbotthepony.mc.otm.registry.MRegistry
import java.io.ByteArrayInputStream
import java.io.OutputStream
import java.util.function.Supplier
class MatteryPlayerFieldPacket(val bytes: ByteArray, val length: Int) : MatteryPacket {
@ -340,23 +338,6 @@ class SwitchAndroidFeaturePacket(val type: AndroidFeatureType<*>, val newState:
}
}
object TriggerShockwavePacket : MatteryPacket {
override fun write(buff: FriendlyByteBuf) {
// no op
}
override fun play(context: Supplier<NetworkEvent.Context>) {
context.packetHandled = true
context.enqueueWork {
val shockwave = context.sender?.matteryPlayer?.getFeature(AndroidFeatures.SHOCKWAVE) as ShockwaveFeature? ?: return@enqueueWork
if (shockwave.cooldown <= 0 && shockwave.isActive && shockwave.airTicks > 0) {
shockwave.shockwave()
}
}
}
}
object MatteryPlayerNetworkChannel : MatteryNetworkChannel(
version = "1",
name = "player"
@ -378,6 +359,8 @@ object MatteryPlayerNetworkChannel : MatteryNetworkChannel(
add(ExoSuitMenuOpen::class, { ExoSuitMenuOpen }, PLAY_TO_SERVER)
add(SwitchAndroidFeaturePacket::class, SwitchAndroidFeaturePacket.Companion::read, PLAY_TO_SERVER)
add(TriggerShockwavePacket::class, { TriggerShockwavePacket }, PLAY_TO_SERVER)
add(TriggerJumpBoostPacket::class, { TriggerJumpBoostPacket }, PLAY_TO_SERVER)
}
}

View File

@ -22,6 +22,7 @@ object AndroidFeatures {
val ITEM_MAGNET: AndroidFeatureType<*> by registry.register(MNames.ITEM_MAGNET) { AndroidFeatureType(::ItemMagnetFeature) }
val FALL_DAMPENERS: AndroidFeatureType<*> by registry.register(MNames.FALL_DAMPENERS) { AndroidFeatureType(::FallDampenersFeature) }
val PHANTOM_ATTRACTOR: AndroidFeatureType<*> by registry.register(MNames.PHANTOM_ATTRACTOR) { AndroidFeatureType(::PhantomAttractorFeature) }
val JUMP_BOOST: AndroidFeatureType<*> by registry.register(MNames.JUMP_BOOST) { AndroidFeatureType(::JumpBoostFeature) }
internal fun register(bus: IEventBus) {
registry.register(bus)

View File

@ -224,6 +224,7 @@ object MNames {
const val PLASMA = "plasma_projectile"
const val PHANTOM_ATTRACTOR = "phantom_attractor"
const val JUMP_BOOST = "jump_boost"
}
object StatNames {

View File

@ -26,6 +26,7 @@ import ru.dbotthepony.mc.otm.android.AndroidFeatureType
import ru.dbotthepony.mc.otm.android.AndroidResearchType
import ru.dbotthepony.mc.otm.android.feature.FallDampenersFeature
import ru.dbotthepony.mc.otm.android.feature.ItemMagnetFeature
import ru.dbotthepony.mc.otm.android.feature.JumpBoostFeature
import ru.dbotthepony.mc.otm.android.feature.NanobotsArmorFeature
import ru.dbotthepony.mc.otm.android.feature.ShockwaveFeature
import ru.dbotthepony.mc.otm.block.CargoCrateBlock
@ -240,5 +241,6 @@ object MRegistry {
ShockwaveFeature.Companion
ItemMagnetFeature.Companion
FallDampenersFeature.Companion
JumpBoostFeature.Companion
}
}