1
0
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:
chylex 2019-04-11 03:48:33 +02:00
parent cf5f940513
commit bc4134dc3d
4 changed files with 113 additions and 74 deletions

View File

@ -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(

View File

@ -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)
}

View File

@ -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)
}
}
}
}

View File

@ -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
})
}
}
}