Rift appearance and closing improvements

* Made rifts emit light
 * Improved rift edges
 * Made rifts jitter
 * Rift removal tool slowly closes rift
This commit is contained in:
Runemoro 2018-04-02 17:43:23 -04:00
parent e13943d281
commit f51265298d
8 changed files with 70 additions and 83 deletions

View file

@ -42,7 +42,7 @@ public class ParticleRiftEffect extends ParticleSimpleAnimated { // TODO: colors
public static class Rift extends ParticleRiftEffect {
public Rift(World world, double x, double y, double z, double motionX, double motionY, double motionZ) {
super(world, x, y, z, motionX, motionY, motionZ, 0.0f, 0.7f, 0.55f, 38, 16);
super(world, x, y, z, motionX, motionY, motionZ, 0.0f, 0.7f, 0.55f, 3800, 1600);
}
}

View file

@ -22,91 +22,50 @@ public final class RiftCrackRenderer {
// Changes how far the triangles move
// TODO: Actually seems to control the glow around the rift
float motionMagnitude = 0.2F;
float motionMagnitude = 0.6F;
// Changes how quickly the triangles move
float motionSpeed = 2000.0F;
float motionSpeed = 0.014f;
// Number of individual jitter waveforms to generate
// changes how "together" the overall motions are
int jCount = 5;
int jCount = 10;
// Calculate jitter like for monoliths
// Used to be: 0xF1234568 * hashCode(), this is probably to avoid syncing all rifts
long riftRandom = (long) (0xF1234568L * (xWorld + yWorld * (2L << 21) + zWorld * (2L << 42)));
float time = ((Minecraft.getSystemTime() + riftRandom) % 2000000) / motionSpeed;
long riftRandom = 0;//(long) (0xF1234568L * (xWorld + yWorld * (2L << 21) + zWorld * (2L << 42)));
float time = ((Minecraft.getSystemTime() + riftRandom) % 2000000) * motionSpeed;
double[] jitters = new double[jCount];
// TODO: Fix jitters. This loop seems to be overwriting all but the last cos with sin
double aggroScaling = size * size * size / 700f;
// We use random constants here on purpose just to get different wave forms
double xJitter = aggroScaling * Math.sin(1.1f * time*size) * Math.sin(0.8f * time);
double yJitter = aggroScaling * Math.sin(1.2f * time*size) * Math.sin(0.9f * time);
double zJitter = aggroScaling * Math.sin(1.3f * time*size) * Math.sin(0.7f * time);
// generate a series of waveforms
for (int i = 0; i < jCount - 1; i += 1) {
// TODO: Division by magnitude... Not multiplication???
jitters[i] = Math.sin((1F + i / 10F) * time) * Math.cos(1F - i / 10F * time) / motionMagnitude;
jitters[i + 1] = Math.cos((1F + i / 10F) * time) * Math.sin(1F - i / 10F * time) / motionMagnitude;
for (int i = 0; i < jCount; i += 1) {
jitters[i] = Math.sin((1F + i / 10F) * time) * Math.cos(1F - i / 10F * time) * motionMagnitude;
}
// determines which jitter waveform we select. Modulo so the same point
// gets the same jitter waveform over multiple frames
int jIndex = 0;
// set the color for the render
GlStateManager.color(.1F, .1F, .1F, 1F);
// set the blending mode
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL_ONE_MINUS_SRC_COLOR, GL_ONE);
GlStateManager.glBegin(GL11.GL_TRIANGLES);
for (Point p : poly.points) {
jIndex = Math.abs((p.x + p.y) * (p.x + p.y + 1) / 2 + p.y);
// jIndex++;
// Calculate the rotation for the fractal, apply offset, and apply jitter
double x = (p.x + jitters[(jIndex + 1) % jCount] - offsetX) * Math.cos(Math.toRadians(riftRotation)) - jitters[(jIndex + 2) % jCount] * Math.sin(Math.toRadians(riftRotation));
double y = p.y + jitters[jIndex % jCount] - offsetY;
double z = (p.x + jitters[(jIndex + 2) % jCount] - offsetX) * Math.sin(Math.toRadians(riftRotation)) + jitters[(jIndex + 2) % jCount] * Math.cos(Math.toRadians(riftRotation));
// Apply scaling
x *= scale;
y *= scale;
z *= scale;
// Apply transform to center the offset origin into the middle of a block
x += .5;
y += .5;
z += .5;
// Draw the vertex and apply the world (screenspace) relative coordinates
GL11.glVertex3d(xWorld + x, yWorld + y, zWorld + z);
}
GlStateManager.glEnd();
GlStateManager.color(.3F, .3F, .3F, .2F);
glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);
GlStateManager.color(0.08f, 0.08f, 0.08f, .3F);
glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); // Invert the backgrounds
// Draw the next set of triangles to form a background and change their color slightly over time
GlStateManager.glBegin(GL11.GL_TRIANGLES);
for (Point p : poly.points) {
jIndex++;
double x = (p.x - offsetX) * Math.cos(Math.toRadians(riftRotation)) - 0 * Math.sin(Math.toRadians(riftRotation));
double y = p.y - offsetY;
double z = (p.x - offsetX) * Math.sin(Math.toRadians(riftRotation)) + 0 * Math.cos(Math.toRadians(riftRotation));
int jIndex = Math.abs((p.x + p.y) * (p.x + p.y + 1) / 2 + p.y);
double x = (p.x + jitters[(jIndex + 1) % jCount] - offsetX) * Math.cos(Math.toRadians(riftRotation)) - jitters[(jIndex + 2) % jCount] * Math.sin(Math.toRadians(riftRotation));
double y = p.y + jitters[jIndex % jCount] - offsetY;
double z = (p.x + jitters[(jIndex + 2) % jCount] - offsetZ) * Math.sin(Math.toRadians(riftRotation)) + jitters[(jIndex + 2) % jCount] * Math.cos(Math.toRadians(riftRotation));
x *= scale;
y *= scale;
z *= scale;
x += .5;
y += .5;
z += .5;
// TODO: What does this do?
//if (jIndex % 3 == 0) {
// GL11.glColor4d(1 - jitters[(jIndex + 5) % jCount] / 11,
// 1 - jitters[(jIndex + 4) % jCount] / 8,
// 1 - jitters[(jIndex + 3) % jCount] / 8, 1);
//}
GL11.glVertex3d(xWorld + x, yWorld + y, zWorld + z);
GL11.glVertex3d(xWorld + x + xJitter, yWorld + y + yJitter, zWorld + z + zJitter);
}
// Stop drawing triangles

