Plasma weapon heating, hud and energy usage
This commit is contained in:
parent
2314dbfa85
commit
d9ce8ca3b5
@ -340,6 +340,8 @@ public class RenderHelper {
|
||||
|
||||
private static RGBAColor draw_color = new RGBAColor(255, 255, 255, 255);
|
||||
|
||||
public static boolean forwardWinding = true;
|
||||
|
||||
/**
|
||||
* Draws a solid color rectangle on screen, defined by last setDrawColor(RGBColor rect_color) call
|
||||
*
|
||||
@ -368,10 +370,17 @@ public class RenderHelper {
|
||||
|
||||
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
|
||||
|
||||
if (forwardWinding) {
|
||||
builder.vertex(matrix, x, y + height, depth_z).color(draw_color.getRed(), draw_color.getGreen(), draw_color.getBlue(), draw_color.getAlpha()).endVertex();
|
||||
builder.vertex(matrix, x + width, y + height, depth_z).color(draw_color.getRed(), draw_color.getGreen(), draw_color.getBlue(), draw_color.getAlpha()).endVertex();
|
||||
builder.vertex(matrix, x + width, y, depth_z).color(draw_color.getRed(), draw_color.getGreen(), draw_color.getBlue(), draw_color.getAlpha()).endVertex();
|
||||
builder.vertex(matrix, x, y, depth_z).color(draw_color.getRed(), draw_color.getGreen(), draw_color.getBlue(), draw_color.getAlpha()).endVertex();
|
||||
} else {
|
||||
builder.vertex(matrix, x, y, depth_z).color(draw_color.getRed(), draw_color.getGreen(), draw_color.getBlue(), draw_color.getAlpha()).endVertex();
|
||||
builder.vertex(matrix, x + width, y, depth_z).color(draw_color.getRed(), draw_color.getGreen(), draw_color.getBlue(), draw_color.getAlpha()).endVertex();
|
||||
builder.vertex(matrix, x + width, y + height, depth_z).color(draw_color.getRed(), draw_color.getGreen(), draw_color.getBlue(), draw_color.getAlpha()).endVertex();
|
||||
builder.vertex(matrix, x, y + height, depth_z).color(draw_color.getRed(), draw_color.getGreen(), draw_color.getBlue(), draw_color.getAlpha()).endVertex();
|
||||
}
|
||||
|
||||
tess.end();
|
||||
|
||||
|
@ -261,6 +261,15 @@ data class MutableAngle(override var pitch: Double = 0.0, override var yaw: Doub
|
||||
}
|
||||
}
|
||||
|
||||
fun linearInterpolation(t: Float, a: Float, b: Float): Float {
|
||||
if (t <= 0f)
|
||||
return a
|
||||
else if (t >= 1f)
|
||||
return b
|
||||
|
||||
return a + t * (b - a)
|
||||
}
|
||||
|
||||
fun linearInterpolation(t: Double, a: Double, b: Double): Double {
|
||||
if (t <= 0.0)
|
||||
return a
|
||||
|
@ -41,6 +41,15 @@ data class RGBAColor(val red: Float, val green: Float, val blue: Float, val alph
|
||||
RenderHelper.setDrawColor(this)
|
||||
}
|
||||
|
||||
fun linearInterpolation(t: Float, other: RGBAColor): RGBAColor {
|
||||
return RGBAColor(
|
||||
linearInterpolation(t, red, other.red),
|
||||
linearInterpolation(t, green, other.green),
|
||||
linearInterpolation(t, blue, other.blue),
|
||||
linearInterpolation(t, alpha, other.alpha),
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val BLACK = RGBAColor(0f, 0f, 0f, 1f)
|
||||
val WHITE = RGBAColor(1f, 1f, 1f, 1f)
|
||||
@ -56,3 +65,7 @@ data class RGBAColor(val red: Float, val green: Float, val blue: Float, val alph
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun linearInterpolation(t: Float, a: RGBAColor, b: RGBAColor): RGBAColor {
|
||||
return a.linearInterpolation(t, b)
|
||||
}
|
||||
|
@ -1,11 +1,15 @@
|
||||
package ru.dbotthepony.mc.otm.item.weapon
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem
|
||||
import com.mojang.blaze3d.vertex.*
|
||||
import com.mojang.math.Vector3f
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.model.HumanoidModel
|
||||
import net.minecraft.client.renderer.GameRenderer
|
||||
import net.minecraft.client.renderer.block.model.ItemTransforms
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.Item
|
||||
@ -20,9 +24,14 @@ import net.minecraftforge.event.TickEvent
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||
import net.minecraftforge.fml.LogicalSide
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
import org.lwjgl.opengl.GL30
|
||||
import ru.dbotthepony.mc.otm.*
|
||||
import ru.dbotthepony.mc.otm.capability.matteryEnergy
|
||||
import ru.dbotthepony.mc.otm.client.font
|
||||
import ru.dbotthepony.mc.otm.client.render.RenderHelper
|
||||
import ru.dbotthepony.mc.otm.core.*
|
||||
import ru.dbotthepony.mc.otm.core.Vector
|
||||
import ru.dbotthepony.mc.otm.menu.FormattingHelper
|
||||
import ru.dbotthepony.mc.otm.network.MatteryNetworking
|
||||
import java.util.*
|
||||
import java.util.function.Supplier
|
||||
@ -104,7 +113,7 @@ open class WeaponDataTable(val tag: CompoundTag) {
|
||||
var fireAnim = 0.0
|
||||
var fireAnimDeviation = Angle.ZERO
|
||||
|
||||
fun doFireAnim(amount: Double = 1.0, deviation: Angle? = null) {
|
||||
fun doFireAnim(amount: Double = 0.8, deviation: Angle? = null) {
|
||||
fireAnim = (fireAnim + amount).coerceAtLeast(0.0).coerceAtMost(1.0)
|
||||
|
||||
if (deviation != null) {
|
||||
@ -225,8 +234,17 @@ abstract class AbstractWeaponItem<D : WeaponDataTable>(val tables: KClass<D>, ra
|
||||
return false
|
||||
}
|
||||
|
||||
open fun canPrimaryFire(itemStack: ItemStack, player: Player, dt: D = dataTable(itemStack)): Boolean {
|
||||
if (player is ServerPlayer) {
|
||||
// allow a little deviation, becuse nothing is perfect
|
||||
return dt.nextPrimaryFire <= 2
|
||||
}
|
||||
|
||||
return dt.nextPrimaryFire <= 0
|
||||
}
|
||||
|
||||
fun tryPrimaryFire(itemStack: ItemStack, player: Player, dt: D = dataTable(itemStack)): Boolean {
|
||||
if (dt.nextPrimaryFire <= 0 && primaryFire(itemStack, player, dt)) {
|
||||
if (canPrimaryFire(itemStack, player, dt) && primaryFire(itemStack, player, dt)) {
|
||||
dt.nextPrimaryFire = fireCooldown
|
||||
return true
|
||||
}
|
||||
@ -357,7 +375,7 @@ abstract class AbstractWeaponItem<D : WeaponDataTable>(val tables: KClass<D>, ra
|
||||
(item as AbstractWeaponItem<WeaponDataTable>).dataTable = predictedData
|
||||
|
||||
predictedData?.deployTime = (predictedData!!.deployTime + diff.toDouble() / (300_000_000.0 * item.deployAnimSpeed)).coerceAtMost(1.0).coerceAtLeast(0.0)
|
||||
predictedData?.fireAnim = (predictedData!!.fireAnim - diff.toDouble() / (300_000_000.0 * item.fireAnimRecovery)).coerceAtMost(1.0).coerceAtLeast(0.0)
|
||||
predictedData?.fireAnim = (predictedData!!.fireAnim - diff.toDouble() / (400_000_000.0 * item.fireAnimRecovery)).coerceAtMost(1.0).coerceAtLeast(0.0)
|
||||
|
||||
val player = Minecraft.getInstance().player!!
|
||||
val pose = event.poseStack
|
||||
@ -404,9 +422,9 @@ abstract class AbstractWeaponItem<D : WeaponDataTable>(val tables: KClass<D>, ra
|
||||
)
|
||||
|
||||
val rotFire = item.rotFireAnim
|
||||
pitch += (rotFire.pitch + (predictedData?.fireAnimDeviation?.pitch ?: 0.0)) * fireAnim
|
||||
yaw += (rotFire.yaw + (predictedData?.fireAnimDeviation?.yaw ?: 0.0)) * fireAnim
|
||||
roll += (rotFire.roll + (predictedData?.fireAnimDeviation?.roll ?: 0.0)) * fireAnim
|
||||
pitch += (rotFire.pitch + (predictedData?.fireAnimDeviation?.pitch ?: 0.0)) * fireAnim * (1.0 - progress * 0.6)
|
||||
yaw += (rotFire.yaw + (predictedData?.fireAnimDeviation?.yaw ?: 0.0)) * fireAnim * (1.0 - progress * 0.6)
|
||||
roll += (rotFire.roll + (predictedData?.fireAnimDeviation?.roll ?: 0.0)) * fireAnim * (1.0 - progress * 0.6)
|
||||
|
||||
pose.mulPose(Vector3f.ZP.rotation(roll.toFloat()))
|
||||
pose.mulPose(Vector3f.YP.rotation(yaw.toFloat()))
|
||||
@ -422,12 +440,51 @@ abstract class AbstractWeaponItem<D : WeaponDataTable>(val tables: KClass<D>, ra
|
||||
event.packedLight
|
||||
)
|
||||
|
||||
if (item is PlasmaWeaponItem<*>) {
|
||||
// RenderSystem.setShader(GameRenderer::getPositionColorShader)
|
||||
// RenderSystem.disableTexture()
|
||||
// RenderSystem.enableBlend()
|
||||
|
||||
RenderSystem.setShaderColor(1f, 1f, 1f, 1f)
|
||||
|
||||
pose.translate(-0.85, 0.25, -0.25)
|
||||
pose.mulPose(Vector3f.ZP.rotationDegrees(180f))
|
||||
pose.mulPose(Vector3f.YP.rotationDegrees(180f))
|
||||
pose.scale(0.01f, 0.01f, 0.01f)
|
||||
|
||||
RenderHelper.setDrawColor(holoHudBackground)
|
||||
RenderHelper.drawRect(pose, -2f, -2f, 72f, 34f)
|
||||
|
||||
stack.matteryEnergy?.let {
|
||||
pose.pushPose()
|
||||
pose.translate(0.0, 0.0, -1.0)
|
||||
pose.scale(0.7f, 0.7f, 0.7f)
|
||||
val text = FormattingHelper.formatPower(it.batteryLevel)
|
||||
font.draw(pose, text, 2f, 2f, RGBAColor.WHITE.toInt())
|
||||
pose.popPose()
|
||||
}
|
||||
|
||||
pose.translate(60.0, 0.0, 0.0)
|
||||
|
||||
RenderHelper.setDrawColor(heatBackground)
|
||||
RenderHelper.drawRect(pose, -1f, -1f, 9f, 32f)
|
||||
|
||||
val heat = item.heatProgress(stack, event.partialTicks.toDouble()).toFloat()
|
||||
RenderHelper.setDrawColor(linearInterpolation(heat, initialHeatColor, finalHeatColor))
|
||||
RenderHelper.drawRect(pose, 0f, 30f * (1f - heat), 7f, 30f * heat)
|
||||
}
|
||||
|
||||
pose.popPose()
|
||||
|
||||
item.dataTable = null
|
||||
inRender = false
|
||||
}
|
||||
|
||||
private val holoHudBackground get() = RGBAColor(75, 75, 75, 160)
|
||||
private val heatBackground get() = RGBAColor(40, 144, 210, 160)
|
||||
private val initialHeatColor get() = RGBAColor(85, 68, 7, 160)
|
||||
private val finalHeatColor get() = RGBAColor(245, 118, 41, 160)
|
||||
|
||||
private val localPlayer: Player? get() {
|
||||
return Minecraft.getInstance().player
|
||||
}
|
||||
@ -486,6 +543,9 @@ abstract class AbstractWeaponItem<D : WeaponDataTable>(val tables: KClass<D>, ra
|
||||
}
|
||||
|
||||
(stack.item as? AbstractWeaponItem<*>)?.let {
|
||||
if (event.side == LogicalSide.CLIENT && stack.weaponDataTable?.uuid != predictedData?.uuid)
|
||||
return@let
|
||||
|
||||
if (event.side == LogicalSide.CLIENT) {
|
||||
(it as AbstractWeaponItem<WeaponDataTable>).dataTable = predictedData
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import ru.dbotthepony.mc.otm.capability.extractEnergyInnerExact
|
||||
import ru.dbotthepony.mc.otm.core.*
|
||||
import ru.dbotthepony.mc.otm.core.Vector
|
||||
import ru.dbotthepony.mc.otm.entity.PlasmaProjectile
|
||||
@ -16,123 +17,20 @@ import kotlin.math.PI
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
private val random = Random()
|
||||
private const val DEGS = PI / 180.0
|
||||
|
||||
class VelocityCalculation(
|
||||
xRot: Double,
|
||||
yRot: Double,
|
||||
zRot: Double = 0.0,
|
||||
force: Double,
|
||||
deviation: Double = 0.0,
|
||||
owner: Entity? = null,
|
||||
) {
|
||||
constructor(
|
||||
xRot: Float,
|
||||
yRot: Float,
|
||||
zRot: Float = 0f,
|
||||
force: Double,
|
||||
deviation: Double = 0.0,
|
||||
owner: Entity? = null,
|
||||
) : this(xRot.toDouble(), yRot.toDouble(), zRot.toDouble(), force, deviation, owner)
|
||||
|
||||
constructor(
|
||||
xRot: Float,
|
||||
yRot: Float,
|
||||
zRot: Float = 0f,
|
||||
force: Float,
|
||||
deviation: Double = 0.0,
|
||||
owner: Entity? = null,
|
||||
) : this(xRot.toDouble(), yRot.toDouble(), zRot.toDouble(), force.toDouble(), deviation, owner)
|
||||
|
||||
constructor(
|
||||
xRot: Float,
|
||||
yRot: Float,
|
||||
zRot: Float = 0f,
|
||||
force: Float,
|
||||
deviation: Float,
|
||||
owner: Entity? = null,
|
||||
) : this(xRot.toDouble(), yRot.toDouble(), zRot.toDouble(), force.toDouble(), deviation.toDouble(), owner)
|
||||
|
||||
constructor(
|
||||
owner: Entity,
|
||||
force: Float,
|
||||
deviation: Float,
|
||||
) : this(owner.xRot.toDouble() - 4.5 * (1 / force), owner.yRot.toDouble(), 0.0, force.toDouble(), deviation.toDouble(), owner)
|
||||
|
||||
constructor(
|
||||
owner: Entity,
|
||||
force: Double,
|
||||
deviation: Float,
|
||||
) : this(owner.xRot.toDouble() - 4.5 * (1 / force), owner.yRot.toDouble(), 0.0, force, deviation.toDouble(), owner)
|
||||
|
||||
constructor(
|
||||
owner: Entity,
|
||||
force: Double,
|
||||
deviation: Double,
|
||||
) : this(owner.xRot.toDouble() - 4.5 * (1 / force), owner.yRot.toDouble(), 0.0, force, deviation, owner)
|
||||
|
||||
val xVelocity = -sin(yRot * DEGS) * cos(xRot * (PI / 180.0))
|
||||
val yVelocity = -sin((xRot + zRot) * DEGS)
|
||||
val zVelocity = cos(yRot * DEGS) * cos(xRot * DEGS)
|
||||
|
||||
val velocity: Vec3
|
||||
|
||||
init {
|
||||
var velocity = Vec3(
|
||||
xVelocity,
|
||||
yVelocity,
|
||||
zVelocity
|
||||
).normalize()
|
||||
|
||||
velocity += Vec3(
|
||||
random.nextGaussian() * 0.0075 * deviation,
|
||||
random.nextGaussian() * 0.0075 * deviation,
|
||||
random.nextGaussian() * 0.0075 * deviation,
|
||||
)
|
||||
|
||||
velocity *= force
|
||||
|
||||
if (owner != null) {
|
||||
val ownerVel = owner.deltaMovement
|
||||
|
||||
if (owner.isOnGround) {
|
||||
velocity += ownerVel
|
||||
} else {
|
||||
velocity += Vec3(ownerVel.x, 0.0, ownerVel.z)
|
||||
}
|
||||
}
|
||||
|
||||
this.velocity = velocity
|
||||
}
|
||||
|
||||
val yRotation = Mth.atan2(velocity.x, velocity.z).toFloat() * (180f / Math.PI.toFloat())
|
||||
val xRotation = Mth.atan2(velocity.y, velocity.horizontalDistance()).toFloat() * (180f / Math.PI.toFloat())
|
||||
|
||||
fun load(onto: Entity, withRotation: Boolean = true) {
|
||||
if (withRotation) {
|
||||
onto.xRot = xRotation
|
||||
onto.yRot = yRotation
|
||||
}
|
||||
|
||||
onto.deltaMovement = velocity
|
||||
}
|
||||
}
|
||||
|
||||
class PlasmaRifleItem : PlasmaWeaponItem<WeaponDataTable>(WeaponDataTable::class, ImpreciseFraction(200_000)) {
|
||||
class PlasmaRifleItem : PlasmaWeaponItem<PlasmaWeaponDataTable>(PlasmaWeaponDataTable::class, ImpreciseFraction(200_000)) {
|
||||
override val roundsPerMinute: Int = 200
|
||||
override val scopingTime: Int = 7
|
||||
|
||||
override val positionIdle: Vector
|
||||
get() = Vector(0.2,-0.4,-0.6)
|
||||
get() = Vector(0.2, -0.4, -0.6)
|
||||
override val positionIronSights: Vector
|
||||
get() = Vector(0.0,-0.24,-1.0)
|
||||
get() = Vector(0.0, -0.24, -1.0)
|
||||
override val rotIdle: Angle
|
||||
get() = Angle(0.0, -0.02, 0.0)
|
||||
override val rotIronSights: Angle
|
||||
get() = Angle(-0.02, 0.0, 0.0)
|
||||
|
||||
override fun primaryFire(itemStack: ItemStack, player: Player, dt: WeaponDataTable): Boolean {
|
||||
override fun primaryFire(itemStack: ItemStack, player: Player, dt: PlasmaWeaponDataTable): Boolean {
|
||||
if (!player.level.isClientSide) {
|
||||
val arrow = PlasmaProjectile(player.level)
|
||||
arrow.position = player.eyePosition
|
||||
@ -147,18 +45,26 @@ class PlasmaRifleItem : PlasmaWeaponItem<WeaponDataTable>(WeaponDataTable::class
|
||||
dt.doFireAnim(deviation = rotFireAnimDeviation)
|
||||
}
|
||||
|
||||
receiveHeat(itemStack, player, 10.0, dt)
|
||||
|
||||
player.level.playSound(
|
||||
player,
|
||||
player,
|
||||
MSoundEvents.RIFLE_SHOT,
|
||||
SoundSource.NEUTRAL,
|
||||
SoundSource.PLAYERS,
|
||||
1f,
|
||||
1f
|
||||
)
|
||||
|
||||
energyData(itemStack).extractEnergyInner(ENERGY_PER_SHOT, false)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun canPrimaryFire(itemStack: ItemStack, player: Player, dt: PlasmaWeaponDataTable): Boolean {
|
||||
return super.canPrimaryFire(itemStack, player, dt) && energyData(itemStack).extractEnergyInnerExact(ENERGY_PER_SHOT, true).isPositive
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val ENERGY_PER_SHOT = ImpreciseFraction(3_000)
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import net.minecraft.core.Direction
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.sounds.SoundSource
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.TooltipFlag
|
||||
@ -16,8 +18,12 @@ import net.minecraftforge.common.util.LazyOptional
|
||||
import net.minecraftforge.energy.CapabilityEnergy
|
||||
import ru.dbotthepony.mc.otm.capability.*
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.core.bezierCurve
|
||||
import ru.dbotthepony.mc.otm.doubles
|
||||
import ru.dbotthepony.mc.otm.ifPresentK
|
||||
import ru.dbotthepony.mc.otm.ints
|
||||
import ru.dbotthepony.mc.otm.menu.FormattingHelper
|
||||
import ru.dbotthepony.mc.otm.registry.MSoundEvents
|
||||
import ru.dbotthepony.mc.otm.set
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@ -112,7 +118,7 @@ class PlasmaWeaponEnergy(val itemStack: ItemStack, private val innerCapacity: Im
|
||||
return totalReceived
|
||||
}
|
||||
|
||||
val newEnergy = (innerBatteryLevel - howMuch).coerceAtMost(innerCapacity)
|
||||
val newEnergy = (innerBatteryLevel + howMuch).coerceAtMost(innerCapacity)
|
||||
val diff = newEnergy - innerBatteryLevel
|
||||
|
||||
if (!simulate) {
|
||||
@ -145,7 +151,12 @@ class PlasmaWeaponEnergy(val itemStack: ItemStack, private val innerCapacity: Im
|
||||
get() = (battery.energy?.maxEnergyStoredMattery ?: ImpreciseFraction.ZERO) + innerCapacity
|
||||
}
|
||||
|
||||
abstract class PlasmaWeaponItem<D : WeaponDataTable>(tables: KClass<D>, private val energyCapacity: ImpreciseFraction) : AbstractWeaponItem<D>(tables) {
|
||||
open class PlasmaWeaponDataTable(tag: CompoundTag) : WeaponDataTable(tag) {
|
||||
var heatScore by tag.doubles
|
||||
var heatCooldown by tag.ints
|
||||
}
|
||||
|
||||
abstract class PlasmaWeaponItem<D : PlasmaWeaponDataTable>(tables: KClass<D>, private val energyCapacity: ImpreciseFraction) : AbstractWeaponItem<D>(tables) {
|
||||
override fun appendHoverText(
|
||||
itemStack: ItemStack,
|
||||
p_41422_: Level?,
|
||||
@ -167,9 +178,97 @@ abstract class PlasmaWeaponItem<D : WeaponDataTable>(tables: KClass<D>, private
|
||||
|
||||
fun energyData(itemStack: ItemStack) = itemStack.matteryEnergy as PlasmaWeaponEnergy
|
||||
|
||||
open val cooldownSpeed get() = 1.0
|
||||
open val maxHeat = 40.0
|
||||
open val overheatCooldown = 30
|
||||
|
||||
open val cooldownSpline = doubleArrayOf(
|
||||
0.1,
|
||||
0.14,
|
||||
0.18,
|
||||
0.25,
|
||||
0.35,
|
||||
0.45,
|
||||
0.6,
|
||||
0.8,
|
||||
0.97,
|
||||
1.0,
|
||||
1.0,
|
||||
1.0,
|
||||
1.0,
|
||||
1.0,
|
||||
1.0,
|
||||
1.1,
|
||||
1.2,
|
||||
1.3,
|
||||
1.4,
|
||||
)
|
||||
|
||||
override fun canPrimaryFire(itemStack: ItemStack, player: Player, dt: D): Boolean {
|
||||
if (player is ServerPlayer) {
|
||||
// allow little deviation because nothing is perfect
|
||||
return super.canPrimaryFire(itemStack, player, dt) && dt.heatCooldown <= 2
|
||||
}
|
||||
|
||||
return super.canPrimaryFire(itemStack, player, dt) && dt.heatCooldown <= 0
|
||||
}
|
||||
|
||||
open fun canCooldown(itemStack: ItemStack, player: Player, dt: D = dataTable(itemStack)): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
protected open fun coolWeaponDown(itemStack: ItemStack, player: Player, dt: D) {
|
||||
if (!canCooldown(itemStack, player, dt))
|
||||
return
|
||||
|
||||
if (dt.heatScore > 0.0)
|
||||
dt.heatScore = (dt.heatScore - cooldownSpeed * bezierCurve(heatProgress(itemStack, dt = dt), cooldownSpline)).coerceAtLeast(0.0)
|
||||
|
||||
if (dt.heatCooldown > 0)
|
||||
dt.heatCooldown--
|
||||
}
|
||||
|
||||
open fun heatProgress(itemStack: ItemStack, partialTicks: Double = 0.0, dt: D = dataTable(itemStack)): Double {
|
||||
if (dt.heatScore <= 0)
|
||||
return 0.0
|
||||
|
||||
if (dt.heatScore - cooldownSpeed > maxHeat)
|
||||
return 1.0
|
||||
|
||||
val result = dt.heatScore - cooldownSpeed * partialTicks
|
||||
return result / maxHeat
|
||||
}
|
||||
|
||||
open fun overheatProgress(itemStack: ItemStack, partialTicks: Double = 0.0, dt: D = dataTable(itemStack)): Double {
|
||||
if (dt.heatCooldown <= 0)
|
||||
return 0.0
|
||||
|
||||
if (dt.heatCooldown - partialTicks > overheatCooldown)
|
||||
return 1.0
|
||||
|
||||
val result = dt.heatCooldown - partialTicks
|
||||
return result / overheatCooldown
|
||||
}
|
||||
|
||||
open fun receiveHeat(itemStack: ItemStack, player: Player, byTicks: Double, dt: D = dataTable(itemStack)) {
|
||||
dt.heatScore = (dt.heatScore + byTicks).coerceAtMost(maxHeat * 2)
|
||||
|
||||
if (dt.heatScore > maxHeat) {
|
||||
val before = dt.heatCooldown > 0
|
||||
|
||||
dt.heatCooldown = overheatCooldown
|
||||
|
||||
if (!before) {
|
||||
player.level.playSound(player, player, MSoundEvents.PLASMA_WEAPON_OVERHEAT, SoundSource.PLAYERS, 1f, 1f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun think2(itemStack: ItemStack, player: Player, dt: D) {
|
||||
super.think2(itemStack, player, dt)
|
||||
|
||||
coolWeaponDown(itemStack, player, dt)
|
||||
|
||||
itemStack.getCapability(MatteryCapability.ENERGY).ifPresentK {
|
||||
it as PlasmaWeaponEnergy
|
||||
it.think()
|
||||
|
@ -0,0 +1,114 @@
|
||||
package ru.dbotthepony.mc.otm.item.weapon
|
||||
|
||||
import net.minecraft.util.Mth
|
||||
import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import ru.dbotthepony.mc.otm.core.plus
|
||||
import ru.dbotthepony.mc.otm.core.times
|
||||
import java.util.*
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
private val random = Random()
|
||||
private const val DEGS = PI / 180.0
|
||||
|
||||
class VelocityCalculation(
|
||||
xRot: Double,
|
||||
yRot: Double,
|
||||
zRot: Double = 0.0,
|
||||
force: Double,
|
||||
deviation: Double = 0.0,
|
||||
owner: Entity? = null,
|
||||
) {
|
||||
constructor(
|
||||
xRot: Float,
|
||||
yRot: Float,
|
||||
zRot: Float = 0f,
|
||||
force: Double,
|
||||
deviation: Double = 0.0,
|
||||
owner: Entity? = null,
|
||||
) : this(xRot.toDouble(), yRot.toDouble(), zRot.toDouble(), force, deviation, owner)
|
||||
|
||||
constructor(
|
||||
xRot: Float,
|
||||
yRot: Float,
|
||||
zRot: Float = 0f,
|
||||
force: Float,
|
||||
deviation: Double = 0.0,
|
||||
owner: Entity? = null,
|
||||
) : this(xRot.toDouble(), yRot.toDouble(), zRot.toDouble(), force.toDouble(), deviation, owner)
|
||||
|
||||
constructor(
|
||||
xRot: Float,
|
||||
yRot: Float,
|
||||
zRot: Float = 0f,
|
||||
force: Float,
|
||||
deviation: Float,
|
||||
owner: Entity? = null,
|
||||
) : this(xRot.toDouble(), yRot.toDouble(), zRot.toDouble(), force.toDouble(), deviation.toDouble(), owner)
|
||||
|
||||
constructor(
|
||||
owner: Entity,
|
||||
force: Float,
|
||||
deviation: Float,
|
||||
) : this(owner.xRot.toDouble() - 4.5 * (1 / force), owner.yRot.toDouble(), 0.0, force.toDouble(), deviation.toDouble(), owner)
|
||||
|
||||
constructor(
|
||||
owner: Entity,
|
||||
force: Double,
|
||||
deviation: Float,
|
||||
) : this(owner.xRot.toDouble() - 4.5 * (1 / force), owner.yRot.toDouble(), 0.0, force, deviation.toDouble(), owner)
|
||||
|
||||
constructor(
|
||||
owner: Entity,
|
||||
force: Double,
|
||||
deviation: Double,
|
||||
) : this(owner.xRot.toDouble() - 4.5 * (1 / force), owner.yRot.toDouble(), 0.0, force, deviation, owner)
|
||||
|
||||
val xVelocity = -sin(yRot * DEGS) * cos(xRot * (PI / 180.0))
|
||||
val yVelocity = -sin((xRot + zRot) * DEGS)
|
||||
val zVelocity = cos(yRot * DEGS) * cos(xRot * DEGS)
|
||||
|
||||
val velocity: Vec3
|
||||
|
||||
init {
|
||||
var velocity = Vec3(
|
||||
xVelocity,
|
||||
yVelocity,
|
||||
zVelocity
|
||||
).normalize()
|
||||
|
||||
velocity += Vec3(
|
||||
random.nextGaussian() * 0.0075 * deviation,
|
||||
random.nextGaussian() * 0.0075 * deviation,
|
||||
random.nextGaussian() * 0.0075 * deviation,
|
||||
)
|
||||
|
||||
velocity *= force
|
||||
|
||||
if (owner != null) {
|
||||
val ownerVel = owner.deltaMovement
|
||||
|
||||
if (owner.isOnGround) {
|
||||
velocity += ownerVel
|
||||
} else {
|
||||
velocity += Vec3(ownerVel.x, 0.0, ownerVel.z)
|
||||
}
|
||||
}
|
||||
|
||||
this.velocity = velocity
|
||||
}
|
||||
|
||||
val yRotation = Mth.atan2(velocity.x, velocity.z).toFloat() * (180f / Math.PI.toFloat())
|
||||
val xRotation = Mth.atan2(velocity.y, velocity.horizontalDistance()).toFloat() * (180f / Math.PI.toFloat())
|
||||
|
||||
fun load(onto: Entity, withRotation: Boolean = true) {
|
||||
if (withRotation) {
|
||||
onto.xRot = xRotation
|
||||
onto.yRot = yRotation
|
||||
}
|
||||
|
||||
onto.deltaMovement = velocity
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.registry
|
||||
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.sounds.SoundEvent
|
||||
import net.minecraft.sounds.SoundEvents
|
||||
import net.minecraft.world.entity.EntityType
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext
|
||||
import net.minecraftforge.registries.DeferredRegister
|
||||
@ -11,7 +12,10 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
object MSoundEvents {
|
||||
private val registry: DeferredRegister<SoundEvent> = DeferredRegister.create(ForgeRegistries.SOUND_EVENTS, OverdriveThatMatters.MOD_ID)
|
||||
|
||||
val RIFLE_SHOT by registry.register("item.rifle_shot") { SoundEvent(ResourceLocation(OverdriveThatMatters.MOD_ID, "item.rifle_shot")) }
|
||||
private fun make(name: String) = registry.register(name) { SoundEvent(ResourceLocation(OverdriveThatMatters.MOD_ID, name)) }
|
||||
|
||||
val RIFLE_SHOT: SoundEvent by make("item.rifle_shot")
|
||||
val PLASMA_WEAPON_OVERHEAT: SoundEvent by make("item.plasma_weapon_overheat")
|
||||
|
||||
internal fun register() {
|
||||
registry.register(FMLJavaModLoadingContext.get().modEventBus)
|
||||
|
@ -1,5 +1,7 @@
|
||||
{
|
||||
"otm.sound.rifle_shoot": "Plasma rifle fire",
|
||||
"otm.sound.rifle_shoot": "Plasma rifle fires",
|
||||
"otm.sound.plasma_weapon_overheat": "Plasma weapon overheats",
|
||||
|
||||
"itemGroup.otm": "Overdrive That Matters",
|
||||
|
||||
"otm.pill.warning": "WARNING: This will INSTANTLY decommission you upon ingestion!",
|
||||
@ -287,6 +289,8 @@
|
||||
"item.overdrive_that_matters.tritanium_pants": "Tritanium Leggings",
|
||||
"item.overdrive_that_matters.tritanium_boots": "Tritanium Boots",
|
||||
|
||||
"item.overdrive_that_matters.plasma_rifle": "Plasma Rifle",
|
||||
|
||||
"item.overdrive_that_matters.matter_capacitor_parts": "Matter Capacitor Parts",
|
||||
"item.overdrive_that_matters.matter_capacitor_basic": "Basic Matter Capacitor",
|
||||
"item.overdrive_that_matters.matter_capacitor_normal": "Matter Capacitor",
|
||||
|
@ -8,5 +8,11 @@
|
||||
"weight": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"item.plasma_weapon_overheat": {
|
||||
"subtitle": "otm.sound.plasma_weapon_overheat",
|
||||
"sounds": [
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user