mirror of
https://github.com/chylex/Hardcore-Ender-Expansion-2.git
synced 2025-04-11 03:15:44 +02:00
Move portal fading animation from End Portal code to base classes
This commit is contained in:
parent
cf5f940513
commit
bc4134dc3d
src/main/java/chylex/hee
client/render/block
game/block/entity
@ -1,6 +1,9 @@
|
||||
package chylex.hee.client.render.block
|
||||
import chylex.hee.client.render.util.GL
|
||||
import chylex.hee.game.block.BlockAbstractPortal
|
||||
import chylex.hee.game.block.entity.TileEntityBasePortalController
|
||||
import chylex.hee.system.Resource
|
||||
import chylex.hee.system.util.closestTickingTile
|
||||
import chylex.hee.system.util.square
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.renderer.ActiveRenderInfo
|
||||
@ -29,6 +32,7 @@ import org.lwjgl.opengl.GL11.GL_OBJECT_PLANE
|
||||
import org.lwjgl.opengl.GL11.GL_QUADS
|
||||
import org.lwjgl.opengl.GL11.GL_TEXTURE
|
||||
import java.nio.FloatBuffer
|
||||
import kotlin.math.pow
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
abstract class RenderTileAbstractPortal<T : TileEntity> : TileEntitySpecialRenderer<T>(){
|
||||
@ -61,6 +65,16 @@ abstract class RenderTileAbstractPortal<T : TileEntity> : TileEntitySpecialRende
|
||||
private var cameraTarget = Vec3d.ZERO
|
||||
private var globalTranslation = 0F
|
||||
|
||||
private var isAnimating = false
|
||||
private var animationProgress = 0F
|
||||
|
||||
private fun calculateEasing(layer: Int): Float{
|
||||
return if (isAnimating)
|
||||
(1.1F - square(animationProgress * 4.5F - 4.816F) + 22.1F * (1F - ((layer - 1F) / 14F).pow(1.2F))).coerceIn(0F, 1F).pow(1.5F)
|
||||
else
|
||||
animationProgress
|
||||
}
|
||||
|
||||
// Properties
|
||||
|
||||
protected val color = FloatArray(3)
|
||||
@ -70,6 +84,11 @@ abstract class RenderTileAbstractPortal<T : TileEntity> : TileEntitySpecialRende
|
||||
// Rendering
|
||||
|
||||
override fun render(tile: T, x: Double, y: Double, z: Double, partialTicks: Float, destroyStage: Int, alpha: Float){
|
||||
val acceptor = tile.pos.closestTickingTile<TileEntityBasePortalController>(tile.world, BlockAbstractPortal.MAX_DISTANCE_FROM_FRAME)
|
||||
|
||||
animationProgress = acceptor?.clientAnimationProgress?.get(partialTicks) ?: 0F
|
||||
isAnimating = animationProgress > 0F && animationProgress < 1F
|
||||
|
||||
cameraTarget = ActiveRenderInfo.getCameraPosition()
|
||||
globalTranslation = (Minecraft.getSystemTime() % 700000L) / 700000F
|
||||
|
||||
@ -95,7 +114,7 @@ abstract class RenderTileAbstractPortal<T : TileEntity> : TileEntitySpecialRende
|
||||
GL.blendFunc(SRC_ALPHA, ONE_MINUS_SRC_ALPHA)
|
||||
|
||||
generateNextColor(0)
|
||||
transformColor { 0.1F }
|
||||
transformColor { 0.1F } // discards provided value
|
||||
|
||||
renderLayer(
|
||||
x, y, z,
|
||||
@ -117,7 +136,7 @@ abstract class RenderTileAbstractPortal<T : TileEntity> : TileEntitySpecialRende
|
||||
val colorMultiplier = 1F / (layerIndexRev + 1F)
|
||||
|
||||
generateNextColor(layer)
|
||||
transformColor { it * colorMultiplier }
|
||||
transformColor { it * colorMultiplier * calculateEasing(layer) }
|
||||
|
||||
if (layerIndexRev <= layerCount){
|
||||
renderLayer(
|
||||
|
@ -1,39 +1,21 @@
|
||||
package chylex.hee.client.render.block
|
||||
import chylex.hee.game.block.BlockAbstractPortal
|
||||
import chylex.hee.game.block.entity.TileEntityEndPortalAcceptor
|
||||
import chylex.hee.system.util.closestTickingTile
|
||||
import chylex.hee.system.util.square
|
||||
import net.minecraft.tileentity.TileEntityEndPortal
|
||||
import net.minecraftforge.fml.relauncher.Side
|
||||
import net.minecraftforge.fml.relauncher.SideOnly
|
||||
import java.util.Random
|
||||
import kotlin.math.pow
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
object RenderTileEndPortal : RenderTileAbstractPortal<TileEntityEndPortal>(){
|
||||
private const val seed = 31100L
|
||||
private val rand = Random(seed)
|
||||
|
||||
private var isAnimating = false
|
||||
private var animationProgress = 0F
|
||||
|
||||
override fun generateNextColor(layer: Int){
|
||||
val easingMp = if (isAnimating)
|
||||
(1.1F - square(animationProgress * 4.5F - 4.816F) + 22.1F * (1F - ((layer - 1F) / 14F).pow(1.2F))).coerceIn(0F, 1F).pow(1.5F)
|
||||
else
|
||||
animationProgress
|
||||
|
||||
color[0] = ((rand.nextFloat() * 0.5F) + 0.1F) * easingMp
|
||||
color[1] = ((rand.nextFloat() * 0.5F) + 0.4F) * easingMp
|
||||
color[2] = ((rand.nextFloat() * 0.5F) + 0.5F) * easingMp
|
||||
color[0] = (rand.nextFloat() * 0.5F) + 0.1F
|
||||
color[1] = (rand.nextFloat() * 0.5F) + 0.4F
|
||||
color[2] = (rand.nextFloat() * 0.5F) + 0.5F
|
||||
}
|
||||
|
||||
override fun render(tile: TileEntityEndPortal, x: Double, y: Double, z: Double, partialTicks: Float, destroyStage: Int, alpha: Float){
|
||||
val acceptor = tile.pos.closestTickingTile<TileEntityEndPortalAcceptor>(tile.world, BlockAbstractPortal.MAX_DISTANCE_FROM_FRAME)
|
||||
|
||||
animationProgress = acceptor?.foregroundRenderProgress?.get(partialTicks) ?: 0F
|
||||
isAnimating = animationProgress > 0F && animationProgress < 1F
|
||||
|
||||
rand.setSeed(seed)
|
||||
super.render(tile, x, y, z, partialTicks, destroyStage, alpha)
|
||||
}
|
||||
|
@ -0,0 +1,67 @@
|
||||
package chylex.hee.game.block.entity
|
||||
import chylex.hee.game.block.entity.TileEntityBase.Context.NETWORK
|
||||
import chylex.hee.game.block.entity.TileEntityBasePortalController.ForegroundRenderState.Animating
|
||||
import chylex.hee.game.block.entity.TileEntityBasePortalController.ForegroundRenderState.Invisible
|
||||
import chylex.hee.game.block.entity.TileEntityBasePortalController.ForegroundRenderState.Visible
|
||||
import chylex.hee.system.util.math.LerpedFloat
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.util.ITickable
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
abstract class TileEntityBasePortalController : TileEntityBase(), ITickable{
|
||||
private companion object{
|
||||
private const val RENDER_STATE_TAG = "RenderState"
|
||||
private const val RENDER_PROGRESS_TAG = "RenderProgress"
|
||||
}
|
||||
|
||||
sealed class ForegroundRenderState(val progress: Float){
|
||||
class Animating(progress: Float): ForegroundRenderState(progress)
|
||||
object Visible : ForegroundRenderState(1F)
|
||||
object Invisible : ForegroundRenderState(0F)
|
||||
}
|
||||
|
||||
protected abstract val serverRenderState: ForegroundRenderState
|
||||
protected abstract val clientAnimationFadeInSpeed: Float
|
||||
protected abstract val clientAnimationFadeOutSpeed: Float
|
||||
|
||||
private var clientRenderState: ForegroundRenderState = Invisible
|
||||
val clientAnimationProgress = LerpedFloat(0F)
|
||||
|
||||
private fun updateAnimation(){
|
||||
when(clientRenderState){
|
||||
Invisible -> clientAnimationProgress.update(max(0F, clientAnimationProgress - clientAnimationFadeOutSpeed))
|
||||
is Animating -> clientAnimationProgress.update(min(1F, clientAnimationProgress + clientAnimationFadeInSpeed))
|
||||
}
|
||||
}
|
||||
|
||||
override fun update(){
|
||||
if (world.isRemote){
|
||||
updateAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
override fun writeNBT(nbt: NBTTagCompound, context: Context) = with(nbt){
|
||||
if (context == NETWORK){
|
||||
setString(RENDER_STATE_TAG, when(val state = serverRenderState){
|
||||
is Animating -> "Animating".also { setFloat(RENDER_PROGRESS_TAG, state.progress) }
|
||||
Visible -> "Visible"
|
||||
Invisible -> ""
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun readNBT(nbt: NBTTagCompound, context: Context) = with(nbt){
|
||||
if (context == NETWORK){
|
||||
clientRenderState = when(getString(RENDER_STATE_TAG)){
|
||||
"Animating" -> Animating(getFloat(RENDER_PROGRESS_TAG))
|
||||
"Visible" -> Visible
|
||||
else -> Invisible
|
||||
}
|
||||
|
||||
if (clientRenderState != Invisible){
|
||||
clientAnimationProgress.updateImmediately(clientRenderState.progress)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,29 +1,22 @@
|
||||
package chylex.hee.game.block.entity
|
||||
import chylex.hee.game.block.BlockEnergyCluster
|
||||
import chylex.hee.game.block.entity.TileEntityBase.Context.NETWORK
|
||||
import chylex.hee.game.block.entity.TileEntityBase.Context.STORAGE
|
||||
import chylex.hee.game.block.entity.TileEntityBasePortalController.ForegroundRenderState.Animating
|
||||
import chylex.hee.game.block.entity.TileEntityBasePortalController.ForegroundRenderState.Invisible
|
||||
import chylex.hee.game.block.entity.TileEntityBasePortalController.ForegroundRenderState.Visible
|
||||
import chylex.hee.game.block.entity.TileEntityEndPortalAcceptor.ChargeState.CHARGING
|
||||
import chylex.hee.game.block.entity.TileEntityEndPortalAcceptor.ChargeState.FINISHED
|
||||
import chylex.hee.game.block.entity.TileEntityEndPortalAcceptor.ChargeState.IDLE
|
||||
import chylex.hee.game.block.entity.TileEntityEndPortalAcceptor.ChargeState.WAITING
|
||||
import chylex.hee.game.block.entity.TileEntityEndPortalAcceptor.ForegroundRenderState.ANIMATING
|
||||
import chylex.hee.game.block.entity.TileEntityEndPortalAcceptor.ForegroundRenderState.INVISIBLE
|
||||
import chylex.hee.game.block.entity.TileEntityEndPortalAcceptor.ForegroundRenderState.VISIBLE
|
||||
import chylex.hee.game.mechanics.energy.IEnergyQuantity
|
||||
import chylex.hee.game.mechanics.energy.IEnergyQuantity.Units
|
||||
import chylex.hee.system.util.FLAG_SKIP_RENDER
|
||||
import chylex.hee.system.util.FLAG_SYNC_CLIENT
|
||||
import chylex.hee.system.util.breakBlock
|
||||
import chylex.hee.system.util.getEnum
|
||||
import chylex.hee.system.util.getTile
|
||||
import chylex.hee.system.util.math.LerpedFloat
|
||||
import chylex.hee.system.util.setEnum
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.util.ITickable
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
class TileEntityEndPortalAcceptor : TileEntityBase(), ITickable{
|
||||
class TileEntityEndPortalAcceptor : TileEntityBasePortalController(){
|
||||
private companion object{
|
||||
private const val NO_REFRESH = Int.MAX_VALUE
|
||||
|
||||
@ -38,23 +31,18 @@ class TileEntityEndPortalAcceptor : TileEntityBase(), ITickable{
|
||||
|
||||
// Client animation
|
||||
|
||||
private enum class ForegroundRenderState{
|
||||
INVISIBLE,
|
||||
ANIMATING,
|
||||
VISIBLE
|
||||
}
|
||||
|
||||
private var foregroundRenderState = INVISIBLE
|
||||
val foregroundRenderProgress = LerpedFloat(0F)
|
||||
|
||||
private fun updateAnimation(){
|
||||
if (foregroundRenderState == INVISIBLE){
|
||||
foregroundRenderProgress.update(max(0F, foregroundRenderProgress - ANIMATION_PROGRESS_PER_UPDATE * 8F))
|
||||
override val serverRenderState
|
||||
get() = when(chargeState){
|
||||
IDLE, WAITING -> Invisible
|
||||
CHARGING -> Animating(chargedEnergy.units.value.toFloat() / ENERGY_REQUIRED.units.value)
|
||||
FINISHED -> Visible
|
||||
}
|
||||
else if (foregroundRenderState == ANIMATING){
|
||||
foregroundRenderProgress.update(min(1F, foregroundRenderProgress + ANIMATION_PROGRESS_PER_UPDATE))
|
||||
}
|
||||
}
|
||||
|
||||
override val clientAnimationFadeInSpeed
|
||||
get() = ANIMATION_PROGRESS_PER_UPDATE
|
||||
|
||||
override val clientAnimationFadeOutSpeed
|
||||
get() = ANIMATION_PROGRESS_PER_UPDATE * 8F
|
||||
|
||||
// Charge handling
|
||||
|
||||
@ -149,32 +137,24 @@ class TileEntityEndPortalAcceptor : TileEntityBase(), ITickable{
|
||||
}
|
||||
|
||||
override fun update(){
|
||||
if (world.isRemote){
|
||||
updateAnimation()
|
||||
}
|
||||
else if (ticksToRefresh != NO_REFRESH && --ticksToRefresh <= 0){
|
||||
super.update()
|
||||
|
||||
if (!world.isRemote && ticksToRefresh != NO_REFRESH && --ticksToRefresh <= 0){
|
||||
refreshClusterState()
|
||||
}
|
||||
}
|
||||
|
||||
override fun writeNBT(nbt: NBTTagCompound, context: Context) = with(nbt){
|
||||
super.writeNBT(nbt, context)
|
||||
|
||||
if (context == STORAGE){
|
||||
setInteger("EnergyCharge", chargedEnergy.units.value)
|
||||
}
|
||||
else if (context == NETWORK){
|
||||
setEnum("RenderState", when(chargeState){
|
||||
IDLE, WAITING -> INVISIBLE
|
||||
CHARGING -> ANIMATING
|
||||
FINISHED -> VISIBLE
|
||||
})
|
||||
|
||||
if (chargeState == CHARGING){
|
||||
setFloat("RenderProgress", chargedEnergy.units.value.toFloat() / ENERGY_REQUIRED.units.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun readNBT(nbt: NBTTagCompound, context: Context) = with(nbt){
|
||||
super.readNBT(nbt, context)
|
||||
|
||||
if (context == STORAGE){
|
||||
chargedEnergy = Units(getInteger("EnergyCharge"))
|
||||
|
||||
@ -185,14 +165,5 @@ class TileEntityEndPortalAcceptor : TileEntityBase(), ITickable{
|
||||
chargeState = CHARGING
|
||||
}
|
||||
}
|
||||
else if (context == NETWORK){
|
||||
foregroundRenderState = getEnum<ForegroundRenderState>("RenderState") ?: INVISIBLE
|
||||
|
||||
foregroundRenderProgress.updateImmediately(when(foregroundRenderState){
|
||||
INVISIBLE -> 0F
|
||||
ANIMATING -> getFloat("RenderProgress")
|
||||
VISIBLE -> 1F
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user