View file

@ -30,6 +30,7 @@ public class TileEntityFloatingRiftRenderer extends TileEntitySpecialRenderer<Ti
private void renderCrack(TileEntityFloatingRift rift, double x, double y, double z, float partialTicks, int destroyStage, float alpha) {
GL11.glPushMatrix();
// TODO: Make the sky get dark when a player approaches a rift?
// Make the rift render on both sides, disable texture mapping and lighting
GlStateManager.disableLighting();
@ -40,7 +41,7 @@ public class TileEntityFloatingRiftRenderer extends TileEntitySpecialRenderer<Ti
//GlStateManager.colorLogicOp(GlStateManager.LogicOp.INVERT);
//GlStateManager.enableColorLogic();
RiftCrackRenderer.drawCrack(rift.riftRotation, rift.getCurve(), rift.growth / 15, x, y, z);
RiftCrackRenderer.drawCrack(rift.riftRotation, rift.getCurve(), rift.growth / 90, x + 0.5, y + 1.5, z + 0.5);
GlStateManager.disableBlend();
GlStateManager.enableTexture2D();

View file

@ -43,6 +43,11 @@ public final class ModConfig {
@Name("riftBoundingBoxInCreative")
@LangKey("dimdoors.general.riftBoundingBoxInCreative")
public boolean riftBoundingBoxInCreative;
@Name("riftCloseSpeed")
@LangKey("dimdoors.general.riftCloseSpeed")
@RangeDouble(min = 0)
public float riftCloseSpeed = 1f;
}
public static class Pockets {

View file

@ -35,6 +35,7 @@ public class BlockFloatingRift extends BlockSpecialAir implements ITileEntityPro
setUnlocalizedName(ID);
setTickRandomly(true);
setResistance(6000000.0F); // Same as bedrock
setLightLevel(0.5f);
}
@Override
@ -96,11 +97,16 @@ public class BlockFloatingRift extends BlockSpecialAir implements ITileEntityPro
rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D));
}
if (rift.shouldClose) { // Renders an opposite color effect if it is being closed by the rift remover
if (rift.closing) { // Renders an opposite color effect if it is being closed by the rift remover
FMLClientHandler.instance().getClient().effectRenderer.addEffect(new ParticleRiftEffect.ClosingRiftEffect(
world,
pos.getX() + .5, pos.getY() + .5, pos.getZ() + .5,
rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D));
}
FMLClientHandler.instance().getClient().effectRenderer.addEffect(new ParticleRiftEffect.Rift(
world,
pos.getX() + .5, pos.getY() + 1.5, pos.getZ() + .5,
rand.nextGaussian() * 0.1D, rand.nextGaussian() * 0.1D, rand.nextGaussian() * 0.1D));
}
}

