Мир: остров, дороги-дамбы, биомы; LOD ступенями; консоль сервера; баны; постобработка
This commit is contained in:
@@ -1337,4 +1337,41 @@ import org.lwjgl.opengl.ContextCapabilities;
|
||||
--- AFTER
|
||||
this.mc.profiler.endStartSection("terrain_setup");
|
||||
net.rustnotmc.client.RsxLod.render(this.mc);
|
||||
renderglobal.setupTerrain(entity, (double) f, frustum, this.frameCount++, this.mc.player.isSpectator());
|
||||
renderglobal.setupTerrain(entity, (double) f, frustum, this.frameCount++, this.mc.player.isSpectator());
|
||||
|
||||
# The post effects read the projection the world was drawn with.
|
||||
=== FILE net/minecraft/client/renderer/EntityRenderer.java
|
||||
--- BEFORE
|
||||
if (this.mc.gameSettings.viewBobbing) {
|
||||
this.applyBobbing(f);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void disableLightmap() {
|
||||
--- AFTER
|
||||
if (this.mc.gameSettings.viewBobbing) {
|
||||
this.applyBobbing(f);
|
||||
}
|
||||
net.rustnotmc.client.RsxPostPipeline.captureProjection();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void disableLightmap() {
|
||||
|
||||
# The post effects run on what the world drew, before the hand and the
|
||||
# interface come over it.
|
||||
=== FILE net/minecraft/client/renderer/EntityRenderer.java
|
||||
--- BEFORE
|
||||
this.mc.profiler.endStartSection("hand");
|
||||
if (this.renderHand) {
|
||||
--- AFTER
|
||||
this.mc.profiler.endStartSection("rsxpost");
|
||||
if (i == 2 && !this.mc.gameSettings.anaglyph) {
|
||||
net.rustnotmc.client.RsxPostPipeline.apply(this.mc);
|
||||
}
|
||||
|
||||
this.mc.profiler.endStartSection("hand");
|
||||
if (this.renderHand) {
|
||||
@@ -127,6 +127,9 @@ public final class RsxBootstrap {
|
||||
}
|
||||
// our own commands come first: they are not mod commands, and a mod
|
||||
// should not be able to take a name that the game itself uses
|
||||
if (net.rustnotmc.client.RsxPostPipeline.command(line)) {
|
||||
return true;
|
||||
}
|
||||
if (RsxHitboxDebug.command(line)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -139,9 +139,14 @@ public final class RsxLod {
|
||||
+ (mc.getRenderViewEntity().posZ - mc.getRenderViewEntity().lastTickPosZ)
|
||||
* (double) mc.getRenderPartialTicks();
|
||||
|
||||
// the colour the far view fades into: the colour of the sky
|
||||
float fogStart = (float) (mc.gameSettings.renderDistanceChunks * 16.0D * 0.75D);
|
||||
float fogEnd = (float) (mc.gameSettings.renderDistanceChunks * 16.0D);
|
||||
// the colour the far view fades into: the colour of the sky. The far
|
||||
// view reaches further than the chunks do, so its fog sits at the
|
||||
// edge of the far view and not at the edge of the chunks; the two
|
||||
// kinds of ground fade into the same sky where they meet.
|
||||
float chunkEdge = (float) (mc.gameSettings.renderDistanceChunks * 16.0D);
|
||||
float farEdge = 1600.0F;
|
||||
float fogStart = Math.max(chunkEdge * 0.8F, 128.0F);
|
||||
float fogEnd = chunkEdge + farEdge;
|
||||
float fogRed = 0.47F;
|
||||
float fogGreen = 0.65F;
|
||||
float fogBlue = 1.0F;
|
||||
@@ -193,6 +198,12 @@ public final class RsxLod {
|
||||
int vertices = cells * 6;
|
||||
ByteBuffer data = ByteBuffer.allocateDirect(vertices * 16).order(ByteOrder.nativeOrder());
|
||||
|
||||
// the sun of the far view: the same direction from the north-west
|
||||
// and above, so that the far ground is not flat colour
|
||||
float sunX = -0.4629F;
|
||||
float sunY = 0.8165F;
|
||||
float sunZ = -0.3492F;
|
||||
|
||||
for (int z = 0; z < size - 1; z++) {
|
||||
for (int x = 0; x < size - 1; x++) {
|
||||
int at = z * size + x;
|
||||
@@ -211,14 +222,27 @@ public final class RsxLod {
|
||||
float g = (region.colors[c + 1] & 0xFF) / 255.0F;
|
||||
float b = (region.colors[c + 2] & 0xFF) / 255.0F;
|
||||
|
||||
// the slope of the cell: the client works out its own light
|
||||
// here, because the far view has no blocks for the game to
|
||||
// light, only the shape of the ground it has already got
|
||||
float dx = (h10 + h11 - h00 - h01) / (2.0F * step);
|
||||
float dz = (h01 + h11 - h00 - h10) / (2.0F * step);
|
||||
float length = (float) Math.sqrt(dx * dx + dz * dz + 1.0F);
|
||||
float facing = (-dx * sunX + sunY - dz * sunZ) / length;
|
||||
float light = Math.max(0.42F, (facing - 0.35F) * 0.95F + 0.72F);
|
||||
|
||||
float lr = Math.min(1.0F, r * light);
|
||||
float lg = Math.min(1.0F, g * light);
|
||||
float lb = Math.min(1.0F, b * light);
|
||||
|
||||
// two triangles: the first one along the diagonal, the second
|
||||
// one the other way, so that the ground is never torn
|
||||
vertex(data, x0, h00, z0, r, g, b);
|
||||
vertex(data, x1, h10, z0, r, g, b);
|
||||
vertex(data, x1, h11, z1, r, g, b);
|
||||
vertex(data, x0, h00, z0, r, g, b);
|
||||
vertex(data, x1, h11, z1, r, g, b);
|
||||
vertex(data, x0, h01, z1, r, g, b);
|
||||
vertex(data, x0, h00, z0, lr, lg, lb);
|
||||
vertex(data, x1, h10, z0, lr, lg, lb);
|
||||
vertex(data, x1, h11, z1, lr, lg, lb);
|
||||
vertex(data, x0, h00, z0, lr, lg, lb);
|
||||
vertex(data, x1, h11, z1, lr, lg, lb);
|
||||
vertex(data, x0, h01, z1, lr, lg, lb);
|
||||
}
|
||||
}
|
||||
data.flip();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,9 +24,13 @@ public final class RsxBlockMap {
|
||||
*
|
||||
* A chunk has sixteen thousand blocks in it and a client may be given a
|
||||
* hundred chunks at a time, so this is looked up sixty times a second per
|
||||
* chunk instead of a million.
|
||||
* chunk instead of a million. The room is (the highest legal id + 1) and
|
||||
* a slot left null draws as air, so a block the client joined late on no
|
||||
* longer sneaks past the end of the array as it did when the roads came
|
||||
* off the wire as nothing at all.
|
||||
*/
|
||||
private static final IBlockState[] STATES = new IBlockState[8];
|
||||
private static final IBlockState[] STATES =
|
||||
new IBlockState[net.rustnotmc.protocol.Blocks.MAX + 1];
|
||||
|
||||
static {
|
||||
STATES[net.rustnotmc.protocol.Blocks.AIR] = Blocks.AIR.getDefaultState();
|
||||
@@ -37,6 +41,13 @@ public final class RsxBlockMap {
|
||||
STATES[net.rustnotmc.protocol.Blocks.WATER] = Blocks.WATER.getDefaultState();
|
||||
STATES[net.rustnotmc.protocol.Blocks.WOOD] = Blocks.LOG.getDefaultState();
|
||||
STATES[net.rustnotmc.protocol.Blocks.LEAVES] = Blocks.LEAVES.getDefaultState();
|
||||
// the game has no asphalt of its own; grey is the road's color
|
||||
STATES[net.rustnotmc.protocol.Blocks.ASPHALT] =
|
||||
Blocks.CONCRETE.getDefaultState().withProperty(
|
||||
net.minecraft.block.BlockColored.COLOR,
|
||||
net.minecraft.item.EnumDyeColor.GRAY);
|
||||
STATES[net.rustnotmc.protocol.Blocks.SNOW] =
|
||||
Blocks.SNOW.getDefaultState();
|
||||
}
|
||||
|
||||
private RsxBlockMap() {
|
||||
|
||||
@@ -96,6 +96,20 @@ public final class RsxWorldBridge {
|
||||
throws java.io.IOException {
|
||||
boolean skyLight = world.provider.hasSkyLight();
|
||||
|
||||
int[] heights = new int[256];
|
||||
for (int column = 0; column < 256; column++) {
|
||||
int x = column & 15;
|
||||
int z = column >> 4;
|
||||
int top = 0;
|
||||
for (int y = 255; y >= 0; y--) {
|
||||
if (blocks[ChunkFormat.index(x, y, z)] != net.rustnotmc.protocol.Blocks.AIR) {
|
||||
top = y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
heights[column] = top;
|
||||
}
|
||||
|
||||
PacketBuffer sections = new PacketBuffer(Unpooled.buffer(128 * 1024));
|
||||
int mask = 0;
|
||||
|
||||
@@ -124,9 +138,9 @@ public final class RsxWorldBridge {
|
||||
}
|
||||
mask |= 1 << section;
|
||||
container.write(sections);
|
||||
sections.writeBytes(LIGHT);
|
||||
sections.writeBytes(UNLIT);
|
||||
if (skyLight) {
|
||||
sections.writeBytes(LIGHT);
|
||||
sections.writeBytes(skyLight(section * 16, heights));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,14 +164,47 @@ public final class RsxWorldBridge {
|
||||
return packet;
|
||||
}
|
||||
|
||||
/** A section's light, all of it on. */
|
||||
private static final byte[] LIGHT = new byte[2048];
|
||||
/** The light of a block that is its own source. */
|
||||
private static final byte[] UNLIT = new byte[2048];
|
||||
|
||||
/**
|
||||
* The light of one section, worked out from the chunk's heightmap.
|
||||
*
|
||||
* The server does not compute light yet, and it also has no business
|
||||
* doing so: a client that owns the blocks is the one that knows where the
|
||||
* sky is. Columns above the surface read as full sky, and everything below
|
||||
* the top of its column sinks two light steps for every block of ground
|
||||
* it is buried in. Buildings get their shade, tunnels their darkness, and
|
||||
* the gradient runs in one block increments so the vertex interpolation
|
||||
* the game already does turns it into a smooth ramp instead of a ledge.
|
||||
*/
|
||||
private static byte[] skyLight(int baseY, int[] heights) {
|
||||
byte[] data = new byte[2048];
|
||||
for (int column = 0; column < 256; column++) {
|
||||
int x = column & 15;
|
||||
int z = column >> 4;
|
||||
int top = heights[column];
|
||||
for (int y = 0; y < 16; y++) {
|
||||
int global = baseY + y;
|
||||
int light = global > top ? 15 : 15 - 2 * (top - global);
|
||||
if (light <= 0) {
|
||||
continue;
|
||||
}
|
||||
int coordinate = (y << 8) | (z << 4) | x;
|
||||
if ((coordinate & 1) == 0) {
|
||||
data[coordinate >> 1] |= (byte) light;
|
||||
} else {
|
||||
data[coordinate >> 1] |= (byte) (light << 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/** The biomes of a chunk: one byte per column. */
|
||||
private static final byte[] BIOMES = new byte[256];
|
||||
|
||||
static {
|
||||
java.util.Arrays.fill(LIGHT, (byte) 0xFF);
|
||||
java.util.Arrays.fill(BIOMES, (byte) 1); // plains
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user