mirror of
https://github.com/GTNewHorizons/ThaumicHorizons.git
synced 2026-10-25 20:32:28 +00:00
Fix vortex flicker on chunk reload and stabilizer sync (#116)
Co-authored-by: thehoblit <thehoblit@gmail.com>
This commit is contained in:
1 parent
2768e1b1eb
commit
db3f4e0cba
3 files changed
+76
-58
No files matched your search
+32
-37
@@ -7,13 +7,12 @@ package com.kentington.thaumichorizons.client.renderer.tile;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.Vec3;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
@@ -23,7 +22,6 @@ import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import thaumcraft.api.aspects.Aspect;
|
||||
import thaumcraft.api.aspects.AspectList;
|
||||
import thaumcraft.client.lib.QuadHelper;
|
||||
import thaumcraft.client.lib.UtilsFX;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@@ -34,7 +32,7 @@ public class TileVortexRender extends TileEntitySpecialRenderer {
|
||||
|
||||
public void renderTileEntityAt(final TileEntity tile, final double x, final double y, final double z,
|
||||
final float partialTicks) {
|
||||
if (!(tile instanceof final TileVortex node)) {
|
||||
if (!(tile instanceof final TileVortex node) || !node.clientSynced) {
|
||||
return;
|
||||
}
|
||||
final float size = 10.0f;
|
||||
@@ -72,6 +70,10 @@ public class TileVortexRender extends TileEntitySpecialRenderer {
|
||||
return;
|
||||
}
|
||||
float alpha = (float) ((viewDistance - distance) / viewDistance);
|
||||
// Camera-relative center — avoids float precision loss at large world coords.
|
||||
final double cx = x + 0.5 - RenderManager.renderPosX;
|
||||
final double cy = y + 0.5 - RenderManager.renderPosY;
|
||||
final double cz = z + 0.5 - RenderManager.renderPosZ;
|
||||
GL11.glPushMatrix();
|
||||
GL11.glAlphaFunc(GL11.GL_GREATER, 0.003921569f);
|
||||
GL11.glDepthMask(false);
|
||||
@@ -79,7 +81,6 @@ public class TileVortexRender extends TileEntitySpecialRenderer {
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST);
|
||||
}
|
||||
GL11.glDisable(GL11.GL_CULL_FACE);
|
||||
final long time = nt / 5000000L;
|
||||
final float bscale = 0.25f;
|
||||
GL11.glPushMatrix();
|
||||
final float rad = ((float) Math.PI * 2F);
|
||||
@@ -104,7 +105,8 @@ public class TileVortexRender extends TileEntitySpecialRenderer {
|
||||
scale = MathHelper.sin(viewer.ticksExisted / (14.0f - count)) * bscale + bscale * 2.0f;
|
||||
scale = 0.4f;
|
||||
scale *= size;
|
||||
angle = time % (5000 + 500 * count) / (5000.0f + 500 * count) * rad;
|
||||
final long periodNs = (5000L + 500L * count) * 5_000_000L;
|
||||
angle = (float) ((double) (nt % periodNs) / periodNs) * rad;
|
||||
if (beams < 6 || timeOpen < 50) {
|
||||
UtilsFX.renderFacingStrip(
|
||||
x + 0.5,
|
||||
@@ -153,9 +155,9 @@ public class TileVortexRender extends TileEntitySpecialRenderer {
|
||||
if (!cheat && (beams < 6 || timeOpen < 50)) {
|
||||
UtilsFX.bindTexture(TileVortexRender.vortextex);
|
||||
renderVortex(
|
||||
x + 0.5,
|
||||
y + 0.5,
|
||||
z + 0.5,
|
||||
cx,
|
||||
cy,
|
||||
cz,
|
||||
angle * 20.0f * corescale / (1 + 2 * beams),
|
||||
scale / 5.0f * corescale,
|
||||
0.8f,
|
||||
@@ -193,7 +195,8 @@ public class TileVortexRender extends TileEntitySpecialRenderer {
|
||||
scale = MathHelper.sin(viewer.ticksExisted / (14.0f - count)) * bscale + bscale * 2.0f;
|
||||
scale = 0.4f;
|
||||
scale *= size;
|
||||
angle = time % (5000 + 500 * count) / (5000.0f + 500 * count) * rad;
|
||||
final long periodNs2 = (5000L + 500L * count) * 5_000_000L;
|
||||
angle = (float) ((double) (nt % periodNs2) / periodNs2) * rad;
|
||||
UtilsFX.renderFacingStrip(
|
||||
x + 0.5,
|
||||
y + 0.5,
|
||||
@@ -233,37 +236,29 @@ public class TileVortexRender extends TileEntitySpecialRenderer {
|
||||
final float arYZ = ActiveRenderInfo.rotationYZ;
|
||||
final float arXY = ActiveRenderInfo.rotationXY;
|
||||
final float arXZ = ActiveRenderInfo.rotationXZ;
|
||||
final EntityPlayer player = (EntityPlayer) Minecraft.getMinecraft().renderViewEntity;
|
||||
final double iPX = player.prevPosX + (player.posX - player.prevPosX) * partialTicks;
|
||||
final double iPY = player.prevPosY + (player.posY - player.prevPosY) * partialTicks;
|
||||
final double iPZ = player.prevPosZ + (player.posZ - player.prevPosZ) * partialTicks;
|
||||
GL11.glTranslated(-iPX, -iPY, -iPZ);
|
||||
|
||||
// Rotate screen-plane basis vectors (H = right, V = up) by angle.
|
||||
// This avoids Rodrigues rotation around a qvec that shifts with every head movement,
|
||||
// which caused the vortex to jerk whenever the player moved the camera.
|
||||
final float cos = MathHelper.cos(angle);
|
||||
final float sin = MathHelper.sin(angle);
|
||||
final float hX = cos * arX + sin * arYZ;
|
||||
final float hY = sin * arXZ;
|
||||
final float hZ = cos * arZ + sin * arXY;
|
||||
final float vX = cos * arYZ - sin * arX;
|
||||
final float vY = cos * arXZ;
|
||||
final float vZ = cos * arXY - sin * arZ;
|
||||
|
||||
tessellator.startDrawingQuads();
|
||||
tessellator.setBrightness(220);
|
||||
tessellator.setColorRGBA_I(color, (int) (alpha * 255.0f));
|
||||
final Vec3 v1 = Vec3
|
||||
.createVectorHelper(-arX * scale - arYZ * scale, -arXZ * scale, -arZ * scale - arXY * scale);
|
||||
final Vec3 v2 = Vec3.createVectorHelper(-arX * scale + arYZ * scale, arXZ * scale, -arZ * scale + arXY * scale);
|
||||
final Vec3 v3 = Vec3.createVectorHelper(arX * scale + arYZ * scale, arXZ * scale, arZ * scale + arXY * scale);
|
||||
final Vec3 v4 = Vec3.createVectorHelper(arX * scale - arYZ * scale, -arXZ * scale, arZ * scale - arXY * scale);
|
||||
if (angle != 0.0f) {
|
||||
final Vec3 pvec = Vec3.createVectorHelper(iPX, iPY, iPZ);
|
||||
final Vec3 tvec = Vec3.createVectorHelper(px, py, pz);
|
||||
final Vec3 qvec = pvec.subtract(tvec).normalize();
|
||||
QuadHelper.setAxis(qvec, angle).rotate(v1);
|
||||
QuadHelper.setAxis(qvec, angle).rotate(v2);
|
||||
QuadHelper.setAxis(qvec, angle).rotate(v3);
|
||||
QuadHelper.setAxis(qvec, angle).rotate(v4);
|
||||
}
|
||||
final float f2 = 0.0f;
|
||||
final float f3 = 1.0f;
|
||||
final float f4 = 0.0f;
|
||||
final float f5 = 1.0f;
|
||||
tessellator.setNormal(0.0f, 0.0f, -1.0f);
|
||||
tessellator.addVertexWithUV(px + v1.xCoord, py + v1.yCoord, pz + v1.zCoord, f2, f5);
|
||||
tessellator.addVertexWithUV(px + v2.xCoord, py + v2.yCoord, pz + v2.zCoord, f3, f5);
|
||||
tessellator.addVertexWithUV(px + v3.xCoord, py + v3.yCoord, pz + v3.zCoord, f3, f4);
|
||||
tessellator.addVertexWithUV(px + v4.xCoord, py + v4.yCoord, pz + v4.zCoord, f2, f4);
|
||||
tessellator
|
||||
.addVertexWithUV(px + (-hX - vX) * scale, py + (-hY - vY) * scale, pz + (-hZ - vZ) * scale, 0.0, 1.0);
|
||||
tessellator
|
||||
.addVertexWithUV(px + (-hX + vX) * scale, py + (-hY + vY) * scale, pz + (-hZ + vZ) * scale, 1.0, 1.0);
|
||||
tessellator.addVertexWithUV(px + (hX + vX) * scale, py + (hY + vY) * scale, pz + (hZ + vZ) * scale, 1.0, 0.0);
|
||||
tessellator.addVertexWithUV(px + (hX - vX) * scale, py + (hY - vY) * scale, pz + (hZ - vZ) * scale, 0.0, 0.0);
|
||||
tessellator.draw();
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.util.DamageSource;
|
||||
@@ -63,6 +65,9 @@ public class TileVortex extends TileThaumcraft implements IWandable, IAspectCont
|
||||
public ArrayList<ItemStack> items;
|
||||
Thread ppThread;
|
||||
private boolean soundStarted = false;
|
||||
// true once the first S35 description packet has been received on the client
|
||||
public boolean clientSynced = false;
|
||||
private int lastSyncedBeams = -1;
|
||||
|
||||
public TileVortex() {
|
||||
this.aspects = new AspectList();
|
||||
@@ -78,6 +83,13 @@ public class TileVortex extends TileThaumcraft implements IWandable, IAspectCont
|
||||
public void updateEntity() {
|
||||
super.updateEntity();
|
||||
|
||||
// Send one packet per tick when beams changes, so same-tick re/deHungrify
|
||||
// pairs don't produce two packets with an intermediate wrong value.
|
||||
if (!this.worldObj.isRemote && this.beams != this.lastSyncedBeams) {
|
||||
this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord);
|
||||
this.lastSyncedBeams = this.beams;
|
||||
}
|
||||
|
||||
if (this.worldObj != null && this.worldObj.isRemote && !soundStarted) {
|
||||
ThaumicHorizons.proxy.playVortexSound(this);
|
||||
soundStarted = true;
|
||||
@@ -149,7 +161,7 @@ public class TileVortex extends TileThaumcraft implements IWandable, IAspectCont
|
||||
this.handlePocketPlaneStuff();
|
||||
}
|
||||
if (!this.cheat) {
|
||||
this.count += 6 - this.beams;
|
||||
this.count += Math.max(0, 6 - this.beams);
|
||||
}
|
||||
if (this.count > MAX_COUNT && !this.cheat
|
||||
&& this.worldObj.provider.dimensionId != ThaumicHorizons.dimensionPocketId) {
|
||||
@@ -579,6 +591,19 @@ public class TileVortex extends TileThaumcraft implements IWandable, IAspectCont
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.network.Packet getDescriptionPacket() {
|
||||
NBTTagCompound nbt = new NBTTagCompound();
|
||||
this.writeCustomNBT(nbt);
|
||||
return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 1, nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) {
|
||||
this.readCustomNBT(pkt.func_148857_g());
|
||||
this.clientSynced = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate() {
|
||||
super.invalidate();
|
||||
|
||||
+18
-20
@@ -86,20 +86,20 @@ public class TileVortexStabilizer extends TileThaumcraft implements IWandable {
|
||||
if (this.hasTarget) {
|
||||
this.reHungrifyTarget();
|
||||
this.hasTarget = false;
|
||||
} else if (!this.hasTarget
|
||||
&& this.worldObj.getTileEntity(mop.blockX, mop.blockY, mop.blockZ) instanceof INode) {
|
||||
this.hasTarget = true;
|
||||
this.target = this.worldObj.getTileEntity(mop.blockX, mop.blockY, mop.blockZ);
|
||||
this.prevType = ((INode) this.worldObj
|
||||
.getTileEntity(mop.blockX, mop.blockY, mop.blockZ)).getNodeType().ordinal();
|
||||
this.deHungrifyTarget();
|
||||
} else
|
||||
if (!this.hasTarget && this.worldObj
|
||||
.getTileEntity(mop.blockX, mop.blockY, mop.blockZ) instanceof TileVortex) {
|
||||
this.hasTarget = true;
|
||||
this.target = this.worldObj.getTileEntity(mop.blockX, mop.blockY, mop.blockZ);
|
||||
this.deHungrifyTarget();
|
||||
}
|
||||
}
|
||||
// Separate if (not else if) so a new valid target is acquired in the same tick,
|
||||
// preventing a window where beams is decremented but not yet restored.
|
||||
final TileEntity newTE = this.worldObj.getTileEntity(mop.blockX, mop.blockY, mop.blockZ);
|
||||
if (!this.hasTarget && newTE instanceof INode) {
|
||||
this.hasTarget = true;
|
||||
this.target = newTE;
|
||||
this.prevType = ((INode) newTE).getNodeType().ordinal();
|
||||
this.deHungrifyTarget();
|
||||
} else if (!this.hasTarget && newTE instanceof TileVortex) {
|
||||
this.hasTarget = true;
|
||||
this.target = newTE;
|
||||
this.deHungrifyTarget();
|
||||
}
|
||||
this.xTarget = mop.blockX;
|
||||
this.yTarget = mop.blockY;
|
||||
this.zTarget = mop.blockZ;
|
||||
@@ -167,24 +167,22 @@ public class TileVortexStabilizer extends TileThaumcraft implements IWandable {
|
||||
public void reHungrifyTarget() {
|
||||
if (this.target instanceof INode) {
|
||||
((INode) this.target).setNodeType(NodeType.values()[this.prevType]);
|
||||
} else if (this.target instanceof final TileVortex tileVortex) {
|
||||
--tileVortex.beams;
|
||||
} else if (this.target instanceof TileVortex) {
|
||||
--((TileVortex) this.target).beams;
|
||||
}
|
||||
if (this.target != null) {
|
||||
this.target.markDirty();
|
||||
this.worldObj.markBlockForUpdate(this.target.xCoord, this.target.yCoord, this.target.zCoord);
|
||||
}
|
||||
}
|
||||
|
||||
void deHungrifyTarget() {
|
||||
if (this.target instanceof INode) {
|
||||
((INode) this.target).setNodeType(NodeType.NORMAL);
|
||||
} else if (this.target instanceof final TileVortex tileVortex) {
|
||||
++tileVortex.beams;
|
||||
} else if (this.target instanceof TileVortex) {
|
||||
++((TileVortex) this.target).beams;
|
||||
}
|
||||
if (this.target != null) {
|
||||
this.target.markDirty();
|
||||
this.worldObj.markBlockForUpdate(this.target.xCoord, this.target.yCoord, this.target.zCoord);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user