Apply 0.0.13a update

This commit is contained in:
zontreck 2023-12-04 14:11:30 -07:00
parent ebd62f2394
commit a2b809a39f
44 changed files with 2077 additions and 587 deletions

View file

@ -19,6 +19,7 @@ public class Entity {
public float xRot;
public AABB bb;
public boolean onGround = false;
public boolean horizontalCollision = false;
public boolean removed = false;
protected float heightOffset = 0.0F;
protected float bbWidth = 0.6F;
@ -30,9 +31,9 @@ public class Entity {
}
protected void resetPos() {
float x = (float)Math.random() * (float)this.level.width;
float x = (float)Math.random() * (float)(this.level.width - 2) + 1.0F;
float y = (float)(this.level.depth + 10);
float z = (float)Math.random() * (float)this.level.height;
float z = (float)Math.random() * (float)(this.level.height - 2) + 1.0F;
this.setPos(x, y, z);
}
@ -73,6 +74,12 @@ public class Entity {
this.zo = this.z;
}
public boolean isFree(float xa, float ya, float za) {
AABB box = this.bb.cloneMove(xa, ya, za);
ArrayList aABBs = this.level.getCubes(box);
return aABBs.size() > 0 ? false : !this.level.containsAnyLiquid(box);
}
public void move(float xa, float ya, float za) {
float xaOrg = xa;
float yaOrg = ya;
@ -97,6 +104,7 @@ public class Entity {
}
this.bb.move(0.0F, 0.0F, za);
this.horizontalCollision = xaOrg != xa || zaOrg != za;
this.onGround = yaOrg != ya && yaOrg < 0.0F;
if(xaOrg != xa) {
this.xd = 0.0F;
@ -115,6 +123,14 @@ public class Entity {
this.z = (this.bb.z0 + this.bb.z1) / 2.0F;
}
public boolean isInWater() {
return this.level.containsLiquid(this.bb.grow(0.0F, -0.4F, 0.0F), 1);
}
public boolean isInLava() {
return this.level.containsLiquid(this.bb, 2);
}
public void moveRelative(float xa, float za, float speed) {
float dist = xa * xa + za * za;
if(dist >= 0.01F) {

View file

@ -14,4 +14,52 @@ public class HitResult {
this.z = z;
this.f = f;
}
public boolean isCloserThan(Player player, HitResult o, int editMode) {
float dist = this.distanceTo(player, 0);
float dist2 = o.distanceTo(player, 0);
if(dist < dist2) {
return true;
} else {
dist = this.distanceTo(player, editMode);
dist2 = o.distanceTo(player, editMode);
return dist < dist2;
}
}
private float distanceTo(Player player, int editMode) {
int xx = this.x;
int yy = this.y;
int zz = this.z;
if(editMode == 1) {
if(this.f == 0) {
--yy;
}
if(this.f == 1) {
++yy;
}
if(this.f == 2) {
--zz;
}
if(this.f == 3) {
++zz;
}
if(this.f == 4) {
--xx;
}
if(this.f == 5) {
++xx;
}
}
float xd = (float)xx - player.x;
float yd = (float)yy - player.y;
float zd = (float)zz - player.z;
return xd * xd + yd * yd + zd * zd;
}
}

View file

@ -2,9 +2,14 @@ package com.mojang.minecraft;
import com.mojang.minecraft.character.Zombie;
import com.mojang.minecraft.gui.Font;
import com.mojang.minecraft.gui.PauseScreen;
import com.mojang.minecraft.gui.Screen;
import com.mojang.minecraft.level.Chunk;
import com.mojang.minecraft.level.Level;
import com.mojang.minecraft.level.LevelIO;
import com.mojang.minecraft.level.LevelLoaderListener;
import com.mojang.minecraft.level.LevelRenderer;
import com.mojang.minecraft.level.levelgen.LevelGen;
import com.mojang.minecraft.level.tile.Tile;
import com.mojang.minecraft.particle.ParticleEngine;
import com.mojang.minecraft.phys.AABB;
@ -13,6 +18,9 @@ import com.mojang.minecraft.renderer.Tesselator;
import com.mojang.minecraft.renderer.Textures;
import java.awt.Canvas;
import java.awt.Component;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
@ -28,11 +36,11 @@ import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;
public class Minecraft implements Runnable {
public static final String VERSION_STRING = "0.0.11a";
public class Minecraft implements Runnable, LevelLoaderListener {
public static final String VERSION_STRING = "0.0.13a";
private boolean fullscreen = false;
private int width;
private int height;
public int width;
public int height;
private FloatBuffer fogColor0 = BufferUtils.createFloatBuffer(4);
private FloatBuffer fogColor1 = BufferUtils.createFloatBuffer(4);
private Timer timer = new Timer(20.0F);
@ -41,6 +49,7 @@ public class Minecraft implements Runnable {
private Player player;
private int paintTexture = 1;
private ParticleEngine particleEngine;
public User user = new User("noname");
private ArrayList<Entity> entities = new ArrayList();
private Canvas parent;
public boolean appletMode = false;
@ -48,8 +57,11 @@ public class Minecraft implements Runnable {
private Cursor emptyCursor;
private int yMouseAxis = 1;
public Textures textures;
private Font font;
public Font font;
private int editMode = 0;
private Screen screen = null;
private LevelIO levelIo = new LevelIO(this);
private LevelGen levelGen = new LevelGen(this);
private volatile boolean running = false;
private String fpsString = "";
private boolean mouseGrabbed = false;
@ -57,6 +69,7 @@ public class Minecraft implements Runnable {
private IntBuffer selectBuffer = BufferUtils.createIntBuffer(2000);
private HitResult hitResult = null;
FloatBuffer lb = BufferUtils.createFloatBuffer(16);
private String title = "";
public Minecraft(Canvas parent, int width, int height, boolean fullscreen) {
this.parent = parent;
@ -67,12 +80,11 @@ public class Minecraft implements Runnable {
}
public void init() throws LWJGLException, IOException {
int col0 = 16710650;
int col1 = 920330;
float fr = 0.5F;
float fg = 0.8F;
float fb = 1.0F;
this.fogColor0.put(new float[]{(float)(col0 >> 16 & 255) / 255.0F, (float)(col0 >> 8 & 255) / 255.0F, (float)(col0 & 255) / 255.0F, 1.0F});
this.fogColor0.put(new float[]{fr, fg, fb, 1.0F});
this.fogColor0.flip();
this.fogColor1.put(new float[]{(float)(col1 >> 16 & 255) / 255.0F, (float)(col1 >> 8 & 255) / 255.0F, (float)(col1 & 255) / 255.0F, 1.0F});
this.fogColor1.flip();
@ -86,16 +98,16 @@ public class Minecraft implements Runnable {
Display.setDisplayMode(new DisplayMode(this.width, this.height));
}
Display.setTitle("Minecraft 0.0.11a");
Display.setTitle("Minecraft 0.0.13a");
try {
Display.create();
} catch (LWJGLException var10) {
var10.printStackTrace();
} catch (LWJGLException var12) {
var12.printStackTrace();
try {
Thread.sleep(1000L);
} catch (InterruptedException var9) {
} catch (InterruptedException var11) {
}
Display.create();
@ -112,37 +124,62 @@ public class Minecraft implements Runnable {
GL11.glDepthFunc(GL11.GL_LEQUAL);
GL11.glEnable(GL11.GL_ALPHA_TEST);
GL11.glAlphaFunc(GL11.GL_GREATER, 0.0F);
GL11.glCullFace(GL11.GL_BACK);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
this.checkGlError("Startup");
this.level = new Level(256, 256, 64);
this.font = new Font("/default.gif", this.textures);
IntBuffer imgData = BufferUtils.createIntBuffer(256);
imgData.clear().limit(256);
GL11.glViewport(0, 0, this.width, this.height);
this.level = new Level();
boolean success = false;
try {
success = this.levelIo.load(this.level, new FileInputStream(new File("level.dat")));
if(!success) {
success = this.levelIo.loadLegacy(this.level, new FileInputStream(new File("level.dat")));
}
} catch (Exception var10) {
success = false;
}
if(!success) {
this.levelGen.generateLevel(this.level, this.user.name, 256, 256, 64);
}
this.levelRenderer = new LevelRenderer(this.level, this.textures);
this.player = new Player(this.level);
this.particleEngine = new ParticleEngine(this.level, this.textures);
this.font = new Font("/default.gif", this.textures);
for(int imgData = 0; imgData < 10; ++imgData) {
Zombie e = new Zombie(this.level, this.textures, 128.0F, 0.0F, 128.0F);
e.resetPos();
this.entities.add(e);
for(int e = 0; e < 10; ++e) {
Zombie zombie = new Zombie(this.level, this.textures, 128.0F, 0.0F, 128.0F);
zombie.resetPos();
this.entities.add(zombie);
}
IntBuffer var11 = BufferUtils.createIntBuffer(256);
var11.clear().limit(256);
if(this.appletMode) {
try {
this.emptyCursor = new Cursor(16, 16, 0, 0, 1, var11, (IntBuffer)null);
} catch (LWJGLException var8) {
var8.printStackTrace();
this.emptyCursor = new Cursor(16, 16, 0, 0, 1, imgData, (IntBuffer)null);
} catch (LWJGLException var9) {
var9.printStackTrace();
}
} else {
this.grabMouse();
}
this.checkGlError("Post startup");
}
public void setScreen(Screen screen) {
this.screen = screen;
if(screen != null) {
int screenWidth = this.width * 240 / this.height;
int screenHeight = this.height * 240 / this.height;
screen.init(this, screenWidth, screenHeight);
}
}
private void checkGlError(String string) {
int errorCode = GL11.glGetError();
if(errorCode != 0) {
@ -155,12 +192,17 @@ public class Minecraft implements Runnable {
}
public void destroy() {
protected void attemptSaveLevel() {
try {
this.level.save();
this.levelIo.save(this.level, new FileOutputStream(new File("level.dat")));
} catch (Exception var2) {
var2.printStackTrace();
}
}
public void destroy() {
this.attemptSaveLevel();
Mouse.destroy();
Keyboard.destroy();
Display.destroy();
@ -172,6 +214,7 @@ public class Minecraft implements Runnable {
try {
this.init();
} catch (Exception var9) {
var9.printStackTrace();
JOptionPane.showMessageDialog((Component)null, var9.toString(), "Failed to start Minecraft", 0);
return;
}
@ -233,11 +276,13 @@ public class Minecraft implements Runnable {
Mouse.setGrabbed(true);
}
this.setScreen((Screen)null);
}
}
public void releaseMouse() {
if(this.mouseGrabbed) {
this.player.releaseAllKeys();
this.mouseGrabbed = false;
if(this.appletMode) {
try {
@ -249,6 +294,7 @@ public class Minecraft implements Runnable {
Mouse.setGrabbed(false);
}
this.setScreen(new PauseScreen());
}
}
@ -298,74 +344,96 @@ public class Minecraft implements Runnable {
}
public void tick() {
while(Mouse.next()) {
if(!this.mouseGrabbed && Mouse.getEventButtonState()) {
this.grabMouse();
} else {
if(Mouse.getEventButton() == 0 && Mouse.getEventButtonState()) {
this.handleMouseClick();
}
if(this.screen == null) {
label97:
while(true) {
if(!Mouse.next()) {
while(true) {
if(!Keyboard.next()) {
break label97;
}
if(Mouse.getEventButton() == 1 && Mouse.getEventButtonState()) {
this.editMode = (this.editMode + 1) % 2;
}
}
}
this.player.setKey(Keyboard.getEventKey(), Keyboard.getEventKeyState());
if(Keyboard.getEventKeyState()) {
if(Keyboard.getEventKey() == Keyboard.KEY_ESCAPE) {
this.releaseMouse();
}
while(true) {
do {
if(!Keyboard.next()) {
this.level.tick();
this.particleEngine.tick();
if(Keyboard.getEventKey() == Keyboard.KEY_RETURN) {
this.attemptSaveLevel();
}
for(int i = 0; i < this.entities.size(); ++i) {
((Entity)this.entities.get(i)).tick();
if(((Entity)this.entities.get(i)).removed) {
this.entities.remove(i--);
if(Keyboard.getEventKey() == Keyboard.KEY_R) {
this.player.resetPos();
}
if(Keyboard.getEventKey() == Keyboard.KEY_1) {
this.paintTexture = 1;
}
if(Keyboard.getEventKey() == Keyboard.KEY_2) {
this.paintTexture = 3;
}
if(Keyboard.getEventKey() == Keyboard.KEY_3) {
this.paintTexture = 4;
}
if(Keyboard.getEventKey() == Keyboard.KEY_4) {
this.paintTexture = 5;
}
if(Keyboard.getEventKey() == Keyboard.KEY_6) {
this.paintTexture = 6;
}
if(Keyboard.getEventKey() == Keyboard.KEY_Y) {
this.yMouseAxis *= -1;
}
if(Keyboard.getEventKey() == Keyboard.KEY_G) {
this.entities.add(new Zombie(this.level, this.textures, this.player.x, this.player.y, this.player.z));
}
if(Keyboard.getEventKey() == Keyboard.KEY_F) {
this.levelRenderer.toggleDrawDistance();
}
}
}
this.player.tick();
return;
}
} while(!Keyboard.getEventKeyState());
if(Keyboard.getEventKey() == Keyboard.KEY_ESCAPE && (this.appletMode || !this.fullscreen)) {
this.releaseMouse();
}
if(!this.mouseGrabbed && Mouse.getEventButtonState()) {
this.grabMouse();
} else {
if(Mouse.getEventButton() == 0 && Mouse.getEventButtonState()) {
this.handleMouseClick();
}
if(Keyboard.getEventKey() == Keyboard.KEY_RETURN) {
this.level.save();
}
if(Keyboard.getEventKey() == Keyboard.KEY_1) {
this.paintTexture = 1;
}
if(Keyboard.getEventKey() == Keyboard.KEY_2) {
this.paintTexture = 3;
}
if(Keyboard.getEventKey() == Keyboard.KEY_3) {
this.paintTexture = 4;
}
if(Keyboard.getEventKey() == Keyboard.KEY_4) {
this.paintTexture = 5;
}
if(Keyboard.getEventKey() == Keyboard.KEY_6) {
this.paintTexture = 6;
}
if(Keyboard.getEventKey() == Keyboard.KEY_Y) {
this.yMouseAxis *= -1;
}
if(Keyboard.getEventKey() == Keyboard.KEY_G) {
this.entities.add(new Zombie(this.level, this.textures, this.player.x, this.player.y, this.player.z));
if(Mouse.getEventButton() == 1 && Mouse.getEventButtonState()) {
this.editMode = (this.editMode + 1) % 2;
}
}
}
}
if(this.screen != null) {
this.screen.updateEvents();
if(this.screen != null) {
this.screen.tick();
}
}
this.level.tick();
this.particleEngine.tick();
for(int i = 0; i < this.entities.size(); ++i) {
((Entity)this.entities.get(i)).tick();
if(((Entity)this.entities.get(i)).removed) {
this.entities.remove(i--);
}
}
this.player.tick();
}
private boolean isFree(AABB aabb) {
@ -395,7 +463,7 @@ public class Minecraft implements Runnable {
private void setupCamera(float a) {
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GLU.gluPerspective(70.0F, (float)this.width / (float)this.height, 0.05F, 1000.0F);
GLU.gluPerspective(70.0F, (float)this.width / (float)this.height, 0.05F, 1024.0F);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
this.moveCameraToPlayer(a);
@ -409,7 +477,7 @@ public class Minecraft implements Runnable {
this.viewportBuffer.flip();
this.viewportBuffer.limit(16);
GLU.gluPickMatrix((float)x, (float)y, 5.0F, 5.0F, this.viewportBuffer);
GLU.gluPerspective(70.0F, (float)this.width / (float)this.height, 0.05F, 1000.0F);
GLU.gluPerspective(70.0F, (float)this.width / (float)this.height, 0.05F, 1024.0F);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
this.moveCameraToPlayer(a);
@ -424,35 +492,25 @@ public class Minecraft implements Runnable {
int hits = GL11.glRenderMode(GL11.GL_RENDER);
this.selectBuffer.flip();
this.selectBuffer.limit(this.selectBuffer.capacity());
long closest = 0L;
int[] names = new int[10];
int hitNameCount = 0;
HitResult bestResult = null;
for(int i = 0; i < hits; ++i) {
int nameCount = this.selectBuffer.get();
long minZ = (long)this.selectBuffer.get();
this.selectBuffer.get();
int j;
if(minZ >= closest && i != 0) {
for(j = 0; j < nameCount; ++j) {
this.selectBuffer.get();
}
} else {
closest = minZ;
hitNameCount = nameCount;
this.selectBuffer.get();
for(j = 0; j < nameCount; ++j) {
names[j] = this.selectBuffer.get();
}
for(int j = 0; j < nameCount; ++j) {
names[j] = this.selectBuffer.get();
}
this.hitResult = new HitResult(names[0], names[1], names[2], names[3], names[4]);
if(bestResult == null || this.hitResult.isCloserThan(this.player, bestResult, this.editMode)) {
bestResult = this.hitResult;
}
}
if(hitNameCount > 0) {
this.hitResult = new HitResult(names[0], names[1], names[2], names[3], names[4]);
} else {
this.hitResult = null;
}
this.hitResult = bestResult;
}
public void render(float a) {
@ -485,6 +543,7 @@ public class Minecraft implements Runnable {
this.checkGlError("Set up camera");
GL11.glEnable(GL11.GL_CULL_FACE);
Frustum var5 = Frustum.getFrustum();
this.levelRenderer.cull(var5);
this.levelRenderer.updateDirtyChunks(this.player);
this.checkGlError("Update chunks");
this.setupFog(0);
@ -515,17 +574,37 @@ public class Minecraft implements Runnable {
}
this.particleEngine.render(this.player, a, 1);
this.levelRenderer.renderSurroundingGround();
if(this.hitResult != null) {
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_ALPHA_TEST);
this.levelRenderer.renderHit(this.player, this.hitResult, this.editMode, this.paintTexture);
this.levelRenderer.renderHitOutline(this.player, this.hitResult, this.editMode, this.paintTexture);
GL11.glEnable(GL11.GL_ALPHA_TEST);
GL11.glEnable(GL11.GL_LIGHTING);
}
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
this.setupFog(0);
this.levelRenderer.renderSurroundingWater();
GL11.glEnable(GL11.GL_BLEND);
GL11.glColorMask(false, false, false, false);
this.levelRenderer.render(this.player, 2);
GL11.glColorMask(true, true, true, true);
this.levelRenderer.render(this.player, 2);
GL11.glDisable(GL11.GL_BLEND);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_FOG);
this.checkGlError("Rendered rest");
if(this.hitResult != null) {
GL11.glDepthFunc(GL11.GL_LESS);
GL11.glDisable(GL11.GL_ALPHA_TEST);
this.levelRenderer.renderHit(this.hitResult, this.editMode, this.paintTexture);
this.levelRenderer.renderHit(this.player, this.hitResult, this.editMode, this.paintTexture);
this.levelRenderer.renderHitOutline(this.player, this.hitResult, this.editMode, this.paintTexture);
GL11.glEnable(GL11.GL_ALPHA_TEST);
GL11.glDepthFunc(GL11.GL_LEQUAL);
}
this.checkGlError("Rendered hit");
this.drawGui(a);
this.checkGlError("Rendered gui");
Display.update();
@ -534,6 +613,8 @@ public class Minecraft implements Runnable {
private void drawGui(float a) {
int screenWidth = this.width * 240 / this.height;
int screenHeight = this.height * 240 / this.height;
int xMouse = Mouse.getX() * screenWidth / this.width;
int yMouse = screenHeight - Mouse.getY() * screenHeight / this.height - 1;
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
@ -543,29 +624,29 @@ public class Minecraft implements Runnable {
GL11.glTranslatef(0.0F, 0.0F, -200.0F);
this.checkGlError("GUI: Init");
GL11.glPushMatrix();
GL11.glTranslatef((float)(screenWidth - 16), 16.0F, 0.0F);
GL11.glTranslatef((float)(screenWidth - 16), 16.0F, -50.0F);
Tesselator t = Tesselator.instance;
GL11.glScalef(16.0F, 16.0F, 16.0F);
GL11.glRotatef(30.0F, 1.0F, 0.0F, 0.0F);
GL11.glRotatef(-30.0F, 1.0F, 0.0F, 0.0F);
GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F);
GL11.glTranslatef(-1.5F, 0.5F, -0.5F);
GL11.glScalef(-1.0F, -1.0F, 1.0F);
GL11.glTranslatef(-1.5F, 0.5F, 0.5F);
GL11.glScalef(-1.0F, -1.0F, -1.0F);
int id = this.textures.loadTexture("/terrain.png", 9728);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
GL11.glEnable(GL11.GL_TEXTURE_2D);
t.init();
t.begin();
Tile.tiles[this.paintTexture].render(t, this.level, 0, -2, 0, 0);
t.flush();
t.end();
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glPopMatrix();
this.checkGlError("GUI: Draw selected");
this.font.drawShadow("0.0.11a", 2, 2, 16777215);
this.font.drawShadow("0.0.13a", 2, 2, 16777215);
this.font.drawShadow(this.fpsString, 2, 12, 16777215);
this.checkGlError("GUI: Draw text");
int wc = screenWidth / 2;
int hc = screenHeight / 2;
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
t.init();
t.begin();
t.vertex((float)(wc + 1), (float)(hc - 4), 0.0F);
t.vertex((float)(wc - 0), (float)(hc - 4), 0.0F);
t.vertex((float)(wc - 0), (float)(hc + 5), 0.0F);
@ -574,26 +655,42 @@ public class Minecraft implements Runnable {
t.vertex((float)(wc - 4), (float)(hc - 0), 0.0F);
t.vertex((float)(wc - 4), (float)(hc + 1), 0.0F);
t.vertex((float)(wc + 5), (float)(hc + 1), 0.0F);
t.flush();
t.end();
this.checkGlError("GUI: Draw crosshair");
if(this.screen != null) {
this.screen.render(xMouse, yMouse);
}
}
private void setupFog(int i) {
if(i == 0) {
Tile currentTile = Tile.tiles[this.level.getTile((int)this.player.x, (int)(this.player.y + 0.12F), (int)this.player.z)];
if(currentTile != null && currentTile.getLiquidType() == 1) {
GL11.glFogi(GL11.GL_FOG_MODE, GL11.GL_EXP);
GL11.glFogf(GL11.GL_FOG_DENSITY, 0.1F);
GL11.glFog(GL11.GL_FOG_COLOR, this.getBuffer(0.02F, 0.02F, 0.2F, 1.0F));
GL11.glLightModel(GL11.GL_LIGHT_MODEL_AMBIENT, this.getBuffer(0.3F, 0.3F, 0.7F, 1.0F));
} else if(currentTile != null && currentTile.getLiquidType() == 2) {
GL11.glFogi(GL11.GL_FOG_MODE, GL11.GL_EXP);
GL11.glFogf(GL11.GL_FOG_DENSITY, 2.0F);
GL11.glFog(GL11.GL_FOG_COLOR, this.getBuffer(0.6F, 0.1F, 0.0F, 1.0F));
GL11.glLightModel(GL11.GL_LIGHT_MODEL_AMBIENT, this.getBuffer(0.4F, 0.3F, 0.3F, 1.0F));
} else if(i == 0) {
GL11.glFogi(GL11.GL_FOG_MODE, GL11.GL_EXP);
GL11.glFogf(GL11.GL_FOG_DENSITY, 0.001F);
GL11.glFog(GL11.GL_FOG_COLOR, this.fogColor0);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glLightModel(GL11.GL_LIGHT_MODEL_AMBIENT, this.getBuffer(1.0F, 1.0F, 1.0F, 1.0F));
} else if(i == 1) {
GL11.glFogi(GL11.GL_FOG_MODE, GL11.GL_EXP);
GL11.glFogf(GL11.GL_FOG_DENSITY, 0.01F);
GL11.glFog(GL11.GL_FOG_COLOR, this.fogColor1);
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_COLOR_MATERIAL);
float br = 0.6F;
GL11.glLightModel(GL11.GL_LIGHT_MODEL_AMBIENT, this.getBuffer(br, br, br, 1.0F));
}
GL11.glEnable(GL11.GL_COLOR_MATERIAL);
GL11.glColorMaterial(GL11.GL_FRONT, GL11.GL_AMBIENT);
GL11.glEnable(GL11.GL_LIGHTING);
}
private FloatBuffer getBuffer(float a, float b, float c, float d) {
@ -610,8 +707,67 @@ public class Minecraft implements Runnable {
}
}
public void beginLevelLoading(String title) {
this.title = title;
int screenWidth = this.width * 240 / this.height;
int screenHeight = this.height * 240 / this.height;
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0.0D, (double)screenWidth, (double)screenHeight, 0.0D, 100.0D, 300.0D);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
GL11.glTranslatef(0.0F, 0.0F, -200.0F);
}
public void levelLoadUpdate(String status) {
int screenWidth = this.width * 240 / this.height;
int screenHeight = this.height * 240 / this.height;
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_COLOR_BUFFER_BIT);
Tesselator t = Tesselator.instance;
GL11.glEnable(GL11.GL_TEXTURE_2D);
int id = this.textures.loadTexture("/dirt.png", 9728);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
t.begin();
t.color(8421504);
float s = 32.0F;
t.vertexUV(0.0F, (float)screenHeight, 0.0F, 0.0F, (float)screenHeight / s);
t.vertexUV((float)screenWidth, (float)screenHeight, 0.0F, (float)screenWidth / s, (float)screenHeight / s);
t.vertexUV((float)screenWidth, 0.0F, 0.0F, (float)screenWidth / s, 0.0F);
t.vertexUV(0.0F, 0.0F, 0.0F, 0.0F, 0.0F);
t.end();
GL11.glEnable(GL11.GL_TEXTURE_2D);
this.font.drawShadow(this.title, (screenWidth - this.font.width(this.title)) / 2, screenHeight / 2 - 4 - 8, 16777215);
this.font.drawShadow(status, (screenWidth - this.font.width(status)) / 2, screenHeight / 2 - 4 + 4, 16777215);
Display.update();
try {
Thread.sleep(200L);
} catch (Exception var8) {
}
}
public void generateNewLevel() {
this.levelGen.generateLevel(this.level, this.user.name, 32, 512, 64);
this.player.resetPos();
for(int i = 0; i < this.entities.size(); ++i) {
this.entities.remove(i--);
}
}
public static void main(String[] args) throws LWJGLException {
Minecraft minecraft = new Minecraft((Canvas)null, 854, 480, false);
(new Thread(minecraft)).start();
boolean fullScreen = false;
for(int minecraft = 0; minecraft < args.length; ++minecraft) {
if(args[minecraft].equalsIgnoreCase("-fullscreen")) {
fullScreen = true;
}
}
Minecraft var3 = new Minecraft((Canvas)null, 854, 480, fullScreen);
(new Thread(var3)).start();
}
}

View file

@ -21,7 +21,7 @@ public class MinecraftApplet extends Applet {
super.removeNotify();
}
};
this.minecraft = new Minecraft(this.canvas, 640, 480, false);
this.minecraft = new Minecraft(this.canvas, this.getWidth(), this.getHeight(), false);
this.minecraft.appletMode = true;
this.setLayout(new BorderLayout());
this.add(this.canvas, "Center");

View file

@ -1,53 +1,124 @@
package com.mojang.minecraft;
import com.mojang.minecraft.level.Level;
import org.lwjgl.input.Keyboard;
public class Player extends Entity {
public static final int KEY_UP = 0;
public static final int KEY_DOWN = 1;
public static final int KEY_LEFT = 2;
public static final int KEY_RIGHT = 3;
public static final int KEY_JUMP = 4;
private boolean[] keys = new boolean[10];
public Player(Level level) {
super(level);
this.heightOffset = 1.62F;
}
public void setKey(int key, boolean state) {
byte id = -1;
if(key == 200 || key == 17) {
id = 0;
}
if(key == 208 || key == 31) {
id = 1;
}
if(key == 203 || key == 30) {
id = 2;
}
if(key == 205 || key == 32) {
id = 3;
}
if(key == 57 || key == 219) {
id = 4;
}
if(id >= 0) {
this.keys[id] = state;
}
}
public void releaseAllKeys() {
for(int i = 0; i < 10; ++i) {
this.keys[i] = false;
}
}
public void tick() {
this.xo = this.x;
this.yo = this.y;
this.zo = this.z;
float xa = 0.0F;
float ya = 0.0F;
if(Keyboard.isKeyDown(Keyboard.KEY_R)) {
this.resetPos();
}
if(Keyboard.isKeyDown(Keyboard.KEY_UP) || Keyboard.isKeyDown(Keyboard.KEY_W)) {
boolean inWater = this.isInWater();
boolean inLava = this.isInLava();
if(this.keys[0]) {
--ya;
}
if(Keyboard.isKeyDown(Keyboard.KEY_DOWN) || Keyboard.isKeyDown(Keyboard.KEY_S)) {
if(this.keys[1]) {
++ya;
}
if(Keyboard.isKeyDown(Keyboard.KEY_LEFT) || Keyboard.isKeyDown(Keyboard.KEY_A)) {
if(this.keys[2]) {
--xa;
}
if(Keyboard.isKeyDown(Keyboard.KEY_RIGHT) || Keyboard.isKeyDown(Keyboard.KEY_D)) {
if(this.keys[3]) {
++xa;
}
if((Keyboard.isKeyDown(Keyboard.KEY_SPACE) || Keyboard.isKeyDown(Keyboard.KEY_LMETA)) && this.onGround) {
this.yd = 0.5F;
if(this.keys[4]) {
if(inWater) {
this.yd += 0.04F;
} else if(inLava) {
this.yd += 0.04F;
} else if(this.onGround) {
this.yd = 0.42F;
this.keys[4] = false;
}
}
this.moveRelative(xa, ya, this.onGround ? 0.1F : 0.02F);
this.yd = (float)((double)this.yd - 0.08D);
this.move(this.xd, this.yd, this.zd);
this.xd *= 0.91F;
this.yd *= 0.98F;
this.zd *= 0.91F;
if(this.onGround) {
this.xd *= 0.7F;
this.zd *= 0.7F;
float yo;
if(inWater) {
yo = this.y;
this.moveRelative(xa, ya, 0.02F);
this.move(this.xd, this.yd, this.zd);
this.xd *= 0.8F;
this.yd *= 0.8F;
this.zd *= 0.8F;
this.yd = (float)((double)this.yd - 0.02D);
if(this.horizontalCollision && this.isFree(this.xd, this.yd + 0.6F - this.y + yo, this.zd)) {
this.yd = 0.3F;
}
} else if(inLava) {
yo = this.y;
this.moveRelative(xa, ya, 0.02F);
this.move(this.xd, this.yd, this.zd);
this.xd *= 0.5F;
this.yd *= 0.5F;
this.zd *= 0.5F;
this.yd = (float)((double)this.yd - 0.02D);
if(this.horizontalCollision && this.isFree(this.xd, this.yd + 0.6F - this.y + yo, this.zd)) {
this.yd = 0.3F;
}
} else {
this.moveRelative(xa, ya, this.onGround ? 0.1F : 0.02F);
this.move(this.xd, this.yd, this.zd);
this.xd *= 0.91F;
this.yd *= 0.98F;
this.zd *= 0.91F;
this.yd = (float)((double)this.yd - 0.08D);
if(this.onGround) {
this.xd *= 0.6F;
this.zd *= 0.6F;
}
}
}

View file

@ -0,0 +1,9 @@
package com.mojang.minecraft;
public class User {
public String name;
public User(String name) {
this.name = name;
}
}

View file

@ -19,7 +19,6 @@ public class SocketConnection {
private ConnectionListener connectionListener;
private int bytesRead;
private int totalBytesWritten;
private int maxBlocksPerIteration = 3;
private Socket socket;
private BufferedInputStream in;
private BufferedOutputStream out;
@ -34,10 +33,6 @@ public class SocketConnection {
this.writeBuffer.clear();
}
public void setMaxBlocksPerIteration(int maxBlocksPerIteration) {
this.maxBlocksPerIteration = maxBlocksPerIteration;
}
public String getIp() {
return this.socket.getInetAddress().toString();
}

View file

@ -7,14 +7,11 @@ import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class SocketServer {
private ServerSocketChannel ssc;
private ServerListener serverListener;
private List<SocketConnection> connections = new LinkedList();
protected static Logger logger = Logger.getLogger("SocketServer");
public SocketServer(byte[] ips, int port, ServerListener serverListener) throws IOException {
this.serverListener = serverListener;
@ -47,7 +44,6 @@ public class SocketServer {
}
try {
logger.log(Level.INFO, socketChannel.socket().getRemoteSocketAddress() + " connected");
socketChannel.configureBlocking(false);
SocketConnection i = new SocketConnection(socketChannel);
this.connections.add(i);

View file

@ -0,0 +1,19 @@
package com.mojang.minecraft.gui;
public class Button {
public int x;
public int y;
public int w;
public int h;
public String msg;
public int id;
public Button(int id, int x, int y, int w, int h, String msg) {
this.id = id;
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.msg = msg;
}
}

View file

@ -70,7 +70,7 @@ public class Font {
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.fontTexture);
Tesselator t = Tesselator.instance;
t.init();
t.begin();
t.color(color);
int xo = 0;
@ -101,7 +101,7 @@ public class Font {
xo += this.charWidths[chars[i]];
}
t.flush();
t.end();
GL11.glDisable(GL11.GL_TEXTURE_2D);
}

View file

@ -0,0 +1,62 @@
package com.mojang.minecraft.gui;
import java.util.ArrayList;
import java.util.List;
public class PauseScreen extends Screen {
private List<Button> buttons = new ArrayList();
public void init() {
this.buttons.add(new Button(0, this.width / 2 - 100, this.height / 3 + 0, 200, 20, "Generate new level"));
this.buttons.add(new Button(1, this.width / 2 - 100, this.height / 3 + 32, 200, 20, "Save level.."));
this.buttons.add(new Button(2, this.width / 2 - 100, this.height / 3 + 64, 200, 20, "Load level.."));
this.buttons.add(new Button(3, this.width / 2 - 100, this.height / 3 + 96, 200, 20, "Back to game"));
}
protected void keyPressed(char eventCharacter, int eventKey) {
}
protected void mouseClicked(int x, int y, int buttonNum) {
if(buttonNum == 0) {
for(int i = 0; i < this.buttons.size(); ++i) {
Button button = (Button)this.buttons.get(i);
if(x >= button.x && y >= button.y && x < button.x + button.w && y < button.y + button.h) {
this.buttonClicked(button);
}
}
}
}
private void buttonClicked(Button button) {
if(button.id == 0) {
this.minecraft.generateNewLevel();
this.minecraft.setScreen((Screen)null);
this.minecraft.grabMouse();
}
if(button.id == 3) {
this.minecraft.setScreen((Screen)null);
this.minecraft.grabMouse();
}
}
public void render(int xm, int ym) {
this.fillGradient(0, 0, this.width, this.height, 537199872, -1607454624);
for(int i = 0; i < this.buttons.size(); ++i) {
Button button = (Button)this.buttons.get(i);
this.fill(button.x - 1, button.y - 1, button.x + button.w + 1, button.y + button.h + 1, -16777216);
if(xm >= button.x && ym >= button.y && xm < button.x + button.w && ym < button.y + button.h) {
this.fill(button.x - 1, button.y - 1, button.x + button.w + 1, button.y + button.h + 1, -6250336);
this.fill(button.x, button.y, button.x + button.w, button.y + button.h, -8355680);
this.drawCenteredString(button.msg, button.x + button.w / 2, button.y + (button.h - 8) / 2, 16777120);
} else {
this.fill(button.x, button.y, button.x + button.w, button.y + button.h, -9408400);
this.drawCenteredString(button.msg, button.x + button.w / 2, button.y + (button.h - 8) / 2, 14737632);
}
}
}
}

View file

@ -0,0 +1,102 @@
package com.mojang.minecraft.gui;
import com.mojang.minecraft.Minecraft;
import com.mojang.minecraft.renderer.Tesselator;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
public class Screen {
protected Minecraft minecraft;
protected int width;
protected int height;
public void render(int xMouse, int yMouse) {
}
public void init(Minecraft minecraft, int width, int height) {
this.minecraft = minecraft;
this.width = width;
this.height = height;
this.init();
}
public void init() {
}
protected void fill(int x0, int y0, int x1, int y1, int col) {
float a = (float)(col >> 24 & 255) / 255.0F;
float r = (float)(col >> 16 & 255) / 255.0F;
float g = (float)(col >> 8 & 255) / 255.0F;
float b = (float)(col & 255) / 255.0F;
Tesselator t = Tesselator.instance;
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glColor4f(r, g, b, a);
t.begin();
t.vertex((float)x0, (float)y1, 0.0F);
t.vertex((float)x1, (float)y1, 0.0F);
t.vertex((float)x1, (float)y0, 0.0F);
t.vertex((float)x0, (float)y0, 0.0F);
t.end();
GL11.glDisable(GL11.GL_BLEND);
}
protected void fillGradient(int x0, int y0, int x1, int y1, int col1, int col2) {
float a1 = (float)(col1 >> 24 & 255) / 255.0F;
float r1 = (float)(col1 >> 16 & 255) / 255.0F;
float g1 = (float)(col1 >> 8 & 255) / 255.0F;
float b1 = (float)(col1 & 255) / 255.0F;
float a2 = (float)(col2 >> 24 & 255) / 255.0F;
float r2 = (float)(col2 >> 16 & 255) / 255.0F;
float g2 = (float)(col2 >> 8 & 255) / 255.0F;
float b2 = (float)(col2 & 255) / 255.0F;
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glBegin(GL11.GL_QUADS);
GL11.glColor4f(r1, g1, b1, a1);
GL11.glVertex2f((float)x1, (float)y0);
GL11.glVertex2f((float)x0, (float)y0);
GL11.glColor4f(r2, g2, b2, a2);
GL11.glVertex2f((float)x0, (float)y1);
GL11.glVertex2f((float)x1, (float)y1);
GL11.glEnd();
GL11.glDisable(GL11.GL_BLEND);
}
public void drawCenteredString(String str, int x, int y, int color) {
Font font = this.minecraft.font;
font.drawShadow(str, x - font.width(str) / 2, y, color);
}
public void drawString(String str, int x, int y, int color) {
Font font = this.minecraft.font;
font.drawShadow(str, x, y, color);
}
public void updateEvents() {
while(Mouse.next()) {
if(Mouse.getEventButtonState()) {
int xm = Mouse.getEventX() * this.width / this.minecraft.width;
int ym = this.height - Mouse.getEventY() * this.height / this.minecraft.height - 1;
this.mouseClicked(xm, ym, Mouse.getEventButton());
}
}
while(Keyboard.next()) {
if(Keyboard.getEventKeyState()) {
this.keyPressed(Keyboard.getEventCharacter(), Keyboard.getEventKey());
}
}
}
protected void keyPressed(char eventCharacter, int eventKey) {
}
protected void mouseClicked(int x, int y, int button) {
}
public void tick() {
}
}

View file

@ -21,6 +21,7 @@ public class Chunk {
private boolean dirty = true;
private int lists = -1;
public long dirtiedTime = 0L;
public boolean visible;
private static Tesselator t = Tesselator.instance;
public static int updates = 0;
private static long totalTime = 0L;
@ -38,15 +39,13 @@ public class Chunk {
this.y = (float)(y0 + y1) / 2.0F;
this.z = (float)(z0 + z1) / 2.0F;
this.aabb = new AABB((float)x0, (float)y0, (float)z0, (float)x1, (float)y1, (float)z1);
this.lists = GL11.glGenLists(2);
this.lists = GL11.glGenLists(3);
}
private void rebuild(int layer) {
this.dirty = false;
++updates;
long before = System.nanoTime();
GL11.glNewList(this.lists + layer, GL11.GL_COMPILE);
t.init();
t.begin();
int tiles = 0;
for(int after = this.x0; after < this.x1; ++after) {
@ -61,7 +60,7 @@ public class Chunk {
}
}
t.flush();
t.end();
GL11.glEndList();
long var9 = System.nanoTime();
if(tiles > 0) {
@ -72,8 +71,11 @@ public class Chunk {
}
public void rebuild() {
++updates;
this.rebuild(0);
this.rebuild(1);
this.rebuild(2);
this.dirty = false;
}
public void render(int layer) {
@ -98,4 +100,14 @@ public class Chunk {
float zd = player.z - this.z;
return xd * xd + yd * yd + zd * zd;
}
public void reset() {
this.dirty = true;
for(int i = 0; i < 3; ++i) {
GL11.glNewList(this.lists + i, GL11.GL_COMPILE);
GL11.glEndList();
}
}
}

View file

@ -0,0 +1,13 @@
package com.mojang.minecraft.level;
public class Coord {
public final int x;
public final int y;
public final int z;
public Coord(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
}

View file

@ -1,30 +1,18 @@
package com.mojang.minecraft.level;
import com.mojang.minecraft.Player;
import com.mojang.minecraft.renderer.Frustum;
import java.util.Comparator;
public class DirtyChunkSorter implements Comparator<Chunk> {
private Player player;
private Frustum frustum;
private long now = System.currentTimeMillis();
public DirtyChunkSorter(Player player, Frustum frustum) {
public DirtyChunkSorter(Player player) {
this.player = player;
this.frustum = frustum;
}
public int compare(Chunk c0, Chunk c1) {
boolean i0 = this.frustum.isVisible(c0.aabb);
boolean i1 = this.frustum.isVisible(c1.aabb);
if(i0 && !i1) {
return -1;
} else if(i1 && !i0) {
return 1;
} else {
int t0 = (int)((this.now - c0.dirtiedTime) / 2000L);
int t1 = (int)((this.now - c1.dirtiedTime) / 2000L);
return t0 < t1 ? -1 : (t0 > t1 ? 1 : (c0.distanceToSqr(this.player) < c1.distanceToSqr(this.player) ? -1 : 1));
}
boolean i0 = c0.visible;
boolean i1 = c1.visible;
return i0 && !i1 ? -1 : (i1 && !i0 ? 1 : (c0.distanceToSqr(this.player) < c1.distanceToSqr(this.player) ? -1 : 1));
}
}

View file

@ -0,0 +1,16 @@
package com.mojang.minecraft.level;
import com.mojang.minecraft.Player;
import java.util.Comparator;
public class DistanceSorter implements Comparator<Chunk> {
private Player player;
public DistanceSorter(Player player) {
this.player = player;
}
public int compare(Chunk c0, Chunk c1) {
return c0.distanceToSqr(this.player) < c1.distanceToSqr(this.player) ? -1 : 1;
}
}

View file

@ -2,66 +2,36 @@ package com.mojang.minecraft.level;
import com.mojang.minecraft.level.tile.Tile;
import com.mojang.minecraft.phys.AABB;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Random;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class Level {
private static final int TILE_UPDATE_INTERVAL = 400;
public final int width;
public final int height;
public final int depth;
private byte[] blocks;
private static final int TILE_UPDATE_INTERVAL = 200;
public int width;
public int height;
public int depth;
byte[] blocks;
private int[] lightDepths;
private ArrayList<LevelListener> levelListeners = new ArrayList();
private Random random = new Random();
private int randValue = this.random.nextInt();
public String name;
public String creator;
public long createTime;
int unprocessed = 0;
private static final int multiplier = 1664525;
private static final int addend = 1013904223;
public Level(int w, int h, int d) {
public void setData(int w, int d, int h, byte[] blocks) {
this.width = w;
this.height = h;
this.depth = d;
this.blocks = new byte[w * h * d];
this.blocks = blocks;
this.lightDepths = new int[w * h];
boolean mapLoaded = this.load();
if(!mapLoaded) {
this.blocks = (new LevelGen(w, h, d)).generateMap();
}
this.calcLightDepths(0, 0, w, h);
}
public boolean load() {
try {
DataInputStream e = new DataInputStream(new GZIPInputStream(new FileInputStream(new File("level.dat"))));
e.readFully(this.blocks);
this.calcLightDepths(0, 0, this.width, this.height);
for(int i = 0; i < this.levelListeners.size(); ++i) {
((LevelListener)this.levelListeners.get(i)).allChanged();
}
e.close();
return true;
} catch (Exception var3) {
var3.printStackTrace();
return false;
}
}
public void save() {
try {
DataOutputStream e = new DataOutputStream(new GZIPOutputStream(new FileOutputStream(new File("level.dat"))));
e.write(this.blocks);
e.close();
} catch (Exception var2) {
var2.printStackTrace();
for(int i = 0; i < this.levelListeners.size(); ++i) {
((LevelListener)this.levelListeners.get(i)).allChanged();
}
}
@ -75,7 +45,7 @@ public class Level {
for(y = this.depth - 1; y > 0 && !this.isLightBlocker(x, y, z); --y) {
}
this.lightDepths[x + z * this.width] = y;
this.lightDepths[x + z * this.width] = y + 1;
if(oldDepth != y) {
int yl0 = oldDepth < y ? oldDepth : y;
int yl1 = oldDepth > y ? oldDepth : y;
@ -102,14 +72,131 @@ public class Level {
return tile == null ? false : tile.blocksLight();
}
public ArrayList<AABB> getCubes(AABB aABB) {
ArrayList aABBs = new ArrayList();
int x0 = (int)aABB.x0;
int x1 = (int)(aABB.x1 + 1.0F);
int y0 = (int)aABB.y0;
int y1 = (int)(aABB.y1 + 1.0F);
int z0 = (int)aABB.z0;
int z1 = (int)(aABB.z1 + 1.0F);
public ArrayList<AABB> getCubes(AABB box) {
ArrayList boxes = new ArrayList();
int x0 = (int)Math.floor((double)box.x0);
int x1 = (int)Math.floor((double)(box.x1 + 1.0F));
int y0 = (int)Math.floor((double)box.y0);
int y1 = (int)Math.floor((double)(box.y1 + 1.0F));
int z0 = (int)Math.floor((double)box.z0);
int z1 = (int)Math.floor((double)(box.z1 + 1.0F));
for(int x = x0; x < x1; ++x) {
for(int y = y0; y < y1; ++y) {
for(int z = z0; z < z1; ++z) {
if(x >= 0 && y >= 0 && z >= 0 && x < this.width && y < this.depth && z < this.height) {
Tile var14 = Tile.tiles[this.getTile(x, y, z)];
if(var14 != null) {
AABB aabb1 = var14.getAABB(x, y, z);
if(aabb1 != null) {
boxes.add(aabb1);
}
}
} else if(x < 0 || y < 0 || z < 0 || x >= this.width || z >= this.height) {
AABB aabb = Tile.unbreakable.getAABB(x, y, z);
if(aabb != null) {
boxes.add(aabb);
}
}
}
}
}
return boxes;
}
public boolean setTile(int x, int y, int z, int type) {
if(x >= 0 && y >= 0 && z >= 0 && x < this.width && y < this.depth && z < this.height) {
if(type == this.blocks[(y * this.height + z) * this.width + x]) {
return false;
} else {
this.blocks[(y * this.height + z) * this.width + x] = (byte)type;
this.neighborChanged(x - 1, y, z, type);
this.neighborChanged(x + 1, y, z, type);
this.neighborChanged(x, y - 1, z, type);
this.neighborChanged(x, y + 1, z, type);
this.neighborChanged(x, y, z - 1, type);
this.neighborChanged(x, y, z + 1, type);
this.calcLightDepths(x, z, 1, 1);
for(int i = 0; i < this.levelListeners.size(); ++i) {
((LevelListener)this.levelListeners.get(i)).tileChanged(x, y, z);
}
return true;
}
} else {
return false;
}
}
public boolean setTileNoUpdate(int x, int y, int z, int type) {
if(x >= 0 && y >= 0 && z >= 0 && x < this.width && y < this.depth && z < this.height) {
if(type == this.blocks[(y * this.height + z) * this.width + x]) {
return false;
} else {
this.blocks[(y * this.height + z) * this.width + x] = (byte)type;
return true;
}
} else {
return false;
}
}
private void neighborChanged(int x, int y, int z, int type) {
if(x >= 0 && y >= 0 && z >= 0 && x < this.width && y < this.depth && z < this.height) {
Tile tile = Tile.tiles[this.blocks[(y * this.height + z) * this.width + x]];
if(tile != null) {
tile.neighborChanged(this, x, y, z, type);
}
}
}
public boolean isLit(int x, int y, int z) {
return x >= 0 && y >= 0 && z >= 0 && x < this.width && y < this.depth && z < this.height ? y >= this.lightDepths[x + z * this.width] : true;
}
public int getTile(int x, int y, int z) {
return x >= 0 && y >= 0 && z >= 0 && x < this.width && y < this.depth && z < this.height ? this.blocks[(y * this.height + z) * this.width + x] : 0;
}
public boolean isSolidTile(int x, int y, int z) {
Tile tile = Tile.tiles[this.getTile(x, y, z)];
return tile == null ? false : tile.isSolid();
}
public void tick() {
this.unprocessed += this.width * this.height * this.depth;
int ticks = this.unprocessed / 200;
this.unprocessed -= ticks * 200;
for(int i = 0; i < ticks; ++i) {
this.randValue = this.randValue * 1664525 + 1013904223;
int x = this.randValue >> 16 & this.width - 1;
this.randValue = this.randValue * 1664525 + 1013904223;
int y = this.randValue >> 16 & this.depth - 1;
this.randValue = this.randValue * 1664525 + 1013904223;
int z = this.randValue >> 16 & this.height - 1;
byte id = this.blocks[(y * this.height + z) * this.width + x];
if(Tile.shouldTick[id]) {
Tile.tiles[id].tick(this, x, y, z, this.random);
}
}
}
public float getGroundLevel() {
return 32.0F;
}
public boolean containsAnyLiquid(AABB box) {
int x0 = (int)Math.floor((double)box.x0);
int x1 = (int)Math.floor((double)(box.x1 + 1.0F));
int y0 = (int)Math.floor((double)box.y0);
int y1 = (int)Math.floor((double)(box.y1 + 1.0F));
int z0 = (int)Math.floor((double)box.z0);
int z1 = (int)Math.floor((double)(box.z1 + 1.0F));
if(x0 < 0) {
x0 = 0;
}
@ -138,65 +225,58 @@ public class Level {
for(int y = y0; y < y1; ++y) {
for(int z = z0; z < z1; ++z) {
Tile tile = Tile.tiles[this.getTile(x, y, z)];
if(tile != null) {
AABB aabb = tile.getAABB(x, y, z);
if(aabb != null) {
aABBs.add(aabb);
}
if(tile != null && tile.getLiquidType() > 0) {
return true;
}
}
}
}
return aABBs;
return false;
}
public boolean setTile(int x, int y, int z, int type) {
if(x >= 0 && y >= 0 && z >= 0 && x < this.width && y < this.depth && z < this.height) {
if(type == this.blocks[(y * this.height + z) * this.width + x]) {
return false;
} else {
this.blocks[(y * this.height + z) * this.width + x] = (byte)type;
this.calcLightDepths(x, z, 1, 1);
public boolean containsLiquid(AABB box, int liquidId) {
int x0 = (int)Math.floor((double)box.x0);
int x1 = (int)Math.floor((double)(box.x1 + 1.0F));
int y0 = (int)Math.floor((double)box.y0);
int y1 = (int)Math.floor((double)(box.y1 + 1.0F));
int z0 = (int)Math.floor((double)box.z0);
int z1 = (int)Math.floor((double)(box.z1 + 1.0F));
if(x0 < 0) {
x0 = 0;
}
for(int i = 0; i < this.levelListeners.size(); ++i) {
((LevelListener)this.levelListeners.get(i)).tileChanged(x, y, z);
if(y0 < 0) {
y0 = 0;
}
if(z0 < 0) {
z0 = 0;
}
if(x1 > this.width) {
x1 = this.width;
}
if(y1 > this.depth) {
y1 = this.depth;
}
if(z1 > this.height) {
z1 = this.height;
}
for(int x = x0; x < x1; ++x) {
for(int y = y0; y < y1; ++y) {
for(int z = z0; z < z1; ++z) {
Tile tile = Tile.tiles[this.getTile(x, y, z)];
if(tile != null && tile.getLiquidType() == liquidId) {
return true;
}
}
return true;
}
} else {
return false;
}
}
public boolean isLit(int x, int y, int z) {
return x >= 0 && y >= 0 && z >= 0 && x < this.width && y < this.depth && z < this.height ? y >= this.lightDepths[x + z * this.width] : true;
}
public int getTile(int x, int y, int z) {
return x >= 0 && y >= 0 && z >= 0 && x < this.width && y < this.depth && z < this.height ? this.blocks[(y * this.height + z) * this.width + x] : 0;
}
public boolean isSolidTile(int x, int y, int z) {
Tile tile = Tile.tiles[this.getTile(x, y, z)];
return tile == null ? false : tile.isSolid();
}
public void tick() {
this.unprocessed += this.width * this.height * this.depth;
int ticks = this.unprocessed / 400;
this.unprocessed -= ticks * 400;
for(int i = 0; i < ticks; ++i) {
int x = this.random.nextInt(this.width);
int y = this.random.nextInt(this.depth);
int z = this.random.nextInt(this.height);
Tile tile = Tile.tiles[this.getTile(x, y, z)];
if(tile != null) {
tile.tick(this, x, y, z, this.random);
}
}
return false;
}
}

View file

@ -1,117 +0,0 @@
package com.mojang.minecraft.level;
import com.mojang.minecraft.level.tile.Tile;
import java.util.Random;
public class LevelGen {
private int width;
private int height;
private int depth;
private Random random = new Random();
public LevelGen(int width, int height, int depth) {
this.width = width;
this.height = height;
this.depth = depth;
}
public byte[] generateMap() {
int w = this.width;
int h = this.height;
int d = this.depth;
int[] heightmap1 = (new NoiseMap(0)).read(w, h);
int[] heightmap2 = (new NoiseMap(0)).read(w, h);
int[] cf = (new NoiseMap(1)).read(w, h);
int[] rockMap = (new NoiseMap(1)).read(w, h);
byte[] blocks = new byte[this.width * this.height * this.depth];
int count;
int i;
int length;
for(count = 0; count < w; ++count) {
for(i = 0; i < d; ++i) {
for(int x = 0; x < h; ++x) {
int y = heightmap1[count + x * this.width];
int z = heightmap2[count + x * this.width];
length = cf[count + x * this.width];
if(length < 128) {
z = y;
}
int dir1 = y;
if(z > y) {
dir1 = z;
}
dir1 = dir1 / 8 + d / 3;
int dira1 = rockMap[count + x * this.width] / 8 + d / 3;
if(dira1 > dir1 - 2) {
dira1 = dir1 - 2;
}
int dir2 = (i * this.height + x) * this.width + count;
int dira2 = 0;
if(i == dir1) {
dira2 = Tile.grass.id;
}
if(i < dir1) {
dira2 = Tile.dirt.id;
}
if(i <= dira1) {
dira2 = Tile.rock.id;
}
blocks[dir2] = (byte)dira2;
}
}
}
count = w * h * d / 256 / 64;
for(i = 0; i < count; ++i) {
float var29 = this.random.nextFloat() * (float)w;
float var30 = this.random.nextFloat() * (float)d;
float var31 = this.random.nextFloat() * (float)h;
length = (int)(this.random.nextFloat() + this.random.nextFloat() * 150.0F);
float var32 = (float)((double)this.random.nextFloat() * Math.PI * 2.0D);
float var33 = 0.0F;
float var34 = (float)((double)this.random.nextFloat() * Math.PI * 2.0D);
float var35 = 0.0F;
for(int l = 0; l < length; ++l) {
var29 = (float)((double)var29 + Math.sin((double)var32) * Math.cos((double)var34));
var31 = (float)((double)var31 + Math.cos((double)var32) * Math.cos((double)var34));
var30 = (float)((double)var30 + Math.sin((double)var34));
var32 += var33 * 0.2F;
var33 *= 0.9F;
var33 += this.random.nextFloat() - this.random.nextFloat();
var34 += var35 * 0.5F;
var34 *= 0.5F;
var35 *= 0.9F;
var35 += this.random.nextFloat() - this.random.nextFloat();
float size = (float)(Math.sin((double)l * Math.PI / (double)length) * 2.5D + 1.0D);
for(int xx = (int)(var29 - size); xx <= (int)(var29 + size); ++xx) {
for(int yy = (int)(var30 - size); yy <= (int)(var30 + size); ++yy) {
for(int zz = (int)(var31 - size); zz <= (int)(var31 + size); ++zz) {
float xd = (float)xx - var29;
float yd = (float)yy - var30;
float zd = (float)zz - var31;
float dd = xd * xd + yd * yd * 2.0F + zd * zd;
if(dd < size * size && xx >= 1 && yy >= 1 && zz >= 1 && xx < this.width - 1 && yy < this.depth - 1 && zz < this.height - 1) {
int ii = (yy * this.height + zz) * this.width + xx;
if(blocks[ii] == Tile.rock.id) {
blocks[ii] = 0;
}
}
}
}
}
}
}
return blocks;
}
}

View file

@ -0,0 +1,104 @@
package com.mojang.minecraft.level;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class LevelIO {
private static final int MAGIC_NUMBER = 656127880;
private static final int CURRENT_VERSION = 1;
private LevelLoaderListener levelLoaderListener;
public String error = null;
public LevelIO(LevelLoaderListener levelLoaderListener) {
this.levelLoaderListener = levelLoaderListener;
}
public boolean load(Level level, InputStream in) {
this.levelLoaderListener.beginLevelLoading("Loading level");
this.levelLoaderListener.levelLoadUpdate("Reading..");
try {
DataInputStream e = new DataInputStream(new GZIPInputStream(in));
int magic = e.readInt();
if(magic != 656127880) {
this.error = "Bad level file format";
return false;
} else {
byte version = e.readByte();
if(version > 1) {
this.error = "Bad level file format";
return false;
} else {
String name = e.readUTF();
String creator = e.readUTF();
long createTime = e.readLong();
short width = e.readShort();
short height = e.readShort();
short depth = e.readShort();
byte[] blocks = new byte[width * height * depth];
e.readFully(blocks);
e.close();
level.setData(width, depth, height, blocks);
level.name = name;
level.creator = creator;
level.createTime = createTime;
return true;
}
}
} catch (Exception var14) {
var14.printStackTrace();
this.error = "Failed to load level: " + var14.toString();
return false;
}
}
public boolean loadLegacy(Level level, InputStream in) {
this.levelLoaderListener.beginLevelLoading("Loading level");
this.levelLoaderListener.levelLoadUpdate("Reading..");
try {
DataInputStream e = new DataInputStream(new GZIPInputStream(in));
String name = "--";
String creator = "unknown";
long createTime = 0L;
short width = 256;
short height = 256;
byte depth = 64;
byte[] blocks = new byte[width * height * depth];
e.readFully(blocks);
e.close();
level.setData(width, depth, height, blocks);
level.name = name;
level.creator = creator;
level.createTime = createTime;
return true;
} catch (Exception var12) {
var12.printStackTrace();
this.error = "Failed to load level: " + var12.toString();
return false;
}
}
public void save(Level level, OutputStream out) {
try {
DataOutputStream e = new DataOutputStream(new GZIPOutputStream(out));
e.writeInt(656127880);
e.writeByte(1);
e.writeUTF(level.name);
e.writeUTF(level.creator);
e.writeLong(level.createTime);
e.writeShort(level.width);
e.writeShort(level.height);
e.writeShort(level.depth);
e.write(level.blocks);
e.close();
} catch (Exception var4) {
var4.printStackTrace();
}
}
}

View file

@ -0,0 +1,7 @@
package com.mojang.minecraft.level;
public interface LevelLoaderListener {
void beginLevelLoading(String var1);
void levelLoadUpdate(String var1);
}

View file

@ -8,55 +8,84 @@ import com.mojang.minecraft.renderer.Frustum;
import com.mojang.minecraft.renderer.Tesselator;
import com.mojang.minecraft.renderer.Textures;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.lwjgl.opengl.GL11;
public class LevelRenderer implements LevelListener {
public static final int MAX_REBUILDS_PER_FRAME = 8;
public static final int MAX_REBUILDS_PER_FRAME = 4;
public static final int CHUNK_SIZE = 16;
private Level level;
private Chunk[] chunks;
private Chunk[] sortedChunks;
private int xChunks;
private int yChunks;
private int zChunks;
private Textures textures;
private int surroundLists;
private int drawDistance = 0;
float lX = 0.0F;
float lY = 0.0F;
float lZ = 0.0F;
public LevelRenderer(Level level, Textures textures) {
this.level = level;
this.textures = textures;
level.addListener(this);
this.xChunks = level.width / 16;
this.yChunks = level.depth / 16;
this.zChunks = level.height / 16;
this.chunks = new Chunk[this.xChunks * this.yChunks * this.zChunks];
this.surroundLists = GL11.glGenLists(2);
this.allChanged();
}
for(int x = 0; x < this.xChunks; ++x) {
public void allChanged() {
this.lX = -900000.0F;
this.lY = -900000.0F;
this.lZ = -900000.0F;
this.xChunks = (this.level.width + 16 - 1) / 16;
this.yChunks = (this.level.depth + 16 - 1) / 16;
this.zChunks = (this.level.height + 16 - 1) / 16;
this.chunks = new Chunk[this.xChunks * this.yChunks * this.zChunks];
this.sortedChunks = new Chunk[this.xChunks * this.yChunks * this.zChunks];
int i;
for(i = 0; i < this.xChunks; ++i) {
for(int y = 0; y < this.yChunks; ++y) {
for(int z = 0; z < this.zChunks; ++z) {
int x0 = x * 16;
int x0 = i * 16;
int y0 = y * 16;
int z0 = z * 16;
int x1 = (x + 1) * 16;
int x1 = (i + 1) * 16;
int y1 = (y + 1) * 16;
int z1 = (z + 1) * 16;
if(x1 > level.width) {
x1 = level.width;
if(x1 > this.level.width) {
x1 = this.level.width;
}
if(y1 > level.depth) {
y1 = level.depth;
if(y1 > this.level.depth) {
y1 = this.level.depth;
}
if(z1 > level.height) {
z1 = level.height;
if(z1 > this.level.height) {
z1 = this.level.height;
}
this.chunks[(x + y * this.xChunks) * this.zChunks + z] = new Chunk(level, x0, y0, z0, x1, y1, z1);
this.chunks[(i + y * this.xChunks) * this.zChunks + z] = new Chunk(this.level, x0, y0, z0, x1, y1, z1);
this.sortedChunks[(i + y * this.xChunks) * this.zChunks + z] = this.chunks[(i + y * this.xChunks) * this.zChunks + z];
}
}
}
GL11.glNewList(this.surroundLists + 0, GL11.GL_COMPILE);
this.compileSurroundingGround();
GL11.glEndList();
GL11.glNewList(this.surroundLists + 1, GL11.GL_COMPILE);
this.compileSurroundingWater();
GL11.glEndList();
for(i = 0; i < this.chunks.length; ++i) {
this.chunks[i].reset();
}
}
public List<Chunk> getAllDirtyChunks() {
@ -78,25 +107,151 @@ public class LevelRenderer implements LevelListener {
public void render(Player player, int layer) {
GL11.glEnable(GL11.GL_TEXTURE_2D);
int id = this.textures.loadTexture("/terrain.png", 9728);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
Frustum frustum = Frustum.getFrustum();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.textures.loadTexture("/terrain.png", GL11.GL_NEAREST));
float xd = player.x - this.lX;
float yd = player.y - this.lY;
float zd = player.z - this.lZ;
if(xd * xd + yd * yd + zd * zd > 64.0F) {
this.lX = player.x;
this.lY = player.y;
this.lZ = player.z;
Arrays.sort(this.sortedChunks, new DistanceSorter(player));
}
for(int i = 0; i < this.chunks.length; ++i) {
if(frustum.isVisible(this.chunks[i].aabb)) {
this.chunks[i].render(layer);
for(int i = 0; i < this.sortedChunks.length; ++i) {
if(this.sortedChunks[i].visible) {
float dd = (float)(256 / (1 << this.drawDistance));
if(this.drawDistance == 0 || this.sortedChunks[i].distanceToSqr(player) < dd * dd) {
this.sortedChunks[i].render(layer);
}
}
}
GL11.glDisable(GL11.GL_TEXTURE_2D);
}
public void renderSurroundingGround() {
GL11.glCallList(this.surroundLists + 0);
}
public void compileSurroundingGround() {
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.textures.loadTexture("/rock.png", GL11.GL_NEAREST));
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
Tesselator t = Tesselator.instance;
float y = this.level.getGroundLevel() - 2.0F;
int s = 128;
if(s > this.level.width) {
s = this.level.width;
}
if(s > this.level.height) {
s = this.level.height;
}
byte d = 5;
t.begin();
int zz;
for(zz = -s * d; zz < this.level.width + s * d; zz += s) {
for(int zz1 = -s * d; zz1 < this.level.height + s * d; zz1 += s) {
float yy = y;
if(zz >= 0 && zz1 >= 0 && zz < this.level.width && zz1 < this.level.height) {
yy = 0.0F;
}
t.vertexUV((float)(zz + 0), yy, (float)(zz1 + s), 0.0F, (float)s);
t.vertexUV((float)(zz + s), yy, (float)(zz1 + s), (float)s, (float)s);
t.vertexUV((float)(zz + s), yy, (float)(zz1 + 0), (float)s, 0.0F);
t.vertexUV((float)(zz + 0), yy, (float)(zz1 + 0), 0.0F, 0.0F);
}
}
t.end();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.textures.loadTexture("/rock.png", GL11.GL_NEAREST));
GL11.glColor3f(0.8F, 0.8F, 0.8F);
t.begin();
for(zz = 0; zz < this.level.width; zz += s) {
t.vertexUV((float)(zz + 0), 0.0F, 0.0F, 0.0F, 0.0F);
t.vertexUV((float)(zz + s), 0.0F, 0.0F, (float)s, 0.0F);
t.vertexUV((float)(zz + s), y, 0.0F, (float)s, y);
t.vertexUV((float)(zz + 0), y, 0.0F, 0.0F, y);
t.vertexUV((float)(zz + 0), y, (float)this.level.height, 0.0F, y);
t.vertexUV((float)(zz + s), y, (float)this.level.height, (float)s, y);
t.vertexUV((float)(zz + s), 0.0F, (float)this.level.height, (float)s, 0.0F);
t.vertexUV((float)(zz + 0), 0.0F, (float)this.level.height, 0.0F, 0.0F);
}
GL11.glColor3f(0.6F, 0.6F, 0.6F);
for(zz = 0; zz < this.level.height; zz += s) {
t.vertexUV(0.0F, y, (float)(zz + 0), 0.0F, 0.0F);
t.vertexUV(0.0F, y, (float)(zz + s), (float)s, 0.0F);
t.vertexUV(0.0F, 0.0F, (float)(zz + s), (float)s, y);
t.vertexUV(0.0F, 0.0F, (float)(zz + 0), 0.0F, y);
t.vertexUV((float)this.level.width, 0.0F, (float)(zz + 0), 0.0F, y);
t.vertexUV((float)this.level.width, 0.0F, (float)(zz + s), (float)s, y);
t.vertexUV((float)this.level.width, y, (float)(zz + s), (float)s, 0.0F);
t.vertexUV((float)this.level.width, y, (float)(zz + 0), 0.0F, 0.0F);
}
t.end();
GL11.glDisable(GL11.GL_BLEND);
GL11.glDisable(GL11.GL_TEXTURE_2D);
}
public void renderSurroundingWater() {
GL11.glCallList(this.surroundLists + 1);
}
public void compileSurroundingWater() {
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glColor3f(1.0F, 1.0F, 1.0F);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.textures.loadTexture("/water.png", GL11.GL_NEAREST));
float y = this.level.getGroundLevel();
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
Tesselator t = Tesselator.instance;
int s = 128;
if(s > this.level.width) {
s = this.level.width;
}
if(s > this.level.height) {
s = this.level.height;
}
byte d = 5;
t.begin();
for(int xx = -s * d; xx < this.level.width + s * d; xx += s) {
for(int zz = -s * d; zz < this.level.height + s * d; zz += s) {
float yy = y - 0.1F;
if(xx < 0 || zz < 0 || xx >= this.level.width || zz >= this.level.height) {
t.vertexUV((float)(xx + 0), yy, (float)(zz + s), 0.0F, (float)s);
t.vertexUV((float)(xx + s), yy, (float)(zz + s), (float)s, (float)s);
t.vertexUV((float)(xx + s), yy, (float)(zz + 0), (float)s, 0.0F);
t.vertexUV((float)(xx + 0), yy, (float)(zz + 0), 0.0F, 0.0F);
t.vertexUV((float)(xx + 0), yy, (float)(zz + 0), 0.0F, 0.0F);
t.vertexUV((float)(xx + s), yy, (float)(zz + 0), (float)s, 0.0F);
t.vertexUV((float)(xx + s), yy, (float)(zz + s), (float)s, (float)s);
t.vertexUV((float)(xx + 0), yy, (float)(zz + s), 0.0F, (float)s);
}
}
}
t.end();
GL11.glDisable(GL11.GL_BLEND);
GL11.glDisable(GL11.GL_TEXTURE_2D);
}
public void updateDirtyChunks(Player player) {
List dirty = this.getAllDirtyChunks();
if(dirty != null) {
Collections.sort(dirty, new DirtyChunkSorter(player, Frustum.getFrustum()));
Collections.sort(dirty, new DirtyChunkSorter(player));
for(int i = 0; i < 8 && i < dirty.size(); ++i) {
for(int i = 0; i < 4 && i < dirty.size(); ++i) {
((Chunk)dirty.get(i)).rebuild();
}
@ -105,7 +260,7 @@ public class LevelRenderer implements LevelListener {
public void pick(Player player, Frustum frustum) {
Tesselator t = Tesselator.instance;
float r = 3.0F;
float r = 2.5F;
AABB box = player.bb.grow(r, r, r);
int x0 = (int)box.x0;
int x1 = (int)(box.x1 + 1.0F);
@ -127,15 +282,15 @@ public class LevelRenderer implements LevelListener {
for(int z = z0; z < z1; ++z) {
Tile tile = Tile.tiles[this.level.getTile(x, y, z)];
if(tile != null && frustum.isVisible(tile.getTileAABB(x, y, z))) {
if(tile != null && tile.mayPick() && frustum.isVisible(tile.getTileAABB(x, y, z))) {
GL11.glLoadName(z);
GL11.glPushName(0);
for(int i = 0; i < 6; ++i) {
GL11.glLoadName(i);
t.init();
tile.renderFaceNoTexture(t, x, y, z, i);
t.flush();
t.begin();
tile.renderFaceNoTexture(player, t, x, y, z, i);
t.end();
}
GL11.glPopName();
@ -152,23 +307,24 @@ public class LevelRenderer implements LevelListener {
GL11.glPopName();
}
public void renderHit(HitResult h, int mode, int tileType) {
public void renderHit(Player player, HitResult h, int mode, int tileType) {
Tesselator t = Tesselator.instance;
GL11.glEnable(GL11.GL_BLEND);
GL11.glEnable(GL11.GL_ALPHA_TEST);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
GL11.glColor4f(1.0F, 1.0F, 1.0F, ((float)Math.sin((double)System.currentTimeMillis() / 100.0D) * 0.2F + 0.4F) * 0.5F);
if(mode == 0) {
t.init();
t.begin();
for(int br = 0; br < 6; ++br) {
Tile.rock.renderFaceNoTexture(t, h.x, h.y, h.z, br);
Tile.rock.renderFaceNoTexture(player, t, h.x, h.y, h.z, br);
}
t.flush();
t.end();
} else {
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
float var10 = (float)Math.sin((double)System.currentTimeMillis() / 100.0D) * 0.2F + 0.8F;
GL11.glColor4f(var10, var10, var10, (float)Math.sin((double)System.currentTimeMillis() / 200.0D) * 0.2F + 0.5F);
float var11 = (float)Math.sin((double)System.currentTimeMillis() / 100.0D) * 0.2F + 0.8F;
GL11.glColor4f(var11, var11, var11, (float)Math.sin((double)System.currentTimeMillis() / 200.0D) * 0.2F + 0.5F);
GL11.glEnable(GL11.GL_TEXTURE_2D);
int id = this.textures.loadTexture("/terrain.png", 9728);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
@ -199,15 +355,76 @@ public class LevelRenderer implements LevelListener {
++x;
}
t.init();
t.begin();
t.noColor();
Tile.tiles[tileType].render(t, this.level, 0, x, y, z);
Tile.tiles[tileType].render(t, this.level, 1, x, y, z);
t.flush();
t.end();
GL11.glDisable(GL11.GL_TEXTURE_2D);
}
GL11.glDisable(GL11.GL_BLEND);
GL11.glDisable(GL11.GL_ALPHA_TEST);
}
public void renderHitOutline(Player player, HitResult h, int mode, int tileType) {
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glColor4f(0.0F, 0.0F, 0.0F, 0.4F);
float x = (float)h.x;
float y = (float)h.y;
float z = (float)h.z;
if(mode == 1) {
if(h.f == 0) {
--y;
}
if(h.f == 1) {
++y;
}
if(h.f == 2) {
--z;
}
if(h.f == 3) {
++z;
}
if(h.f == 4) {
--x;
}
if(h.f == 5) {
++x;
}
}
GL11.glBegin(GL11.GL_LINE_STRIP);
GL11.glVertex3f(x, y, z);
GL11.glVertex3f(x + 1.0F, y, z);
GL11.glVertex3f(x + 1.0F, y, z + 1.0F);
GL11.glVertex3f(x, y, z + 1.0F);
GL11.glVertex3f(x, y, z);
GL11.glEnd();
GL11.glBegin(GL11.GL_LINE_STRIP);
GL11.glVertex3f(x, y + 1.0F, z);
GL11.glVertex3f(x + 1.0F, y + 1.0F, z);
GL11.glVertex3f(x + 1.0F, y + 1.0F, z + 1.0F);
GL11.glVertex3f(x, y + 1.0F, z + 1.0F);
GL11.glVertex3f(x, y + 1.0F, z);
GL11.glEnd();
GL11.glBegin(GL11.GL_LINES);
GL11.glVertex3f(x, y, z);
GL11.glVertex3f(x, y + 1.0F, z);
GL11.glVertex3f(x + 1.0F, y, z);
GL11.glVertex3f(x + 1.0F, y + 1.0F, z);
GL11.glVertex3f(x + 1.0F, y, z + 1.0F);
GL11.glVertex3f(x + 1.0F, y + 1.0F, z + 1.0F);
GL11.glVertex3f(x, y, z + 1.0F);
GL11.glVertex3f(x, y + 1.0F, z + 1.0F);
GL11.glEnd();
GL11.glDisable(GL11.GL_BLEND);
}
public void setDirty(int x0, int y0, int z0, int x1, int y1, int z1) {
@ -259,7 +476,14 @@ public class LevelRenderer implements LevelListener {
this.setDirty(x - 1, y0 - 1, z - 1, x + 1, y1 + 1, z + 1);
}
public void allChanged() {
this.setDirty(0, 0, 0, this.level.width, this.level.depth, this.level.height);
public void toggleDrawDistance() {
this.drawDistance = (this.drawDistance + 1) % 4;
}
public void cull(Frustum frustum) {
for(int i = 0; i < this.chunks.length; ++i) {
this.chunks[i].visible = frustum.isVisible(this.chunks[i].aabb);
}
}
}

View file

@ -1,77 +0,0 @@
package com.mojang.minecraft.level;
import java.util.Random;
public class NoiseMap {
Random random = new Random();
int seed = this.random.nextInt();
int levels = 0;
int fuzz = 16;
public NoiseMap(int levels) {
this.levels = levels;
}
public int[] read(int width, int height) {
Random random = new Random();
int[] tmp = new int[width * height];
int level = this.levels;
int result = width >> level;
int y;
int x;
for(y = 0; y < height; y += result) {
for(x = 0; x < width; x += result) {
tmp[x + y * width] = (random.nextInt(256) - 128) * this.fuzz;
}
}
for(result = width >> level; result > 1; result /= 2) {
y = 256 * (result << level);
x = result / 2;
int y1;
int x1;
int c;
int r;
int d;
int mu;
int ml;
for(y1 = 0; y1 < height; y1 += result) {
for(x1 = 0; x1 < width; x1 += result) {
c = tmp[(x1 + 0) % width + (y1 + 0) % height * width];
r = tmp[(x1 + result) % width + (y1 + 0) % height * width];
d = tmp[(x1 + 0) % width + (y1 + result) % height * width];
mu = tmp[(x1 + result) % width + (y1 + result) % height * width];
ml = (c + d + r + mu) / 4 + random.nextInt(y * 2) - y;
tmp[x1 + x + (y1 + x) * width] = ml;
}
}
for(y1 = 0; y1 < height; y1 += result) {
for(x1 = 0; x1 < width; x1 += result) {
c = tmp[x1 + y1 * width];
r = tmp[(x1 + result) % width + y1 * width];
d = tmp[x1 + (y1 + result) % width * width];
mu = tmp[(x1 + x & width - 1) + (y1 + x - result & height - 1) * width];
ml = tmp[(x1 + x - result & width - 1) + (y1 + x & height - 1) * width];
int m = tmp[(x1 + x) % width + (y1 + x) % height * width];
int u = (c + r + m + mu) / 4 + random.nextInt(y * 2) - y;
int l = (c + d + m + ml) / 4 + random.nextInt(y * 2) - y;
tmp[x1 + x + y1 * width] = u;
tmp[x1 + (y1 + x) * width] = l;
}
}
}
int[] var19 = new int[width * height];
for(y = 0; y < height; ++y) {
for(x = 0; x < width; ++x) {
var19[x + y * width] = tmp[x % width + y % height * width] / 512 + 128;
}
}
return var19;
}
}

View file

@ -0,0 +1,288 @@
package com.mojang.minecraft.level.levelgen;
import com.mojang.minecraft.level.Level;
import com.mojang.minecraft.level.LevelLoaderListener;
import com.mojang.minecraft.level.tile.Tile;
import java.util.ArrayList;
import java.util.Random;
public class LevelGen {
private LevelLoaderListener levelLoaderListener;
private int width;
private int height;
private int depth;
private Random random = new Random();
private byte[] blocks;
private int[] coords = new int[1048576];
public LevelGen(LevelLoaderListener levelLoaderListener) {
this.levelLoaderListener = levelLoaderListener;
}
public boolean generateLevel(Level level, String userName, int width, int height, int depth) {
this.levelLoaderListener.beginLevelLoading("Generating level");
this.width = width;
this.height = height;
this.depth = depth;
this.blocks = new byte[width * height * depth];
this.levelLoaderListener.levelLoadUpdate("Raising..");
double[] heightMap = this.buildHeightmap(width, height);
this.levelLoaderListener.levelLoadUpdate("Eroding..");
this.buildBlocks(heightMap);
this.levelLoaderListener.levelLoadUpdate("Carving..");
this.carveTunnels();
this.levelLoaderListener.levelLoadUpdate("Watering..");
this.addWater();
this.levelLoaderListener.levelLoadUpdate("Melting..");
this.addLava();
level.setData(width, depth, height, this.blocks);
level.createTime = System.currentTimeMillis();
level.creator = userName;
level.name = "A Nice World";
return true;
}
private void buildBlocks(double[] heightMap) {
int w = this.width;
int h = this.height;
int d = this.depth;
for(int x = 0; x < w; ++x) {
for(int y = 0; y < d; ++y) {
for(int z = 0; z < h; ++z) {
int dh = d / 2;
int rh = d / 3;
int i = (y * this.height + z) * this.width + x;
int id = 0;
if(y == dh && y >= d / 2 - 1) {
id = Tile.grass.id;
} else if(y <= dh) {
id = Tile.dirt.id;
}
if(y <= rh) {
id = Tile.rock.id;
}
this.blocks[i] = (byte)id;
}
}
}
}
private double[] buildHeightmap(int width, int height) {
double[] heightmap = new double[width * height];
return heightmap;
}
public void carveTunnels() {
int w = this.width;
int h = this.height;
int d = this.depth;
int count = w * h * d / 256 / 64;
for(int i = 0; i < count; ++i) {
float x = this.random.nextFloat() * (float)w;
float y = this.random.nextFloat() * (float)d;
float z = this.random.nextFloat() * (float)h;
int length = (int)(this.random.nextFloat() + this.random.nextFloat() * 150.0F);
float dir1 = (float)((double)this.random.nextFloat() * Math.PI * 2.0D);
float dira1 = 0.0F;
float dir2 = (float)((double)this.random.nextFloat() * Math.PI * 2.0D);
float dira2 = 0.0F;
for(int l = 0; l < length; ++l) {
x = (float)((double)x + Math.sin((double)dir1) * Math.cos((double)dir2));
z = (float)((double)z + Math.cos((double)dir1) * Math.cos((double)dir2));
y = (float)((double)y + Math.sin((double)dir2));
dir1 += dira1 * 0.2F;
dira1 *= 0.9F;
dira1 += this.random.nextFloat() - this.random.nextFloat();
dir2 += dira2 * 0.5F;
dir2 *= 0.5F;
dira2 *= 0.9F;
dira2 += this.random.nextFloat() - this.random.nextFloat();
float size = (float)(Math.sin((double)l * Math.PI / (double)length) * 2.5D + 1.0D);
for(int xx = (int)(x - size); xx <= (int)(x + size); ++xx) {
for(int yy = (int)(y - size); yy <= (int)(y + size); ++yy) {
for(int zz = (int)(z - size); zz <= (int)(z + size); ++zz) {
float xd = (float)xx - x;
float yd = (float)yy - y;
float zd = (float)zz - z;
float dd = xd * xd + yd * yd * 2.0F + zd * zd;
if(dd < size * size && xx >= 1 && yy >= 1 && zz >= 1 && xx < this.width - 1 && yy < this.depth - 1 && zz < this.height - 1) {
int ii = (yy * this.height + zz) * this.width + xx;
if(this.blocks[ii] == Tile.rock.id) {
this.blocks[ii] = 0;
}
}
}
}
}
}
}
}
public void addWater() {
long before = System.nanoTime();
long tiles = 0L;
byte source = 0;
int target = Tile.calmWater.id;
int after;
for(after = 0; after < this.width; ++after) {
tiles += this.floodFillLiquid(after, this.depth / 2 - 1, 0, source, target);
tiles += this.floodFillLiquid(after, this.depth / 2 - 1, this.height - 1, source, target);
}
for(after = 0; after < this.height; ++after) {
tiles += this.floodFillLiquid(0, this.depth / 2 - 1, after, source, target);
tiles += this.floodFillLiquid(this.width - 1, this.depth / 2 - 1, after, source, target);
}
for(after = 0; after < this.width * this.height / 5000; ++after) {
int x = this.random.nextInt(this.width);
int y = this.depth / 2 - 1;
int z = this.random.nextInt(this.height);
if(this.blocks[(y * this.height + z) * this.width + x] == 0) {
tiles += this.floodFillLiquid(x, y, z, 0, target);
}
}
long var11 = System.nanoTime();
System.out.println("Flood filled " + tiles + " tiles in " + (double)(var11 - before) / 1000000.0D + " ms");
}
public void addLava() {
int lavaCount = 0;
for(int i = 0; i < this.width * this.height * this.depth / 10000; ++i) {
int x = this.random.nextInt(this.width);
int y = this.random.nextInt(this.depth / 2);
int z = this.random.nextInt(this.height);
if(this.blocks[(y * this.height + z) * this.width + x] == 0) {
++lavaCount;
this.floodFillLiquid(x, y, z, 0, Tile.calmLava.id);
}
}
System.out.println("LavaCount: " + lavaCount);
}
public long floodFillLiquid(int x, int y, int z, int source, int tt) {
byte target = (byte)tt;
ArrayList coordBuffer = new ArrayList();
byte p = 0;
int wBits = 1;
int hBits;
for(hBits = 1; 1 << wBits < this.width; ++wBits) {
}
while(1 << hBits < this.height) {
++hBits;
}
int hMask = this.height - 1;
int wMask = this.width - 1;
int var29 = p + 1;
this.coords[p] = ((y << hBits) + z << wBits) + x;
long tiles = 0L;
int upStep = this.width * this.height;
while(var29 > 0) {
--var29;
int cl = this.coords[var29];
if(var29 == 0 && coordBuffer.size() > 0) {
System.out.println("IT HAPPENED!");
this.coords = (int[])coordBuffer.remove(coordBuffer.size() - 1);
var29 = this.coords.length;
}
int z0 = cl >> wBits & hMask;
int y0 = cl >> wBits + hBits;
int x0 = cl & wMask;
int x1;
for(x1 = x0; x0 > 0 && this.blocks[cl - 1] == source; --cl) {
--x0;
}
while(x1 < this.width && this.blocks[cl + x1 - x0] == source) {
++x1;
}
int z1 = cl >> wBits & hMask;
int y1 = cl >> wBits + hBits;
if(z1 != z0 || y1 != y0) {
System.out.println("hoooly fuck");
}
boolean lastNorth = false;
boolean lastSouth = false;
boolean lastBelow = false;
tiles += (long)(x1 - x0);
for(int xx = x0; xx < x1; ++xx) {
this.blocks[cl] = target;
boolean belowId;
if(z0 > 0) {
belowId = this.blocks[cl - this.width] == source;
if(belowId && !lastNorth) {
if(var29 == this.coords.length) {
coordBuffer.add(this.coords);
this.coords = new int[1048576];
var29 = 0;
}
this.coords[var29++] = cl - this.width;
}
lastNorth = belowId;
}
if(z0 < this.height - 1) {
belowId = this.blocks[cl + this.width] == source;
if(belowId && !lastSouth) {
if(var29 == this.coords.length) {
coordBuffer.add(this.coords);
this.coords = new int[1048576];
var29 = 0;
}
this.coords[var29++] = cl + this.width;
}
lastSouth = belowId;
}
if(y0 > 0) {
byte var31 = this.blocks[cl - upStep];
if((target == Tile.lava.id || target == Tile.calmLava.id) && (var31 == Tile.water.id || var31 == Tile.calmWater.id)) {
this.blocks[cl - upStep] = (byte)Tile.rock.id;
}
boolean below = var31 == source;
if(below && !lastBelow) {
if(var29 == this.coords.length) {
coordBuffer.add(this.coords);
this.coords = new int[1048576];
var29 = 0;
}
this.coords[var29++] = cl - upStep;
}
lastBelow = below;
}
++cl;
}
}
return tiles;
}
}

View file

@ -0,0 +1,15 @@
package com.mojang.minecraft.level.levelgen.synth;
public class Distort extends Synth {
private Synth source;
private Synth distort;
public Distort(Synth source, Synth distort) {
this.source = source;
this.distort = distort;
}
public double getValue(double x, double y) {
return this.source.getValue(x + this.distort.getValue(x, y), y);
}
}

View file

@ -0,0 +1,13 @@
package com.mojang.minecraft.level.levelgen.synth;
public class Emboss extends Synth {
private Synth synth;
public Emboss(Synth synth) {
this.synth = synth;
}
public double getValue(double x, double y) {
return this.synth.getValue(x, y) - this.synth.getValue(x + 1.0D, y + 1.0D);
}
}

View file

@ -0,0 +1,67 @@
package com.mojang.minecraft.level.levelgen.synth;
import java.util.Random;
public class ImprovedNoise extends Synth {
private int[] p;
public double scale;
public ImprovedNoise() {
this(new Random());
}
public ImprovedNoise(Random random) {
this.p = new int[512];
int i;
for(i = 0; i < 256; this.p[i] = i++) {
}
for(i = 0; i < 256; ++i) {
int j = random.nextInt(256 - i) + i;
int tmp = this.p[i];
this.p[i] = this.p[j];
this.p[j] = tmp;
this.p[i + 256] = this.p[i];
}
}
public double noise(double x, double y, double z) {
int X = (int)Math.floor(x) & 255;
int Y = (int)Math.floor(y) & 255;
int Z = (int)Math.floor(z) & 255;
x -= Math.floor(x);
y -= Math.floor(y);
z -= Math.floor(z);
double u = this.fade(x);
double v = this.fade(y);
double w = this.fade(z);
int A = this.p[X] + Y;
int AA = this.p[A] + Z;
int AB = this.p[A + 1] + Z;
int B = this.p[X + 1] + Y;
int BA = this.p[B] + Z;
int BB = this.p[B + 1] + Z;
return this.lerp(w, this.lerp(v, this.lerp(u, this.grad(this.p[AA], x, y, z), this.grad(this.p[BA], x - 1.0D, y, z)), this.lerp(u, this.grad(this.p[AB], x, y - 1.0D, z), this.grad(this.p[BB], x - 1.0D, y - 1.0D, z))), this.lerp(v, this.lerp(u, this.grad(this.p[AA + 1], x, y, z - 1.0D), this.grad(this.p[BA + 1], x - 1.0D, y, z - 1.0D)), this.lerp(u, this.grad(this.p[AB + 1], x, y - 1.0D, z - 1.0D), this.grad(this.p[BB + 1], x - 1.0D, y - 1.0D, z - 1.0D))));
}
public double fade(double t) {
return t * t * t * (t * (t * 6.0D - 15.0D) + 10.0D);
}
public double lerp(double t, double a, double b) {
return a + t * (b - a);
}
public double grad(int hash, double x, double y, double z) {
int h = hash & 15;
double u = h < 8 ? x : y;
double v = h < 4 ? y : (h != 12 && h != 14 ? z : x);
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
}
public double getValue(double x, double y) {
return this.noise(x, y, 0.0D);
}
}

View file

@ -0,0 +1,34 @@
package com.mojang.minecraft.level.levelgen.synth;
import java.util.Random;
public class PerlinNoise extends Synth {
private ImprovedNoise[] noiseLevels;
private int levels;
public PerlinNoise(int levels) {
this(new Random(), levels);
}
public PerlinNoise(Random random, int levels) {
this.levels = levels;
this.noiseLevels = new ImprovedNoise[levels];
for(int i = 0; i < levels; ++i) {
this.noiseLevels[i] = new ImprovedNoise(random);
}
}
public double getValue(double x, double y) {
double value = 0.0D;
double pow = 1.0D;
for(int i = 0; i < this.levels; ++i) {
value += this.noiseLevels[i].getValue(x / pow, y / pow) * pow;
pow *= 2.0D;
}
return value;
}
}

View file

@ -0,0 +1,17 @@
package com.mojang.minecraft.level.levelgen.synth;
public class Rotate extends Synth {
private Synth synth;
private double sin;
private double cos;
public Rotate(Synth synth, double angle) {
this.synth = synth;
this.sin = Math.sin(angle);
this.cos = Math.cos(angle);
}
public double getValue(double x, double y) {
return this.synth.getValue(x * this.cos + y * this.sin, y * this.cos - x * this.sin);
}
}

View file

@ -0,0 +1,17 @@
package com.mojang.minecraft.level.levelgen.synth;
public class Scale extends Synth {
private Synth synth;
private double xScale;
private double yScale;
public Scale(Synth synth, double xScale, double yScale) {
this.synth = synth;
this.xScale = 1.0D / xScale;
this.yScale = 1.0D / yScale;
}
public double getValue(double x, double y) {
return this.synth.getValue(x * this.xScale, y * this.yScale);
}
}

View file

@ -0,0 +1,17 @@
package com.mojang.minecraft.level.levelgen.synth;
public abstract class Synth {
public abstract double getValue(double var1, double var3);
public double[] create(int width, int height) {
double[] result = new double[width * height];
for(int y = 0; y < height; ++y) {
for(int x = 0; x < width; ++x) {
result[x + y * width] = this.getValue((double)x, (double)y);
}
}
return result;
}
}

View file

@ -9,6 +9,7 @@ public class Bush extends Tile {
protected Bush(int id) {
super(id);
this.tex = 15;
this.setTicking(true);
}
public void tick(Level level, int x, int y, int z, Random random) {
@ -27,7 +28,7 @@ public class Bush extends Tile {
float v0 = (float)(tex / 16) / 16.0F;
float v1 = v0 + 0.999F / 16.0F;
byte rots = 2;
t.color(1.0F, 1.0F, 1.0F);
t.color((int)255, (int)255, (int)255);
for(int r = 0; r < rots; ++r) {
float xa = (float)(Math.sin((double)r * Math.PI / (double)rots + Math.PI * 0.25D) * 0.5D);
@ -42,10 +43,10 @@ public class Bush extends Tile {
t.vertexUV(x1, y1, z1, u0, v0);
t.vertexUV(x1, y0, z1, u0, v1);
t.vertexUV(x0, y0, z0, u1, v1);
t.vertexUV(x1, y1, z1, u0, v0);
t.vertexUV(x0, y1, z0, u1, v0);
t.vertexUV(x0, y0, z0, u1, v1);
t.vertexUV(x1, y0, z1, u0, v1);
t.vertexUV(x1, y1, z1, u1, v0);
t.vertexUV(x0, y1, z0, u0, v0);
t.vertexUV(x0, y0, z0, u0, v1);
t.vertexUV(x1, y0, z1, u1, v1);
}
}

View file

@ -0,0 +1,52 @@
package com.mojang.minecraft.level.tile;
import com.mojang.minecraft.level.Level;
import java.util.Random;
public class CalmLiquidTile extends LiquidTile {
protected CalmLiquidTile(int id, int liquidType) {
super(id, liquidType);
this.tileId = id - 1;
this.calmTileId = id;
this.setTicking(false);
}
public void tick(Level level, int x, int y, int z, Random random) {
}
public void neighborChanged(Level level, int x, int y, int z, int type) {
boolean hasAirNeighbor = false;
if(level.getTile(x - 1, y, z) == 0) {
hasAirNeighbor = true;
}
if(level.getTile(x + 1, y, z) == 0) {
hasAirNeighbor = true;
}
if(level.getTile(x, y, z - 1) == 0) {
hasAirNeighbor = true;
}
if(level.getTile(x, y, z + 1) == 0) {
hasAirNeighbor = true;
}
if(level.getTile(x, y - 1, z) == 0) {
hasAirNeighbor = true;
}
if(hasAirNeighbor) {
level.setTileNoUpdate(x, y, z, this.tileId);
}
if(this.liquidType == 1 && type == Tile.lava.id) {
level.setTileNoUpdate(x, y, z, Tile.rock.id);
}
if(this.liquidType == 2 && type == Tile.water.id) {
level.setTileNoUpdate(x, y, z, Tile.rock.id);
}
}
}

View file

@ -7,6 +7,7 @@ public class GrassTile extends Tile {
protected GrassTile(int id) {
super(id);
this.tex = 3;
this.setTicking(true);
}
protected int getTexture(int face) {
@ -14,18 +15,20 @@ public class GrassTile extends Tile {
}
public void tick(Level level, int x, int y, int z, Random random) {
if(!level.isLit(x, y, z)) {
level.setTile(x, y, z, Tile.dirt.id);
} else {
for(int i = 0; i < 4; ++i) {
int xt = x + random.nextInt(3) - 1;
int yt = y + random.nextInt(5) - 3;
int zt = z + random.nextInt(3) - 1;
if(level.getTile(xt, yt, zt) == Tile.dirt.id && level.isLit(xt, yt, zt)) {
level.setTile(xt, yt, zt, Tile.grass.id);
if(random.nextInt(4) == 0) {
if(!level.isLit(x, y + 1, z)) {
level.setTile(x, y, z, Tile.dirt.id);
} else {
for(int i = 0; i < 4; ++i) {
int xt = x + random.nextInt(3) - 1;
int yt = y + random.nextInt(5) - 3;
int zt = z + random.nextInt(3) - 1;
if(level.getTile(xt, yt, zt) == Tile.dirt.id && level.isLit(xt, yt + 1, zt)) {
level.setTile(xt, yt, zt, Tile.grass.id);
}
}
}
}
}
}
}

View file

@ -0,0 +1,133 @@
package com.mojang.minecraft.level.tile;
import com.mojang.minecraft.level.Level;
import com.mojang.minecraft.phys.AABB;
import com.mojang.minecraft.renderer.Tesselator;
import java.util.Random;
public class LiquidTile extends Tile {
protected int liquidType;
protected int calmTileId;
protected int tileId;
protected int spreadSpeed = 1;
protected LiquidTile(int id, int liquidType) {
super(id);
this.liquidType = liquidType;
this.tex = 14;
if(liquidType == 2) {
this.tex = 30;
}
if(liquidType == 1) {
this.spreadSpeed = 8;
}
if(liquidType == 2) {
this.spreadSpeed = 2;
}
this.tileId = id;
this.calmTileId = id + 1;
float dd = 0.1F;
this.setShape(0.0F, 0.0F - dd, 0.0F, 1.0F, 1.0F - dd, 1.0F);
this.setTicking(true);
}
public void tick(Level level, int x, int y, int z, Random random) {
this.updateWater(level, x, y, z, 0);
}
public boolean updateWater(Level level, int x, int y, int z, int depth) {
boolean hasChanged = false;
boolean change;
do {
--y;
if(level.getTile(x, y, z) != 0) {
break;
}
change = level.setTile(x, y, z, this.tileId);
if(change) {
hasChanged = true;
}
} while(change && this.liquidType != 2);
++y;
if(this.liquidType == 1 || !hasChanged) {
hasChanged |= this.checkWater(level, x - 1, y, z, depth);
hasChanged |= this.checkWater(level, x + 1, y, z, depth);
hasChanged |= this.checkWater(level, x, y, z - 1, depth);
hasChanged |= this.checkWater(level, x, y, z + 1, depth);
}
if(!hasChanged) {
level.setTileNoUpdate(x, y, z, this.calmTileId);
}
return hasChanged;
}
private boolean checkWater(Level level, int x, int y, int z, int depth) {
boolean hasChanged = false;
int type = level.getTile(x, y, z);
if(type == 0) {
boolean changed = level.setTile(x, y, z, this.tileId);
if(changed && depth < this.spreadSpeed) {
hasChanged |= this.updateWater(level, x, y, z, depth + 1);
}
}
return hasChanged;
}
protected boolean shouldRenderFace(Level level, int x, int y, int z, int layer, int face) {
if(x >= 0 && y >= 0 && z >= 0 && x < level.width && z < level.height) {
if(layer != 2 && this.liquidType == 1) {
return false;
} else {
int id = level.getTile(x, y, z);
return id != this.tileId && id != this.calmTileId ? super.shouldRenderFace(level, x, y, z, -1, face) : false;
}
} else {
return false;
}
}
public void renderFace(Tesselator t, int x, int y, int z, int face) {
super.renderFace(t, x, y, z, face);
super.renderBackFace(t, x, y, z, face);
}
public boolean mayPick() {
return false;
}
public AABB getAABB(int x, int y, int z) {
return null;
}
public boolean blocksLight() {
return true;
}
public boolean isSolid() {
return false;
}
public int getLiquidType() {
return this.liquidType;
}
public void neighborChanged(Level level, int x, int y, int z, int type) {
if(this.liquidType == 1 && (type == Tile.lava.id || type == Tile.calmLava.id)) {
level.setTileNoUpdate(x, y, z, Tile.rock.id);
}
if(this.liquidType == 2 && (type == Tile.water.id || type == Tile.calmWater.id)) {
level.setTileNoUpdate(x, y, z, Tile.rock.id);
}
}
}

View file

@ -1,5 +1,6 @@
package com.mojang.minecraft.level.tile;
import com.mojang.minecraft.Player;
import com.mojang.minecraft.level.Level;
import com.mojang.minecraft.particle.Particle;
import com.mojang.minecraft.particle.ParticleEngine;
@ -8,7 +9,11 @@ import com.mojang.minecraft.renderer.Tesselator;
import java.util.Random;
public class Tile {
public static final int NOT_LIQUID = 0;
public static final int LIQUID_WATER = 1;
public static final int LIQUID_LAVA = 2;
public static final Tile[] tiles = new Tile[256];
public static final boolean[] shouldTick = new boolean[256];
public static final Tile empty = null;
public static final Tile rock = new Tile(1, 1);
public static final Tile grass = new GrassTile(2);
@ -16,12 +21,37 @@ public class Tile {
public static final Tile stoneBrick = new Tile(4, 16);
public static final Tile wood = new Tile(5, 4);
public static final Tile bush = new Bush(6);
public static final Tile unbreakable = new Tile(7, 17);
public static final Tile water = new LiquidTile(8, 1);
public static final Tile calmWater = new CalmLiquidTile(9, 1);
public static final Tile lava = new LiquidTile(10, 2);
public static final Tile calmLava = new CalmLiquidTile(11, 2);
public int tex;
public final int id;
protected float xx0;
protected float yy0;
protected float zz0;
protected float xx1;
protected float yy1;
protected float zz1;
protected Tile(int id) {
tiles[id] = this;
this.id = id;
this.setShape(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
}
protected void setTicking(boolean tick) {
shouldTick[this.id] = tick;
}
protected void setShape(float x0, float y0, float z0, float x1, float y1, float z1) {
this.xx0 = x0;
this.yy0 = y0;
this.zz0 = z0;
this.xx1 = x1;
this.yy1 = y1;
this.zz1 = z1;
}
protected Tile(int id, int tex) {
@ -30,43 +60,52 @@ public class Tile {
}
public void render(Tesselator t, Level level, int layer, int x, int y, int z) {
float c1 = 1.0F;
float c2 = 0.8F;
float c3 = 0.6F;
if(this.shouldRenderFace(level, x, y - 1, z, layer)) {
byte c1 = -1;
byte c2 = -52;
byte c3 = -103;
if(this.shouldRenderFace(level, x, y - 1, z, layer, 0)) {
t.color(c1, c1, c1);
this.renderFace(t, x, y, z, 0);
}
if(this.shouldRenderFace(level, x, y + 1, z, layer)) {
if(this.shouldRenderFace(level, x, y + 1, z, layer, 1)) {
t.color(c1, c1, c1);
this.renderFace(t, x, y, z, 1);
}
if(this.shouldRenderFace(level, x, y, z - 1, layer)) {
if(this.shouldRenderFace(level, x, y, z - 1, layer, 2)) {
t.color(c2, c2, c2);
this.renderFace(t, x, y, z, 2);
}
if(this.shouldRenderFace(level, x, y, z + 1, layer)) {
if(this.shouldRenderFace(level, x, y, z + 1, layer, 3)) {
t.color(c2, c2, c2);
this.renderFace(t, x, y, z, 3);
}
if(this.shouldRenderFace(level, x - 1, y, z, layer)) {
if(this.shouldRenderFace(level, x - 1, y, z, layer, 4)) {
t.color(c3, c3, c3);
this.renderFace(t, x, y, z, 4);
}
if(this.shouldRenderFace(level, x + 1, y, z, layer)) {
if(this.shouldRenderFace(level, x + 1, y, z, layer, 5)) {
t.color(c3, c3, c3);
this.renderFace(t, x, y, z, 5);
}
}
private boolean shouldRenderFace(Level level, int x, int y, int z, int layer) {
return !level.isSolidTile(x, y, z) && level.isLit(x, y, z) ^ layer == 1;
protected boolean shouldRenderFace(Level level, int x, int y, int z, int layer, int face) {
boolean layerOk = true;
if(layer == 2) {
return false;
} else {
if(layer >= 0) {
layerOk = level.isLit(x, y, z) ^ layer == 1;
}
return !level.isSolidTile(x, y, z) && layerOk;
}
}
protected int getTexture(int face) {
@ -75,103 +114,150 @@ public class Tile {
public void renderFace(Tesselator t, int x, int y, int z, int face) {
int tex = this.getTexture(face);
float u0 = (float)(tex % 16) / 16.0F;
float u1 = u0 + 0.999F / 16.0F;
float v0 = (float)(tex / 16) / 16.0F;
float v1 = v0 + 0.999F / 16.0F;
float x0 = (float)x + 0.0F;
float x1 = (float)x + 1.0F;
float y0 = (float)y + 0.0F;
float y1 = (float)y + 1.0F;
float z0 = (float)z + 0.0F;
float z1 = (float)z + 1.0F;
int xt = tex % 16 * 16;
int yt = tex / 16 * 16;
float u0 = (float)xt / 256.0F;
float u1 = ((float)xt + 15.99F) / 256.0F;
float v0 = (float)yt / 256.0F;
float v1 = ((float)yt + 15.99F) / 256.0F;
float x0 = (float)x + this.xx0;
float x1 = (float)x + this.xx1;
float y0 = (float)y + this.yy0;
float y1 = (float)y + this.yy1;
float z0 = (float)z + this.zz0;
float z1 = (float)z + this.zz1;
if(face == 0) {
t.vertexUV(x0, y0, z1, u0, v1);
t.vertexUV(x0, y0, z0, u0, v0);
t.vertexUV(x1, y0, z0, u1, v0);
t.vertexUV(x1, y0, z1, u1, v1);
}
if(face == 1) {
} else if(face == 1) {
t.vertexUV(x1, y1, z1, u1, v1);
t.vertexUV(x1, y1, z0, u1, v0);
t.vertexUV(x0, y1, z0, u0, v0);
t.vertexUV(x0, y1, z1, u0, v1);
}
if(face == 2) {
} else if(face == 2) {
t.vertexUV(x0, y1, z0, u1, v0);
t.vertexUV(x1, y1, z0, u0, v0);
t.vertexUV(x1, y0, z0, u0, v1);
t.vertexUV(x0, y0, z0, u1, v1);
}
if(face == 3) {
} else if(face == 3) {
t.vertexUV(x0, y1, z1, u0, v0);
t.vertexUV(x0, y0, z1, u0, v1);
t.vertexUV(x1, y0, z1, u1, v1);
t.vertexUV(x1, y1, z1, u1, v0);
}
if(face == 4) {
} else if(face == 4) {
t.vertexUV(x0, y1, z1, u1, v0);
t.vertexUV(x0, y1, z0, u0, v0);
t.vertexUV(x0, y0, z0, u0, v1);
t.vertexUV(x0, y0, z1, u1, v1);
}
if(face == 5) {
} else if(face == 5) {
t.vertexUV(x1, y0, z1, u0, v1);
t.vertexUV(x1, y0, z0, u1, v1);
t.vertexUV(x1, y1, z0, u1, v0);
t.vertexUV(x1, y1, z1, u0, v0);
}
}
public void renderBackFace(Tesselator t, int x, int y, int z, int face) {
int tex = this.getTexture(face);
float u0 = (float)(tex % 16) / 16.0F;
float u1 = u0 + 0.999F / 16.0F;
float v0 = (float)(tex / 16) / 16.0F;
float v1 = v0 + 0.999F / 16.0F;
float x0 = (float)x + this.xx0;
float x1 = (float)x + this.xx1;
float y0 = (float)y + this.yy0;
float y1 = (float)y + this.yy1;
float z0 = (float)z + this.zz0;
float z1 = (float)z + this.zz1;
if(face == 0) {
t.vertexUV(x1, y0, z1, u1, v1);
t.vertexUV(x1, y0, z0, u1, v0);
t.vertexUV(x0, y0, z0, u0, v0);
t.vertexUV(x0, y0, z1, u0, v1);
}
if(face == 1) {
t.vertexUV(x0, y1, z1, u0, v1);
t.vertexUV(x0, y1, z0, u0, v0);
t.vertexUV(x1, y1, z0, u1, v0);
t.vertexUV(x1, y1, z1, u1, v1);
}
if(face == 2) {
t.vertexUV(x0, y0, z0, u1, v1);
t.vertexUV(x1, y0, z0, u0, v1);
t.vertexUV(x1, y1, z0, u0, v0);
t.vertexUV(x0, y1, z0, u1, v0);
}
if(face == 3) {
t.vertexUV(x1, y1, z1, u1, v0);
t.vertexUV(x1, y0, z1, u1, v1);
t.vertexUV(x0, y0, z1, u0, v1);
t.vertexUV(x0, y1, z1, u0, v0);
}
if(face == 4) {
t.vertexUV(x0, y0, z1, u1, v1);
t.vertexUV(x0, y0, z0, u0, v1);
t.vertexUV(x0, y1, z0, u0, v0);
t.vertexUV(x0, y1, z1, u1, v0);
}
if(face == 5) {
t.vertexUV(x1, y1, z1, u0, v0);
t.vertexUV(x1, y1, z0, u1, v0);
t.vertexUV(x1, y0, z0, u1, v1);
t.vertexUV(x1, y0, z1, u0, v1);
}
}
public void renderFaceNoTexture(Tesselator t, int x, int y, int z, int face) {
public void renderFaceNoTexture(Player player, Tesselator t, int x, int y, int z, int face) {
float x0 = (float)x + 0.0F;
float x1 = (float)x + 1.0F;
float y0 = (float)y + 0.0F;
float y1 = (float)y + 1.0F;
float z0 = (float)z + 0.0F;
float z1 = (float)z + 1.0F;
if(face == 0) {
if(face == 0 && (float)y > player.y) {
t.vertex(x0, y0, z1);
t.vertex(x0, y0, z0);
t.vertex(x1, y0, z0);
t.vertex(x1, y0, z1);
}
if(face == 1) {
if(face == 1 && (float)y < player.y) {
t.vertex(x1, y1, z1);
t.vertex(x1, y1, z0);
t.vertex(x0, y1, z0);
t.vertex(x0, y1, z1);
}
if(face == 2) {
if(face == 2 && (float)z > player.z) {
t.vertex(x0, y1, z0);
t.vertex(x1, y1, z0);
t.vertex(x1, y0, z0);
t.vertex(x0, y0, z0);
}
if(face == 3) {
if(face == 3 && (float)z < player.z) {
t.vertex(x0, y1, z1);
t.vertex(x0, y0, z1);
t.vertex(x1, y0, z1);
t.vertex(x1, y1, z1);
}
if(face == 4) {
if(face == 4 && (float)x > player.x) {
t.vertex(x0, y1, z1);
t.vertex(x0, y1, z0);
t.vertex(x0, y0, z0);
t.vertex(x0, y0, z1);
}
if(face == 5) {
if(face == 5 && (float)x < player.x) {
t.vertex(x1, y0, z1);
t.vertex(x1, y0, z0);
t.vertex(x1, y1, z0);
@ -196,6 +282,10 @@ public class Tile {
return true;
}
public boolean mayPick() {
return true;
}
public void tick(Level level, int x, int y, int z, Random random) {
}
@ -214,4 +304,11 @@ public class Tile {
}
}
public int getLiquidType() {
return 0;
}
public void neighborChanged(Level level, int x, int y, int z, int type) {
}
}

View file

@ -45,7 +45,7 @@ public class ParticleEngine {
float ya = (float)Math.cos((double)player.xRot * Math.PI / 180.0D);
Tesselator t = Tesselator.instance;
GL11.glColor4f(0.8F, 0.8F, 0.8F, 1.0F);
t.init();
t.begin();
for(int i = 0; i < this.particles.size(); ++i) {
Particle p = (Particle)this.particles.get(i);
@ -54,7 +54,7 @@ public class ParticleEngine {
}
}
t.flush();
t.end();
GL11.glDisable(GL11.GL_TEXTURE_2D);
}
}

View file

@ -62,6 +62,10 @@ public class AABB {
return new AABB(_x0, _y0, _z0, _x1, _y1, _z1);
}
public AABB cloneMove(float xa, float ya, float za) {
return new AABB(this.x0 + za, this.y0 + ya, this.z0 + za, this.x1 + xa, this.y1 + ya, this.z1 + za);
}
public float clipXCollide(AABB c, float xa) {
if(c.y1 > this.y0 && c.y0 < this.y1) {
if(c.z1 > this.z0 && c.z0 < this.z1) {

View file

@ -22,7 +22,7 @@ public class Tesselator {
private boolean noColor = false;
public static Tesselator instance = new Tesselator();
public void flush() {
public void end() {
if(this.vertices > 0) {
this.buffer.clear();
this.buffer.put(this.array, 0, this.p);
@ -66,7 +66,7 @@ public class Tesselator {
this.p = 0;
}
public void init() {
public void begin() {
this.clear();
this.hasColor = false;
this.hasTexture = false;
@ -83,16 +83,20 @@ public class Tesselator {
this.v = v;
}
public void color(float r, float g, float b) {
public void color(int r, int g, int b) {
this.color((byte)r, (byte)g, (byte)b);
}
public void color(byte r, byte g, byte b) {
if(!this.noColor) {
if(!this.hasColor) {
this.len += 3;
}
this.hasColor = true;
this.r = r;
this.g = g;
this.b = b;
this.r = (float)(r & 255) / 255.0F;
this.g = (float)(g & 255) / 255.0F;
this.b = (float)(b & 255) / 255.0F;
}
}
@ -118,15 +122,15 @@ public class Tesselator {
this.array[this.p++] = z;
++this.vertices;
if(this.vertices % 4 == 0 && this.p >= 524288 - this.len * 4) {
this.flush();
this.end();
}
}
public void color(int c) {
float r = (float)(c >> 16 & 255) / 255.0F;
float g = (float)(c >> 8 & 255) / 255.0F;
float b = (float)(c & 255) / 255.0F;
int r = c >> 16 & 255;
int g = c >> 8 & 255;
int b = c & 255;
this.color(r, g, b);
}

View file

@ -23,7 +23,6 @@ public class Textures {
GL11.glGenTextures(e);
int id = e.get(0);
this.idMap.put(resourceName, Integer.valueOf(id));
System.out.println(resourceName + " -> " + id);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, mode);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, mode);
@ -32,6 +31,7 @@ public class Textures {
int h = img.getHeight();
ByteBuffer pixels = BufferUtils.createByteBuffer(w * h * 4);
int[] rawPixels = new int[w * h];
byte[] newPixels = new byte[w * h * 4];
img.getRGB(0, 0, w, h, rawPixels, 0, w);
for(int i = 0; i < rawPixels.length; ++i) {
@ -39,14 +39,18 @@ public class Textures {
int r = rawPixels[i] >> 16 & 255;
int g = rawPixels[i] >> 8 & 255;
int b = rawPixels[i] & 255;
rawPixels[i] = a << 24 | b << 16 | g << 8 | r;
newPixels[i * 4 + 0] = (byte)r;
newPixels[i * 4 + 1] = (byte)g;
newPixels[i * 4 + 2] = (byte)b;
newPixels[i * 4 + 3] = (byte)a;
}
pixels.asIntBuffer().put(rawPixels);
pixels.put(newPixels);
pixels.position(0).limit(newPixels.length);
GLU.gluBuild2DMipmaps(3553, 6408, w, h, 6408, 5121, pixels);
return id;
}
} catch (IOException var15) {
} catch (IOException var16) {
throw new RuntimeException("!!");
}
}

BIN
src/main/resources/dirt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,011 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
src/main/resources/rock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 B