View file

@ -11,7 +11,6 @@ import org.dimdev.dimdoors.shared.sound.ModSounds;
import org.dimdev.dimdoors.shared.tileentities.TileEntityFloatingRift;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.RayTraceResult;
@ -49,13 +48,17 @@ public class ItemRiftRemover extends Item {
RayTraceResult hit = rayTrace(world, player, true);
if (RayTraceHelper.isFloatingRift(hit, world)) {
TileEntityFloatingRift rift = (TileEntityFloatingRift) world.getTileEntity(hit.getBlockPos());
world.setBlockState(rift.getPos(), Blocks.AIR.getDefaultState());
if (!rift.closing) {
rift.setClosing(true);
world.playSound(null, player.getPosition(), ModSounds.RIFT_CLOSE, SoundCategory.BLOCKS, 0.6f, 1);
// TODO: render rift removing animation
stack.damageItem(10, player);
player.sendStatusMessage(new TextComponentTranslation("item.rift_remover.removed"), true);
player.sendStatusMessage(new TextComponentTranslation("item.rift_remover.closing"), true);
return new ActionResult<>(EnumActionResult.SUCCESS, stack);
} else {
player.sendStatusMessage(new TextComponentTranslation("item.rift_remover.already_closing"), true);
}
}
return new ActionResult<>(EnumActionResult.FAIL, stack);
}

View file

@ -17,6 +17,7 @@ import org.dimdev.annotatednbt.Saved;
import org.dimdev.ddutils.lsystem.LSystem;
import org.dimdev.ddutils.nbt.NBTUtils;
import org.dimdev.dimdoors.DimDoors;
import org.dimdev.dimdoors.shared.ModConfig;
import org.dimdev.dimdoors.shared.blocks.BlockFloatingRift;
import org.dimdev.dimdoors.shared.blocks.ModBlocks;
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
@ -37,7 +38,7 @@ import java.util.Random;
// TODO: Some of these properties will need to persist when converting to door and then back to rift!
//Need to be saved:
@Saved /*package-private*/ int updateTimer;
@Saved public boolean shouldClose = false; // TODO
@Saved public boolean closing = false; // TODO: maybe we could have a closingSpeed instead?
@Saved public int spawnedEndermenID = 0;
@Saved public float growth = 0;
@Saved protected float teleportTargetYaw;
@ -64,8 +65,12 @@ import java.util.Random;
// Check if this rift should render white closing particles and
// spread the closing effect to other rifts nearby.
if (shouldClose) {
closeRift();
if (closing) {
if (growth > 0) {
growth -= ModConfig.general.riftCloseSpeed;
} else {
world.setBlockToAir(pos);
}
return;
}
@ -75,8 +80,13 @@ import java.util.Random;
} else if (updateTimer == UPDATE_PERIOD / 2) {
updateNearestRift();
}
growth += 1F / (growth + 1);
updateTimer++;
// Logarithmic growth
for (int n = 0; n < 10; n++) {
// TODO: growthSpeed and growthSize config options
growth += 1F / (growth + 1);
}
}
private void spawnEndermen() {
@ -113,15 +123,17 @@ import java.util.Random;
}
}
private void closeRift() {
world.setBlockToAir(pos);
growth--; //@todo?
}
public boolean updateNearestRift() {
return false;
}
public void setClosing(boolean closing) {
this.closing = closing;
IBlockState state = world.getBlockState(pos);
world.notifyBlockUpdate(pos, state, state, 0);
markDirty();
}
@Override
public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newSate) {
// newState is not accurate if we change the state during onBlockBreak

View file

@ -71,7 +71,8 @@ item.stabilized_rift_signature.stored=Location stored
item.stabilized_rift_signature.created=Rift created
item.rift_configuration_tool.name=Rift Configuration Tool
item.rift_remover.name=Rift Remover
item.rift_remover.removed=Rift Removed
item.rift_remover.closing=The rift will close soon
item.rift_remover.already_closing=This rift is already closing
item.rift_blade.name=Rift Blade
item.world_thread.name=World Thread