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:
parent
e13943d281
commit
f51265298d
8 changed files with 70 additions and 83 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
world.playSound(null, player.getPosition(), ModSounds.RIFT_CLOSE, SoundCategory.BLOCKS, 0.6f, 1);
|
||||
// TODO: render rift removing animation
|
||||
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);
|
||||
return new ActionResult<>(EnumActionResult.SUCCESS, stack);
|
||||
stack.damageItem(10, player);
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue